1
0
Fork 0
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:
hellerve 2016-11-11 13:28:40 +01:00
parent 9337b1c32c
commit ad3919768c
3 changed files with 224 additions and 12 deletions

View file

@ -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)
}
}

View file

@ -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
}

View file

@ -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)