mirror of
https://github.com/alice-lg/birdwatcher.git
synced 2025-03-09 00:00:05 +01:00
added bgp parser
This commit is contained in:
parent
9337b1c32c
commit
ad3919768c
3 changed files with 224 additions and 12 deletions
11
bird/bird.go
11
bird/bird.go
|
@ -3,7 +3,6 @@ package bird
|
|||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func Run(args string) ([]byte, error) {
|
||||
|
@ -32,16 +31,14 @@ func Protocols() Parsed {
|
|||
}
|
||||
|
||||
func ProtocolsBgp() Parsed {
|
||||
protocols := Protocols()
|
||||
protocols := Protocols()["protocols"].([]string)
|
||||
|
||||
bgpProto := Parsed{}
|
||||
bgp_rx := regexp.MustCompile(`^(\w+)\s+BGP\s+.*`)
|
||||
|
||||
for _, v := range protocols {
|
||||
vs := v.(string)
|
||||
if bgp_rx.MatchString(vs) {
|
||||
key := bgp_rx.FindStringSubmatch(vs)[1]
|
||||
bgpProto[key] = parseBgp(vs)
|
||||
if strings.Contains(v, " BGP ") {
|
||||
key := strings.Split(v, " ")[0]
|
||||
bgpProto[key] = parseBgp(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
223
bird/parser.go
223
bird/parser.go
|
@ -12,12 +12,12 @@ func emptyLine(line string) bool {
|
|||
return len(strings.TrimSpace(line)) == 0
|
||||
}
|
||||
|
||||
func getLinesUnfiltered(input []byte) []string {
|
||||
func getLinesUnfiltered(input string) []string {
|
||||
line_sep := regexp.MustCompile(`((\r?\n)|(\r\n?))`)
|
||||
return line_sep.Split(string(input), -1)
|
||||
return line_sep.Split(input, -1)
|
||||
}
|
||||
|
||||
func getLines(input []byte) []string {
|
||||
func getLinesFromString(input string) []string {
|
||||
lines := getLinesUnfiltered(input)
|
||||
|
||||
var filtered []string
|
||||
|
@ -31,6 +31,10 @@ func getLines(input []byte) []string {
|
|||
return filtered
|
||||
}
|
||||
|
||||
func getLines(input []byte) []string {
|
||||
return getLinesFromString(string(input))
|
||||
}
|
||||
|
||||
func specialLine(line string) bool {
|
||||
return (strings.HasPrefix(line, "BIRD") ||
|
||||
strings.HasPrefix(line, "Access restricted"))
|
||||
|
@ -67,7 +71,7 @@ func parseStatus(input []byte) Parsed {
|
|||
func parseProtocols(input []byte) Parsed {
|
||||
res := Parsed{}
|
||||
protocols := []string{}
|
||||
lines := getLinesUnfiltered(input)
|
||||
lines := getLinesUnfiltered(string(input))
|
||||
|
||||
proto := ""
|
||||
for _, line := range lines {
|
||||
|
@ -231,8 +235,219 @@ func parseRoutesCount(input []byte) Parsed {
|
|||
return res
|
||||
}
|
||||
|
||||
// Will snake_case a value like that:
|
||||
// I am a Weird stRiNg -> i_am_a_weird_string
|
||||
func treatKey(key string) string {
|
||||
spaces := regexp.MustCompile(`\s+`)
|
||||
key = spaces.ReplaceAllString(key, "_")
|
||||
return strings.ToLower(key)
|
||||
}
|
||||
|
||||
func parseBgp(input string) Parsed {
|
||||
res := Parsed{}
|
||||
lines := getLinesFromString(input)
|
||||
route_changes := Parsed{}
|
||||
|
||||
bgp_rx := regexp.MustCompile(`^([\w\.]+)\s+BGP\s+(\w+)\s+(\w+)\s+([0-9]{4}-[0-9]{2}-[0-9]{2}\s+[0-9]{2}:[0-9]{2}:[0-9]{2})\s*(\w+)?.*$`)
|
||||
num_val_rx := regexp.MustCompile(`^\s+([^:]+):\s+([\d]+)\s*$`)
|
||||
str_val_rx := regexp.MustCompile(`^\s+([^:]+):\s+(.+)\s*$`)
|
||||
routes_rx := regexp.MustCompile(`^\s+Routes:\s+(\d+)\s+imported,\s+(\d+)\s+filtered,\s+(\d+)\s+exported,\s+(\d+)\s+preferred\s*$`)
|
||||
imp_updates_rx := regexp.MustCompile(`^\s+Import updates:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$`)
|
||||
imp_withdraws_rx := regexp.MustCompile(`^\s+Import withdraws:\s+(\d+)\s+(\d+)\s+\-\-\-\s+(\d+)\s+(\d+)\s*$`)
|
||||
exp_updates_rx := regexp.MustCompile(`^\s+Export updates:\s+(\d+)\s+(\d+)\s+(\d+)\s+\-\-\-\s+(\d+)\s*$`)
|
||||
exp_withdraws_rx := regexp.MustCompile(`^\s+Export withdraws:\s+(\d+)(\s+\-\-\-)+\s+(\d+)\s*$`)
|
||||
for _, line := range lines {
|
||||
if bgp_rx.MatchString(line) {
|
||||
groups := bgp_rx.FindStringSubmatch(line)
|
||||
|
||||
res["protocol"] = groups[1]
|
||||
res["bird_protocol"] = "BGP"
|
||||
res["table"] = groups[2]
|
||||
res["state"] = groups[3]
|
||||
res["state_changed"] = groups[4]
|
||||
res["connection"] = groups[5]
|
||||
} else if routes_rx.MatchString(line) {
|
||||
routes := Parsed{}
|
||||
groups := routes_rx.FindStringSubmatch(line)
|
||||
|
||||
imported, err := strconv.ParseInt(groups[1], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
filtered, err := strconv.ParseInt(groups[2], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
exported, err := strconv.ParseInt(groups[3], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
preferred, err := strconv.ParseInt(groups[4], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
|
||||
routes["imported"] = imported
|
||||
routes["filtered"] = filtered
|
||||
routes["exported"] = exported
|
||||
routes["preferred"] = preferred
|
||||
|
||||
res["routes"] = routes
|
||||
} else if imp_updates_rx.MatchString(line) {
|
||||
updates := Parsed{}
|
||||
groups := imp_updates_rx.FindStringSubmatch(line)
|
||||
|
||||
received, err := strconv.ParseInt(groups[1], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
rejected, err := strconv.ParseInt(groups[2], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
filtered, err := strconv.ParseInt(groups[3], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
ignored, err := strconv.ParseInt(groups[4], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
accepted, err := strconv.ParseInt(groups[5], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
|
||||
updates["received"] = received
|
||||
updates["rejected"] = rejected
|
||||
updates["filtered"] = filtered
|
||||
updates["ignored"] = ignored
|
||||
updates["accepted"] = accepted
|
||||
|
||||
route_changes["import_updates"] = updates
|
||||
} else if imp_withdraws_rx.MatchString(line) {
|
||||
updates := Parsed{}
|
||||
groups := imp_withdraws_rx.FindStringSubmatch(line)
|
||||
|
||||
received, err := strconv.ParseInt(groups[1], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
rejected, err := strconv.ParseInt(groups[2], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
filtered, err := strconv.ParseInt(groups[3], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
accepted, err := strconv.ParseInt(groups[4], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
|
||||
updates["received"] = received
|
||||
updates["rejected"] = rejected
|
||||
updates["filtered"] = filtered
|
||||
updates["accepted"] = accepted
|
||||
|
||||
route_changes["import_withdraws"] = updates
|
||||
} else if exp_updates_rx.MatchString(line) {
|
||||
updates := Parsed{}
|
||||
groups := exp_updates_rx.FindStringSubmatch(line)
|
||||
|
||||
received, err := strconv.ParseInt(groups[1], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
rejected, err := strconv.ParseInt(groups[2], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
ignored, err := strconv.ParseInt(groups[3], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
accepted, err := strconv.ParseInt(groups[4], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
|
||||
updates["received"] = received
|
||||
updates["rejected"] = rejected
|
||||
updates["ignored"] = ignored
|
||||
updates["accepted"] = accepted
|
||||
|
||||
route_changes["export_updates"] = updates
|
||||
} else if exp_withdraws_rx.MatchString(line) {
|
||||
updates := Parsed{}
|
||||
groups := exp_withdraws_rx.FindStringSubmatch(line)
|
||||
|
||||
received, err := strconv.ParseInt(groups[1], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
accepted, err := strconv.ParseInt(groups[3], 10, 64)
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
|
||||
updates["received"] = received
|
||||
updates["accepted"] = accepted
|
||||
|
||||
route_changes["export_withdraws"] = updates
|
||||
} else if num_val_rx.MatchString(line) {
|
||||
groups := num_val_rx.FindStringSubmatch(line)
|
||||
|
||||
key := treatKey(groups[1])
|
||||
val, err := strconv.ParseInt(groups[2], 10, 64)
|
||||
|
||||
if err != nil {
|
||||
// ignore for now
|
||||
continue
|
||||
}
|
||||
|
||||
res[key] = val
|
||||
} else if str_val_rx.MatchString(line) {
|
||||
groups := str_val_rx.FindStringSubmatch(line)
|
||||
|
||||
key := treatKey(groups[1])
|
||||
|
||||
res[key] = groups[2]
|
||||
}
|
||||
}
|
||||
|
||||
res["route_changes"] = route_changes
|
||||
|
||||
if _, ok := res["routes"]; !ok {
|
||||
routes := Parsed{}
|
||||
|
||||
routes["accepted"] = 0
|
||||
routes["filtered"] = 0
|
||||
routes["exported"] = 0
|
||||
routes["preferred"] = 0
|
||||
|
||||
res["routes"] = routes
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ func Bgp(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|||
|
||||
res["api"] = GetApiInfo()
|
||||
|
||||
res["protocols"] = bird.ProtocolsBgp()["protocols"]
|
||||
res["protocols"] = bird.ProtocolsBgp()
|
||||
|
||||
js, _ := json.Marshal(res)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue