mirror of
https://github.com/alice-lg/birdwatcher.git
synced 2025-03-30 00:00:17 +01:00
120 lines
2.5 KiB
Go
120 lines
2.5 KiB
Go
package bird
|
|
|
|
import (
|
|
"os/exec"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var BirdCmd string
|
|
|
|
var Cache = struct {
|
|
sync.RWMutex
|
|
m map[string]Parsed
|
|
}{m: make(map[string]Parsed)}
|
|
|
|
func fromCache(key string) (Parsed, bool) {
|
|
Cache.RLock()
|
|
val, ok := Cache.m[key]
|
|
Cache.RUnlock()
|
|
return val, ok
|
|
}
|
|
|
|
func toCache(key string, val Parsed) {
|
|
val["ttl"] = time.Now().Add(5 * time.Minute)
|
|
Cache.Lock()
|
|
Cache.m[key] = val
|
|
Cache.Unlock()
|
|
}
|
|
|
|
func Run(args string) ([]byte, error) {
|
|
args = "show " + args
|
|
argsList := strings.Split(args, " ")
|
|
return exec.Command(BirdCmd, argsList...).Output()
|
|
}
|
|
|
|
func RunAndParse(cmd string, parser func([]byte) Parsed) (Parsed, bool) {
|
|
if val, ok := fromCache(cmd); ok {
|
|
return val, true
|
|
}
|
|
|
|
out, err := Run(cmd)
|
|
|
|
if err != nil {
|
|
// ignore errors for now
|
|
return Parsed{}, false
|
|
}
|
|
|
|
parsed := parser(out)
|
|
toCache(cmd, parsed)
|
|
return parsed, false
|
|
}
|
|
|
|
func Status() (Parsed, bool) {
|
|
return RunAndParse("status", parseStatus)
|
|
}
|
|
|
|
func Protocols() (Parsed, bool) {
|
|
return RunAndParse("protocols all", parseProtocols)
|
|
}
|
|
|
|
func ProtocolsBgp() (Parsed, bool) {
|
|
p, from_cache := Protocols()
|
|
protocols := p["protocols"].([]string)
|
|
|
|
bgpProto := Parsed{}
|
|
|
|
for _, v := range protocols {
|
|
if strings.Contains(v, " BGP ") {
|
|
key := strings.Split(v, " ")[0]
|
|
bgpProto[key] = parseBgp(v)
|
|
}
|
|
}
|
|
|
|
return Parsed{"protocols": bgpProto}, from_cache
|
|
}
|
|
|
|
func Symbols() (Parsed, bool) {
|
|
return RunAndParse("symbols", parseSymbols)
|
|
}
|
|
|
|
func RoutesProto(protocol string) (Parsed, bool) {
|
|
return RunAndParse("route protocol '"+protocol+"' all",
|
|
parseRoutes)
|
|
}
|
|
|
|
func RoutesProtoCount(protocol string) (Parsed, bool) {
|
|
return RunAndParse("route protocol '"+protocol+"' count",
|
|
parseRoutesCount)
|
|
}
|
|
|
|
func RoutesExport(protocol string) (Parsed, bool) {
|
|
return RunAndParse("route export '"+protocol+"' all",
|
|
parseRoutes)
|
|
}
|
|
|
|
func RoutesExportCount(protocol string) (Parsed, bool) {
|
|
return RunAndParse("route export '"+protocol+"' count",
|
|
parseRoutesCount)
|
|
}
|
|
|
|
func RoutesTable(table string) (Parsed, bool) {
|
|
return RunAndParse("route table '"+table+"' all",
|
|
parseRoutes)
|
|
}
|
|
|
|
func RoutesTableCount(table string) (Parsed, bool) {
|
|
return RunAndParse("route table '"+table+"' count",
|
|
parseRoutesCount)
|
|
}
|
|
|
|
func RoutesLookupTable(net string, table string) (Parsed, bool) {
|
|
return RunAndParse("route for '"+net+"' table '"+table+"' all",
|
|
parseRoutes)
|
|
}
|
|
|
|
func RoutesLookupProtocol(net string, protocol string) (Parsed, bool) {
|
|
return RunAndParse("route for '"+net+"' protocol '"+protocol+"' all",
|
|
parseRoutes)
|
|
}
|