alice-lg/pkg/api/response.go

326 lines
8.0 KiB
Go
Raw Normal View History

2017-05-18 12:52:10 +02:00
package api
import (
2022-11-25 15:38:38 +01:00
"strconv"
2017-05-18 12:52:10 +02:00
"time"
)
// A Response is a general API response. All API responses
// contain meta information with API version and caching
// information.
2021-10-27 17:54:51 +00:00
type Response struct {
Meta *Meta `json:"api"`
}
2017-05-18 15:26:22 +02:00
2021-03-24 14:26:46 +01:00
// ErrorResponse encodes an error message and code
2017-05-18 14:44:38 +02:00
type ErrorResponse struct {
2018-08-05 18:25:59 +02:00
Message string `json:"message"`
Code int `json:"code"`
Tag string `json:"tag"`
RouteserverID string `json:"routeserver_id"`
2017-05-18 14:44:38 +02:00
}
2021-03-24 14:26:46 +01:00
// CacheableResponse is a cache aware API response
2018-07-11 14:07:52 +02:00
type CacheableResponse interface {
2021-03-22 17:35:20 +01:00
CacheTTL() time.Duration
2018-07-11 14:07:52 +02:00
}
2021-03-24 14:26:46 +01:00
// ConfigResponse is a response with client runtime configuration
2017-05-18 15:23:36 +02:00
type ConfigResponse struct {
RejectReasons map[string]interface{} `json:"reject_reasons"`
2017-05-18 14:44:38 +02:00
Noexport Noexport `json:"noexport"`
NoexportReasons map[string]interface{} `json:"noexport_reasons"`
2017-05-18 14:44:38 +02:00
2018-10-02 15:52:46 +02:00
RejectCandidates RejectCandidates `json:"reject_candidates"`
2018-09-22 17:56:30 +02:00
Rpki Rpki `json:"rpki"`
BGPCommunities map[string]interface{} `json:"bgp_communities"`
BGPBlackholeCommunities BGPCommunitiesSet `json:"bgp_blackhole_communities"`
NeighborsColumns map[string]string `json:"neighbors_columns"`
NeighborsColumnsOrder []string `json:"neighbors_columns_order"`
RoutesColumns map[string]string `json:"routes_columns"`
RoutesColumnsOrder []string `json:"routes_columns_order"`
2017-07-04 12:36:48 +02:00
2018-08-03 10:37:05 +02:00
LookupColumns map[string]string `json:"lookup_columns"`
LookupColumnsOrder []string `json:"lookup_columns_order"`
2017-07-04 12:36:48 +02:00
PrefixLookupEnabled bool `json:"prefix_lookup_enabled"`
2017-05-18 14:44:38 +02:00
}
2021-03-24 14:26:46 +01:00
// Noexport options
2017-05-18 14:44:38 +02:00
type Noexport struct {
LoadOnDemand bool `json:"load_on_demand"`
2017-05-18 14:44:38 +02:00
}
// RejectCandidates contains a communities mapping
// of reasons for a rejection in the future.
2018-10-02 15:52:46 +02:00
type RejectCandidates struct {
Communities map[string]interface{} `json:"communities"`
}
// Rpki is the validation status of a prefix
2018-09-22 17:56:30 +02:00
type Rpki struct {
2023-11-28 14:34:12 +01:00
Enabled bool `json:"enabled"`
Valid [][]string `json:"valid"`
Unknown [][]string `json:"unknown"`
NotChecked [][]string `json:"not_checked"`
Invalid [][]string `json:"invalid"`
2018-09-22 17:56:30 +02:00
}
// Meta contains response meta information
// like cacheing time and cache ttl or the API version
type Meta struct {
2022-07-27 18:00:31 +02:00
Version string `json:"version"`
CacheStatus CacheStatus `json:"cache_status"`
ResultFromCache bool `json:"result_from_cache"`
TTL time.Time `json:"ttl"`
StoreStatus *StoreStatusMeta `json:"store_status,omitempty"`
2017-05-18 12:52:10 +02:00
}
// CacheStatus contains cache timing information.
2017-05-18 12:52:10 +02:00
type CacheStatus struct {
CachedAt time.Time `json:"cached_at"`
OrigTTL int `json:"orig_ttl"`
2017-05-18 12:52:10 +02:00
}
2022-07-27 18:00:31 +02:00
// SourceStatus is the current status of a source in
// a store.
type SourceStatus struct {
RefreshInterval time.Duration `json:"refresh_interval"`
LastRefresh time.Time `json:"last_refresh"`
State string `json:"state"`
Initialized bool `json:"initialized"`
}
// StoreStatus is meta data for a store
type StoreStatus struct {
Initialized bool `json:"initialized"`
Sources map[string]*SourceStatus `json:"sources"`
}
// StoreStatusMeta is the meta response for all stores
type StoreStatusMeta struct {
Routes *StoreStatus `json:"routes,omitempty"`
Neighbors *StoreStatus `json:"neighbors,omitempty"`
}
// Status ... TODO: ?
2017-05-18 12:52:10 +02:00
type Status struct {
ServerTime time.Time `json:"server_time"`
LastReboot time.Time `json:"last_reboot"`
LastReconfig time.Time `json:"last_reconfig"`
Message string `json:"message"`
RouterID string `json:"router_id"`
2017-05-18 12:52:10 +02:00
Version string `json:"version"`
Backend string `json:"backend"`
}
// StatusResponse ??
2017-05-18 12:52:10 +02:00
type StatusResponse struct {
2021-10-27 17:54:51 +00:00
Response
Status Status `json:"status"`
2017-05-18 12:52:10 +02:00
}
// A RouteServer is a datasource with attributes.
type RouteServer struct {
ID string `json:"id"`
2021-07-02 14:16:13 +02:00
Type string `json:"type"`
Name string `json:"name"`
2018-10-21 11:29:43 +02:00
Group string `json:"group"`
Blackholes []string `json:"blackholes"`
2018-12-09 18:47:40 +01:00
Order int `json:"-"`
}
// RouteServers is a collection of routeservers.
type RouteServers []RouteServer
2018-12-09 18:47:40 +01:00
// Len implements sorting interface for routeservers
func (rs RouteServers) Len() int {
2018-12-09 18:47:40 +01:00
return len(rs)
}
func (rs RouteServers) Less(i, j int) bool {
2018-12-09 18:47:40 +01:00
return rs[i].Order < rs[j].Order
}
func (rs RouteServers) Swap(i, j int) {
2018-12-09 18:47:40 +01:00
rs[i], rs[j] = rs[j], rs[i]
2017-05-18 12:52:10 +02:00
}
// A RouteServersResponse contains a list of routeservers.
type RouteServersResponse struct {
RouteServers RouteServers `json:"routeservers"`
2017-05-18 12:52:10 +02:00
}
// A LookupRouteServer is a shorter representation of the
// route server data source.
type LookupRouteServer struct {
ID *string `json:"id"`
Name string `json:"name"`
}
// Community is a BGP community
2017-05-18 12:52:10 +02:00
type Community []int
2018-10-16 18:21:20 +02:00
func (com Community) String() string {
2022-06-20 16:42:20 +02:00
if len(com) < 1 {
return ""
}
2022-11-25 15:38:38 +01:00
s := ""
for i, v := range com {
if i > 0 {
s += ":"
}
s += strconv.Itoa(v)
2018-10-16 18:21:20 +02:00
}
2022-11-25 15:38:38 +01:00
return s
2018-10-16 18:21:20 +02:00
}
// Communities is a collection of bgp communities
2018-11-11 17:48:34 +01:00
type Communities []Community
2022-11-25 15:38:38 +01:00
// Unique deduplicates communities.
/*
We can skip this. Worst case is, that the
cardinality is off.
2018-11-11 17:48:34 +01:00
func (communities Communities) Unique() Communities {
seen := map[string]bool{}
result := make(Communities, 0, len(communities))
for _, com := range communities {
key := com.String()
if _, ok := seen[key]; !ok {
// We have not seen this community yet
result = append(result, com)
seen[key] = true
}
}
return result
}
2022-11-25 15:38:38 +01:00
*/
2018-11-11 17:48:34 +01:00
// ExtCommunity is a BGP extended community
type ExtCommunity []interface{}
2017-05-18 12:52:10 +02:00
2018-10-16 18:21:20 +02:00
func (com ExtCommunity) String() string {
2022-06-20 16:42:20 +02:00
if len(com) < 1 {
return ""
}
2022-11-25 15:38:38 +01:00
res := ""
for i, v := range com {
if i == 0 {
res += v.(string)
continue
}
if i > 0 {
res += ":"
}
res += strconv.Itoa(v.(int))
2018-10-16 18:21:20 +02:00
}
2022-11-25 15:38:38 +01:00
return res
2018-10-16 18:21:20 +02:00
}
// ExtCommunities is a collection of extended bgp communities.
2018-11-11 17:48:34 +01:00
type ExtCommunities []ExtCommunity
// Unique deduplicates extended communities.
2022-11-25 15:38:38 +01:00
/*
2018-11-11 17:48:34 +01:00
func (communities ExtCommunities) Unique() ExtCommunities {
seen := map[string]bool{}
result := make(ExtCommunities, 0, len(communities))
for _, com := range communities {
key := com.String()
if _, ok := seen[key]; !ok {
// We have not seen this community yet
result = append(result, com)
seen[key] = true
}
}
return result
}
2022-11-25 15:38:38 +01:00
*/
2018-11-11 17:48:34 +01:00
// BGPInfo is a set of BGP attributes
type BGPInfo struct {
2022-11-16 10:25:02 +01:00
Origin *string `json:"origin"`
AsPath []int `json:"as_path"`
2022-11-16 10:25:02 +01:00
NextHop *string `json:"next_hop"`
2018-11-11 17:48:34 +01:00
Communities Communities `json:"communities"`
LargeCommunities Communities `json:"large_communities"`
ExtCommunities ExtCommunities `json:"ext_communities"`
LocalPref int `json:"local_pref"`
Med int `json:"med"`
2017-05-18 12:52:10 +02:00
}
// HasCommunity checks for the presence of a BGP community.
func (bgp *BGPInfo) HasCommunity(community Community) bool {
2018-10-17 11:05:48 +02:00
if len(community) != 2 {
return false // This can never match.
}
for _, com := range bgp.Communities {
if len(com) != len(community) {
continue // This can't match.
}
if com[0] == community[0] &&
com[1] == community[1] {
return true
}
}
return false
}
// HasExtCommunity checks for the presence of an
// extended community.
func (bgp *BGPInfo) HasExtCommunity(community ExtCommunity) bool {
2018-10-17 11:05:48 +02:00
if len(community) != 3 {
return false // This can never match.
}
for _, com := range bgp.ExtCommunities {
if len(com) != len(community) {
continue // This can't match.
}
if com[0] == community[0] &&
com[1] == community[1] &&
com[2] == community[2] {
return true
}
}
return false
}
// HasLargeCommunity checks for the presence of a large community.
func (bgp *BGPInfo) HasLargeCommunity(community Community) bool {
2018-10-17 11:05:48 +02:00
// TODO: This is an almost 1:1 match to the function above.
if len(community) != 3 {
return false // This can never match.
}
for _, com := range bgp.LargeCommunities {
if len(com) != len(community) {
continue // This can't match.
}
if com[0] == community[0] &&
com[1] == community[1] &&
com[2] == community[2] {
return true
}
}
return false
}