1
0
mirror of https://github.com/alice-lg/alice-lg.git synced 2024-05-11 05:55:03 +00:00

286 lines
6.2 KiB
Go
Raw Normal View History

2021-03-24 14:26:46 +01:00
package openbgpd
import (
2021-03-25 21:48:15 +01:00
"context"
"net/http"
2021-03-26 09:58:26 +01:00
"time"
2021-03-25 21:48:15 +01:00
2021-03-24 14:26:46 +01:00
"github.com/alice-lg/alice-lg/pkg/api"
2021-03-26 09:58:26 +01:00
"github.com/alice-lg/alice-lg/pkg/decoders"
2021-03-24 14:26:46 +01:00
)
2021-03-25 21:48:15 +01:00
const (
// SourceVersion is currently fixed at 1.0
SourceVersion = "1.0"
)
2021-03-24 14:26:46 +01:00
// Source implements the OpenBGPD source for Alice.
// It is intendet to consume structured bgpctl output
// queried over HTTP using a `openbgpd-state-server`.
type Source struct {
2021-04-26 22:01:26 +02:00
// cfg is the source configuration retrieved
// from the alice config file.
cfg *Config
}
// NewSource creates a new source instance with a
// configuration.
func NewSource(cfg *Config) *Source {
return &Source{
cfg: cfg,
}
2021-03-24 14:26:46 +01:00
}
// ExpireCaches expires all cached data
2021-04-26 11:21:37 +02:00
func (src *Source) ExpireCaches() int {
2021-03-24 14:26:46 +01:00
return 0 // Nothing to expire yet
}
// Status returns an API status response. In our case
// this is pretty much only that the service is available.
2021-04-26 11:21:37 +02:00
func (src *Source) Status() (*api.StatusResponse, error) {
2021-03-25 21:48:15 +01:00
apiStatus := api.ApiStatus{
Version: SourceVersion,
ResultFromCache: false,
2021-03-26 09:58:26 +01:00
Ttl: time.Now().UTC(),
2021-03-25 21:48:15 +01:00
}
2021-04-15 16:47:27 +02:00
// Make API request and read response
2021-04-26 22:01:26 +02:00
req, err := src.StatusRequest(context.Background())
2021-03-25 21:48:15 +01:00
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
2021-03-26 09:58:26 +01:00
body, err := decoders.ReadJSONResponse(res)
if err != nil {
return nil, err
}
2021-03-25 21:48:15 +01:00
2021-03-26 09:58:26 +01:00
status := decodeAPIStatus(body)
2021-03-25 21:48:15 +01:00
response := &api.StatusResponse{
Api: apiStatus,
Status: status,
}
2021-04-15 16:47:27 +02:00
return response, nil
}
// Neighbours retrievs a full list of all neighbors
2021-04-26 11:21:37 +02:00
func (src *Source) Neighbours() (*api.NeighboursResponse, error) {
2021-04-15 16:47:27 +02:00
// Retrieve neighbours
apiStatus := api.ApiStatus{
Version: SourceVersion,
ResultFromCache: false,
Ttl: time.Now().UTC(),
}
// Make API request and read response
2021-04-26 22:01:26 +02:00
req, err := src.ShowNeighborsRequest(context.Background())
2021-04-15 16:47:27 +02:00
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
body, err := decoders.ReadJSONResponse(res)
if err != nil {
return nil, err
}
2021-03-25 21:48:15 +01:00
2021-04-15 18:31:12 +02:00
nb, err := decodeNeighbors(body)
if err != nil {
return nil, err
}
2021-07-02 11:16:35 +02:00
// Set route server id (sourceID) for all neighbors
for _, n := range nb {
n.RouteServerId = src.cfg.ID
}
2021-04-15 16:47:27 +02:00
response := &api.NeighboursResponse{
Api: apiStatus,
Neighbours: nb,
}
2021-03-25 21:48:15 +01:00
return response, nil
2021-03-24 14:26:46 +01:00
}
2021-04-26 11:21:37 +02:00
// NeighboursStatus retrives the status summary
// for all neightbors
func (src *Source) NeighboursStatus() (*api.NeighboursStatusResponse, error) {
2021-04-26 11:40:12 +02:00
// Retrieve neighbours
apiStatus := api.ApiStatus{
Version: SourceVersion,
ResultFromCache: false,
Ttl: time.Now().UTC(),
}
// Make API request and read response
2021-04-26 22:01:26 +02:00
req, err := src.ShowNeighborsSummaryRequest(context.Background())
2021-04-26 11:40:12 +02:00
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
// Read and decode response
body, err := decoders.ReadJSONResponse(res)
if err != nil {
return nil, err
}
nb, err := decodeNeighborsStatus(body)
if err != nil {
return nil, err
}
response := &api.NeighboursStatusResponse{
Api: apiStatus,
Neighbours: nb,
}
return response, nil
2021-04-26 11:21:37 +02:00
}
2021-04-26 17:44:25 +02:00
// Routes retrieves the routes for a specific neighbor
2021-04-26 11:21:37 +02:00
// identified by ID.
func (src *Source) Routes(neighborID string) (*api.RoutesResponse, error) {
2021-04-26 17:44:25 +02:00
// Retrieve routes for the specific neighbor
apiStatus := api.ApiStatus{
Version: SourceVersion,
ResultFromCache: false,
Ttl: time.Now().UTC(),
}
// Query RIB for routes received
2021-04-26 22:01:26 +02:00
req, err := src.ShowNeighborRIBInRequest(context.Background(), neighborID)
2021-04-26 17:44:25 +02:00
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
// Read and decode response
body, err := decoders.ReadJSONResponse(res)
if err != nil {
return nil, err
}
recv, err := decodeRoutes(body)
if err != nil {
return nil, err
}
response := &api.RoutesResponse{
Api: apiStatus,
Imported: recv,
}
return response, nil
2021-04-26 11:21:37 +02:00
}
// RoutesReceived returns the routes exported by the neighbor.
func (src *Source) RoutesReceived(neighborID string) (*api.RoutesResponse, error) {
2021-04-26 21:02:06 +02:00
// Retrieve routes for the specific neighbor
apiStatus := api.ApiStatus{
Version: SourceVersion,
ResultFromCache: false,
Ttl: time.Now().UTC(),
}
// Query RIB for routes received
2021-04-26 22:01:26 +02:00
req, err := src.ShowNeighborRIBInRequest(context.Background(), neighborID)
2021-04-26 21:02:06 +02:00
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
// Read and decode response
body, err := decoders.ReadJSONResponse(res)
if err != nil {
return nil, err
}
recv, err := decodeRoutes(body)
if err != nil {
return nil, err
}
response := &api.RoutesResponse{
Api: apiStatus,
Imported: recv,
NotExported: api.Routes{},
}
return response, nil
2021-04-26 11:21:37 +02:00
}
// RoutesFiltered retrieves the routes filtered / not valid
func (src *Source) RoutesFiltered(neighborID string) (*api.RoutesResponse, error) {
2021-04-26 21:02:06 +02:00
apiStatus := api.ApiStatus{
Version: SourceVersion,
ResultFromCache: false,
Ttl: time.Now().UTC(),
}
response := &api.RoutesResponse{
Api: apiStatus,
}
return response, nil
2021-04-26 11:21:37 +02:00
}
// RoutesNotExported retrievs the routes not exported
// from the rs for a neighbor.
func (src *Source) RoutesNotExported(neighborID string) (*api.RoutesResponse, error) {
2021-04-26 21:02:06 +02:00
apiStatus := api.ApiStatus{
Version: SourceVersion,
ResultFromCache: false,
Ttl: time.Now().UTC(),
}
response := &api.RoutesResponse{
Api: apiStatus,
}
return response, nil
2021-04-26 11:21:37 +02:00
}
// AllRoutes retrievs the entire RIB from the source
func (src *Source) AllRoutes() (*api.RoutesResponse, error) {
2021-04-26 21:02:06 +02:00
apiStatus := api.ApiStatus{
Version: SourceVersion,
ResultFromCache: false,
Ttl: time.Now().UTC(),
}
2021-04-26 22:01:26 +02:00
req, err := src.ShowRIBRequest(context.Background())
2021-04-26 21:02:06 +02:00
if err != nil {
return nil, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
// Read and decode response
body, err := decoders.ReadJSONResponse(res)
if err != nil {
return nil, err
}
recv, err := decodeRoutes(body)
if err != nil {
return nil, err
}
response := &api.RoutesResponse{
Api: apiStatus,
Imported: recv,
NotExported: api.Routes{},
}
return response, nil
2021-04-26 11:21:37 +02:00
}