mirror of
https://github.com/alice-lg/birdwatcher.git
synced 2025-03-09 00:00:05 +01:00
added caching to birdwatcher
This commit is contained in:
parent
7c8ea17a06
commit
5bb95f264f
7 changed files with 67 additions and 38 deletions
63
bird/bird.go
63
bird/bird.go
|
@ -3,37 +3,66 @@ package bird
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
"sync"
|
||||
)
|
||||
|
||||
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 {
|
||||
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{}
|
||||
return Parsed{}, false
|
||||
}
|
||||
|
||||
return parser(out)
|
||||
parsed := parser(out)
|
||||
toCache(cmd, parsed)
|
||||
return parsed, false
|
||||
}
|
||||
|
||||
func Status() Parsed {
|
||||
func Status() (Parsed, bool) {
|
||||
return RunAndParse("status", parseStatus)
|
||||
}
|
||||
|
||||
func Protocols() Parsed {
|
||||
func Protocols() (Parsed, bool) {
|
||||
return RunAndParse("protocols all", parseProtocols)
|
||||
}
|
||||
|
||||
func ProtocolsBgp() Parsed {
|
||||
protocols := Protocols()["protocols"].([]string)
|
||||
func ProtocolsBgp() (Parsed, bool) {
|
||||
p, from_cache := Protocols()
|
||||
protocols := p["protocols"].([]string)
|
||||
|
||||
bgpProto := Parsed{}
|
||||
|
||||
|
@ -44,49 +73,49 @@ func ProtocolsBgp() Parsed {
|
|||
}
|
||||
}
|
||||
|
||||
return Parsed{"protocols": bgpProto}
|
||||
return Parsed{"protocols": bgpProto}, from_cache
|
||||
}
|
||||
|
||||
func Symbols() Parsed {
|
||||
func Symbols() (Parsed, bool) {
|
||||
return RunAndParse("symbols", parseSymbols)
|
||||
}
|
||||
|
||||
func RoutesProto(protocol string) Parsed {
|
||||
func RoutesProto(protocol string) (Parsed, bool) {
|
||||
return RunAndParse("route protocol "+protocol+" all",
|
||||
parseRoutes)
|
||||
}
|
||||
|
||||
func RoutesProtoCount(protocol string) Parsed {
|
||||
func RoutesProtoCount(protocol string) (Parsed, bool) {
|
||||
return RunAndParse("route protocol "+protocol+" count",
|
||||
parseRoutesCount)
|
||||
}
|
||||
|
||||
func RoutesExport(protocol string) Parsed {
|
||||
func RoutesExport(protocol string) (Parsed, bool) {
|
||||
return RunAndParse("route export "+protocol+" all",
|
||||
parseRoutes)
|
||||
}
|
||||
|
||||
func RoutesExportCount(protocol string) Parsed {
|
||||
func RoutesExportCount(protocol string) (Parsed, bool) {
|
||||
return RunAndParse("route export "+protocol+" count",
|
||||
parseRoutesCount)
|
||||
}
|
||||
|
||||
func RoutesTable(table string) Parsed {
|
||||
func RoutesTable(table string) (Parsed, bool) {
|
||||
return RunAndParse("route table "+table+" all",
|
||||
parseRoutes)
|
||||
}
|
||||
|
||||
func RoutesTableCount(table string) Parsed {
|
||||
func RoutesTableCount(table string) (Parsed, bool) {
|
||||
return RunAndParse("route table "+table+" count",
|
||||
parseRoutesCount)
|
||||
}
|
||||
|
||||
func RoutesLookupTable(net string, table string) Parsed {
|
||||
func RoutesLookupTable(net string, table string) (Parsed, bool) {
|
||||
return RunAndParse("route for "+net+" table "+table+" all",
|
||||
parseRoutes)
|
||||
}
|
||||
|
||||
func RoutesLookupProtocol(net string, protocol string) Parsed {
|
||||
func RoutesLookupProtocol(net string, protocol string) (Parsed, bool) {
|
||||
return RunAndParse("route for "+net+" protocol "+protocol+" all",
|
||||
parseRoutes)
|
||||
}
|
||||
|
|
|
@ -8,15 +8,14 @@ import (
|
|||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func Endpoint(wrapped func(httprouter.Params) bird.Parsed) httprouter.Handle {
|
||||
func Endpoint(wrapped func(httprouter.Params) (bird.Parsed, bool)) httprouter.Handle {
|
||||
return func(w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
ps httprouter.Params) {
|
||||
res := make(map[string]interface{})
|
||||
|
||||
res["api"] = GetApiInfo()
|
||||
|
||||
ret := wrapped(ps)
|
||||
ret, from_cache := wrapped(ps)
|
||||
res["api"] = GetApiInfo(from_cache)
|
||||
|
||||
for k, v := range ret {
|
||||
res[k] = v
|
||||
|
|
|
@ -5,10 +5,10 @@ import (
|
|||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func Protocols(ps httprouter.Params) bird.Parsed {
|
||||
func Protocols(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.Protocols()
|
||||
}
|
||||
|
||||
func Bgp(ps httprouter.Params) bird.Parsed {
|
||||
func Bgp(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.ProtocolsBgp()
|
||||
}
|
||||
|
|
|
@ -5,26 +5,26 @@ import (
|
|||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func ProtoRoutes(ps httprouter.Params) bird.Parsed {
|
||||
func ProtoRoutes(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.RoutesProto(ps.ByName("protocol"))
|
||||
}
|
||||
|
||||
func TableRoutes(ps httprouter.Params) bird.Parsed {
|
||||
func TableRoutes(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.RoutesTable(ps.ByName("table"))
|
||||
}
|
||||
|
||||
func ProtoCount(ps httprouter.Params) bird.Parsed {
|
||||
func ProtoCount(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.RoutesProtoCount(ps.ByName("protocol"))
|
||||
}
|
||||
|
||||
func TableCount(ps httprouter.Params) bird.Parsed {
|
||||
func TableCount(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.RoutesTable(ps.ByName("table"))
|
||||
}
|
||||
|
||||
func RouteNet(ps httprouter.Params) bird.Parsed {
|
||||
func RouteNet(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.RoutesLookupTable(ps.ByName("net"), "master")
|
||||
}
|
||||
|
||||
func RouteNetTable(ps httprouter.Params) bird.Parsed {
|
||||
func RouteNetTable(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.RoutesLookupTable(ps.ByName("net"), ps.ByName("table"))
|
||||
}
|
||||
|
|
|
@ -5,6 +5,6 @@ import (
|
|||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func Status(ps httprouter.Params) bird.Parsed {
|
||||
func Status(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.Status()
|
||||
}
|
||||
|
|
|
@ -5,14 +5,16 @@ import (
|
|||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
|
||||
func Symbols(ps httprouter.Params) bird.Parsed {
|
||||
func Symbols(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
return bird.Symbols()
|
||||
}
|
||||
|
||||
func SymbolTables(ps httprouter.Params) bird.Parsed {
|
||||
return bird.Parsed{"symbols": bird.Symbols()["routing table"]}
|
||||
func SymbolTables(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
val, from_cache := bird.Symbols()
|
||||
return bird.Parsed{"symbols": val["routing table"]}, from_cache
|
||||
}
|
||||
|
||||
func SymbolProtocols(ps httprouter.Params) bird.Parsed {
|
||||
return bird.Parsed{"symbols": bird.Symbols()["protocols"]}
|
||||
func SymbolProtocols(ps httprouter.Params) (bird.Parsed, bool) {
|
||||
val, from_cache := bird.Symbols()
|
||||
return bird.Parsed{"symbols": val["protocols"]}, from_cache
|
||||
}
|
||||
|
|
|
@ -17,12 +17,11 @@ type APIInfo struct {
|
|||
CacheStatus CacheStatus `json:"cache_status"`
|
||||
}
|
||||
|
||||
func GetApiInfo() *APIInfo {
|
||||
func GetApiInfo(from_cache bool) *APIInfo {
|
||||
ai := &APIInfo{}
|
||||
|
||||
/* Dummy data until we implement caching */
|
||||
ai.Version = "1.0"
|
||||
ai.ResultFromCache = false
|
||||
ai.ResultFromCache = from_cache
|
||||
|
||||
return ai
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue