1
0
Fork 0
mirror of https://github.com/alice-lg/birdwatcher.git synced 2025-03-09 00:00:05 +01:00

API redesign - make birdwatcher more generic

Removed all high level functionality e.g. endpoints with multiple
invocations of birdc.
Add new endpoints which are required to duplicate the removed
functionality within Alice-LG.
This commit is contained in:
Patrick Seeburger 2019-01-18 18:10:06 +01:00 committed by Benedikt Rudolph
parent 12be0f9de3
commit c4dfeb253d
5 changed files with 64 additions and 125 deletions

View file

@ -217,7 +217,6 @@ func Protocols() (Parsed, bool) {
for key, _ := range (*p)["protocols"].(Parsed) {
parsed := (*p)["protocols"].(Parsed)[key].(Parsed)
protocol := parsed["protocol"].(string)
birdProtocol := parsed["bird_protocol"].(string)
@ -269,6 +268,16 @@ func RoutesProto(protocol string) (Parsed, bool) {
return RunAndParse(GetCacheKey("RoutesProto", protocol), cmd, parseRoutes, nil)
}
func RoutesPeer(peer string) (Parsed, bool) {
cmd := routeQueryForChannel("route all where from=" + peer)
return RunAndParse(GetCacheKey("RoutesPeer", peer), cmd, parseRoutes, nil)
}
func RoutesTableAndPeer(table string, peer string) (Parsed, bool) {
cmd := routeQueryForChannel("route table " + table + " all where from=" + peer)
return RunAndParse(GetCacheKey("RoutesTableAndPeer", table, peer), cmd, parseRoutes, nil)
}
func RoutesProtoCount(protocol string) (Parsed, bool) {
cmd := routeQueryForChannel("route protocol "+protocol) + " count"
return RunAndParse(GetCacheKey("RoutesProtoCount", protocol), cmd, parseRoutesCount, nil)
@ -300,24 +309,6 @@ func RoutesExport(protocol string) (Parsed, bool) {
}
func RoutesNoExport(protocol string) (Parsed, bool) {
// In case we have a multi table setup, we have to query
// the pipe protocol.
if ParserConf.PerPeerTables &&
strings.HasPrefix(protocol, ParserConf.PeerProtocolPrefix) {
protocolsRes, from_cache := ProtocolsBgp()
if IsSpecial(protocolsRes) {
return protocolsRes, from_cache
}
if _, ok := protocolsRes["protocols"].(Parsed)[protocol]; !ok {
return NilParse, false
}
// Replace prefix
protocol = ParserConf.PipeProtocolPrefix +
protocol[len(ParserConf.PeerProtocolPrefix):]
}
cmd := routeQueryForChannel("route all noexport " + protocol)
return RunAndParse(GetCacheKey("RoutesNoExport", protocol), cmd, parseRoutes, nil)
}
@ -331,6 +322,10 @@ func RoutesTable(table string) (Parsed, bool) {
return RunAndParse(GetCacheKey("RoutesTable", table), "route table "+table+" all", parseRoutes, nil)
}
func RoutesTableFiltered(table string) (Parsed, bool) {
return RunAndParse(GetCacheKey("RoutesTableFiltered", table), "route table "+table+" filtered", parseRoutes, nil)
}
func RoutesTableCount(table string) (Parsed, bool) {
return RunAndParse(GetCacheKey("RoutesTableCount", table), "route table "+table+" count", parseRoutesCount, nil)
}
@ -343,85 +338,6 @@ func RoutesLookupProtocol(net string, protocol string) (Parsed, bool) {
return RunAndParse(GetCacheKey("RoutesLookupProtocol", net, protocol), "route for "+net+" protocol "+protocol+" all", parseRoutes, nil)
}
func RoutesPeer(peer string) (Parsed, bool) {
cmd := routeQueryForChannel("route export " + peer)
return RunAndParse(GetCacheKey("RoutesPeer", peer), cmd, parseRoutes, nil)
}
func RoutesDump() (Parsed, bool) {
// TODO insert hook to update the cache with the route count information
if ParserConf.PerPeerTables {
return RoutesDumpPerPeerTable()
}
return RoutesDumpSingleTable()
}
func RoutesDumpSingleTable() (Parsed, bool) {
importedRes, cached := RunAndParse(GetCacheKey("RoutesDumpSingleTable", "imported"), routeQueryForChannel("route all"), parseRoutes, nil)
if IsSpecial(importedRes) {
return importedRes, cached
}
filteredRes, cached := RunAndParse(GetCacheKey("RoutesDumpSingleTable", "filtered"), routeQueryForChannel("route all filtered"), parseRoutes, nil)
if IsSpecial(filteredRes) {
return filteredRes, cached
}
imported := importedRes["routes"]
filtered := filteredRes["routes"]
result := Parsed{
"imported": imported,
"filtered": filtered,
}
return result, cached
}
func RoutesDumpPerPeerTable() (Parsed, bool) {
importedRes, cached := RunAndParse(GetCacheKey("RoutesDumpPerPeerTable", "imported"), routeQueryForChannel("route all"), parseRoutes, nil)
if IsSpecial(importedRes) {
return importedRes, cached
}
imported := importedRes["routes"]
filtered := []Parsed{}
// Get protocols with filtered routes
protocolsRes, cached := ProtocolsBgp()
if IsSpecial(protocolsRes) {
return protocolsRes, cached
}
protocols := protocolsRes["protocols"].(Parsed)
for protocol, details := range protocols {
details := details.(Parsed)
counters, ok := details["routes"].(Parsed)
if !ok {
continue
}
filterCount := counters["filtered"]
if filterCount == 0 {
continue // nothing to do here.
}
// Lookup filtered routes
pfilteredRes, _ := RoutesFiltered(protocol)
pfiltered, ok := pfilteredRes["routes"].([]Parsed)
if !ok {
continue // something went wrong...
}
filtered = append(filtered, pfiltered...)
}
result := Parsed{
"imported": imported,
"filtered": filtered,
}
return result, cached
}
func routeQueryForChannel(cmd string) string {
status, _ := Status()
if IsSpecial(status) {

View file

@ -17,10 +17,7 @@ type BirdConfig struct {
}
type ParserConfig struct {
FilterFields []string `toml:"filter_fields"`
PerPeerTables bool `toml:"per_peer_tables"`
PeerProtocolPrefix string `toml:"peer_protocol_prefix"`
PipeProtocolPrefix string `toml:"pipe_protocol_prefix"`
FilterFields []string `toml:"filter_fields"`
}
type RateLimitConfig struct {

View file

@ -16,7 +16,7 @@ import (
)
//go:generate versionize
var VERSION = "1.11.0"
var VERSION = "1.13.0"
func isModuleEnabled(module string, modulesEnabled []string) bool {
for _, enabled := range modulesEnabled {
@ -54,9 +54,18 @@ func makeRouter(config endpoints.ServerConfig) *httprouter.Router {
if isModuleEnabled("routes_protocol", whitelist) {
r.GET("/routes/protocol/:protocol", endpoints.Endpoint(endpoints.ProtoRoutes))
}
if isModuleEnabled("routes_peer", whitelist) {
r.GET("/routes/peer/:peer", endpoints.Endpoint(endpoints.PeerRoutes))
}
if isModuleEnabled("routes_table", whitelist) {
r.GET("/routes/table/:table", endpoints.Endpoint(endpoints.TableRoutes))
}
if isModuleEnabled("routes_table_filtered", whitelist) {
r.GET("/routes/table/:table/filtered", endpoints.Endpoint(endpoints.TableRoutesFiltered))
}
if isModuleEnabled("routes_table_peer", whitelist) {
r.GET("/routes/table/:table/peer/:peer", endpoints.Endpoint(endpoints.TableAndPeerRoutes))
}
if isModuleEnabled("routes_count_protocol", whitelist) {
r.GET("/routes/count/protocol/:protocol", endpoints.Endpoint(endpoints.ProtoCount))
}
@ -79,12 +88,13 @@ func makeRouter(config endpoints.ServerConfig) *httprouter.Router {
r.GET("/route/net/:net", endpoints.Endpoint(endpoints.RouteNet))
r.GET("/route/net/:net/table/:table", endpoints.Endpoint(endpoints.RouteNetTable))
}
if isModuleEnabled("routes_peer", whitelist) {
r.GET("/routes/peer", endpoints.Endpoint(endpoints.RoutesPeer))
if isModuleEnabled("routes_pipe_filtered_count", whitelist) {
r.GET("/routes/pipe/filtered/count", endpoints.Endpoint(endpoints.PipeRoutesFilteredCount))
}
if isModuleEnabled("routes_dump", whitelist) {
r.GET("/routes/dump", endpoints.Endpoint(endpoints.RoutesDump))
if isModuleEnabled("routes_pipe_filtered", whitelist) {
r.GET("/routes/pipe/filtered", endpoints.Endpoint(endpoints.PipeRoutesFiltered))
}
return r
}
@ -108,8 +118,6 @@ func PrintServiceInfo(conf *Config, birdConf bird.BirdConfig) {
for _, m := range conf.Server.ModulesEnabled {
log.Println(" -", m)
}
log.Println(" Per Peer Tables:", conf.Parser.PerPeerTables)
}
// MyLogger is our own log.Logger wrapper so we can customize it

View file

@ -50,6 +50,14 @@ func TableRoutes(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesTable(ps.ByName("table"))
}
func TableRoutesFiltered(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesTableFiltered(ps.ByName("table"))
}
func TableAndPeerRoutes(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesTableAndPeer(ps.ByName("table"), ps.ByName("peer"))
}
func ProtoCount(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
protocol, err := ValidateProtocolParam(ps.ByName("protocol"))
if err != nil {
@ -78,20 +86,21 @@ func RouteNetTable(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesLookupTable(ps.ByName("net"), ps.ByName("table"))
}
func RoutesPeer(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
func PipeRoutesFiltered(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
qs := r.URL.Query()
peerl := qs["peer"]
if len(peerl) != 1 {
return bird.Parsed{"error": "need a peer as single query parameter"}, false
}
peer, err := ValidateProtocolParam(peerl[0])
if err != nil {
return bird.Parsed{"error": fmt.Sprintf("%s", err)}, false
}
return bird.RoutesPeer(peer)
table := qs["table"][0]
pipe := qs["pipe"][0]
return bird.PipeRoutesFiltered(pipe, table)
}
func RoutesDump(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesDump()
func PipeRoutesFilteredCount(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
qs := r.URL.Query()
table := qs["table"][0]
pipe := qs["pipe"][0]
address := qs["address"][0]
return bird.PipeRoutesFilteredCount(pipe, table, address)
}
func PeerRoutes(r *http.Request, ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesPeer(ps.ByName("peer"))
}

15
etc/birdwatcher/birdwatcher.conf Normal file → Executable file
View file

@ -15,7 +15,10 @@ allow_from = []
# protocols
# protocols_bgp
# routes_protocol
# routes_peer
# routes_table
# routes_table_filtered
# routes_table_peer
# routes_count_protocol
# routes_count_table
# routes_count_primary
@ -23,8 +26,8 @@ allow_from = []
# routes_prefixed
# routes_noexport
# route_net
## high-level modules (aggregated data from multiple birdc invocations)
# routes_dump
# routes_pipe_filtered_count
# routes_pipe_filtered
# routes_peer
@ -33,8 +36,14 @@ modules_enabled = ["status",
"protocols_bgp",
"routes_protocol",
"routes_peer",
"routes_table",
"routes_table_filtered",
"routes_table_peer",
"routes_filtered",
"routes_prefixed",
"routes_dump"
"routes_noexport",
"routes_pipe_filtered_count",
"routes_pipe_filtered"
]
[status]