From 1ce2e0ac5333fe57d459f48eaef2e9b4516de2f7 Mon Sep 17 00:00:00 2001 From: Daniel Czerwonk Date: Tue, 12 Dec 2017 00:01:32 +0100 Subject: [PATCH] test for bird 2.0 channel support --- bird_client.go | 13 +++++++ main.go | 10 +++--- parser/parser.go | 8 +++-- parser_test.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 111 insertions(+), 8 deletions(-) diff --git a/bird_client.go b/bird_client.go index 540860d..266d695 100644 --- a/bird_client.go +++ b/bird_client.go @@ -7,6 +7,19 @@ import ( ) func getProtocols() ([]*protocol.Protocol, error) { + var protocols []*protocol.Protocol = nil + var err error = nil + + if *birdV2 { + protocols, err = getProtocolsFromBird(*birdSocket, 0) + } else { + protocols, err = getProtocolsFromBird1() + } + + return protocols, err +} + +func getProtocolsFromBird1() ([]*protocol.Protocol, error) { protocols := make([]*protocol.Protocol, 0) if *birdEnabled { diff --git a/main.go b/main.go index 56ec6b2..fa72fc4 100644 --- a/main.go +++ b/main.go @@ -12,16 +12,14 @@ import ( "github.com/prometheus/common/log" ) -const version string = "1.0.0" +const version string = "1.1.0" var ( showVersion = flag.Bool("version", false, "Print version information.") listenAddress = flag.String("web.listen-address", ":9324", "Address on which to expose metrics and web interface.") metricsPath = flag.String("web.telemetry-path", "/metrics", "Path under which to expose metrics.") birdSocket = flag.String("bird.socket", "/var/run/bird.ctl", "Socket to communicate with bird routing daemon") - bird6Socket = flag.String("bird.socket6", "/var/run/bird6.ctl", "Socket to communicate with bird6 routing daemon") - birdEnabled = flag.Bool("bird.ipv4", true, "Get protocols from bird") - bird6Enabled = flag.Bool("bird.ipv6", true, "Get protocols from bird6") + birdV2 = flag.Bool("bird.v2", false, "Bird major version >= 2.0 (multi channel protocols)") newFormat = flag.Bool("format.new", false, "New metric format (more convinient / generic)") enableBgp = flag.Bool("proto.bgp", true, "Enables metrics for protocol BGP") enableOspf = flag.Bool("proto.ospf", true, "Enables metrics for protocol OSPF") @@ -29,6 +27,10 @@ var ( enableStatic = flag.Bool("proto.static", true, "Enables metrics for protocol Static") enableDevice = flag.Bool("proto.device", true, "Enables metrics for protocol Device") enableDirect = flag.Bool("proto.direct", true, "Enables metrics for protocol Direct") + // pre bird 2.0 + bird6Socket = flag.String("bird.socket6", "/var/run/bird6.ctl", "Socket to communicate with bird6 routing daemon (not compatible with -bird.v2)") + birdEnabled = flag.Bool("bird.ipv4", true, "Get protocols from bird (not compatible with -bird.v2)") + bird6Enabled = flag.Bool("bird.ipv6", true, "Get protocols from bird6 (not compatible with -bird.v2)") ) func init() { diff --git a/parser/parser.go b/parser/parser.go index 3aa550d..462a976 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -14,10 +14,11 @@ import ( ) var ( - protocolRegex *regexp.Regexp - routeRegex *regexp.Regexp - uptimeRegex *regexp.Regexp + protocolRegex *regexp.Regexp + routeRegex *regexp.Regexp + uptimeRegex *regexp.Regexp routeChangeRegex *regexp.Regexp + channelRegex *regexp.Regexp ) func init() { @@ -25,6 +26,7 @@ func init() { routeRegex = regexp.MustCompile("^\\s+Routes:\\s+(\\d+) imported, (?:(\\d+) filtered, )?(\\d+) exported(?:, (\\d+) preferred)?") uptimeRegex = regexp.MustCompile("^(?:((\\d+):(\\d{2}):(\\d{2}))|\\d+)$") routeChangeRegex = regexp.MustCompile("(Import|Export) (updates|withdraws):\\s+(\\d+|---)\\s+(\\d+|---)\\s+(\\d+|---)\\s+(\\d+|---)\\s+(\\d+|---)\\s*") + channelRegex = regexp.MustCompile("Channel ipv(4|6)") } // Parser parses bird output and returns protocol.Protocol structs diff --git a/parser_test.go b/parser_test.go index 9704872..6ec23d7 100644 --- a/parser_test.go +++ b/parser_test.go @@ -3,9 +3,9 @@ package main import ( "testing" + "github.com/czerwonk/bird_exporter/parser" "github.com/czerwonk/bird_exporter/protocol" "github.com/czerwonk/testutils/assert" - "github.com/czerwonk/bird_exporter/parser" ) func TestEstablishedBgpOldTimeFormat(t *testing.T) { @@ -104,6 +104,92 @@ func TestUpdateAndWithdrawCounts(t *testing.T) { assert.Int64Equal("export withdraws accepted", 0, x.ExportWithdraws.Accepted, t) } +func TestWithBird2(t *testing.T) { + data := "Name Proto Table State Since Info\n" + + "direct1 Direct --- up 1513027903\n" + + " Channel ipv4\n" + + " State: UP\n" + + " Table: master4\n" + + " Preference: 240\n" + + " Input filter: ACCEPT\n" + + " Output filter: REJECT\n" + + " Routes: 12 imported, 1 filtered, 34 exported, 100 preferred\n" + + " Route change stats: received rejected filtered ignored accepted\n" + + " Import updates: 1 2 3 4 5\n" + + " Import withdraws: 6 7 8 9 10\n" + + " Export updates: 11 12 13 14 15\n" + + " Export withdraws: 16 17 18 19 ---\n" + + " Channel ipv6\n" + + " State: UP\n" + + " Table: master6\n" + + " Preference: 240\n" + + " Input filter: ACCEPT\n" + + " Output filter: REJECT\n" + + " Routes: 3 imported, 7 filtered, 5 exported, 13 preferred\n" + + " Route change stats: received rejected filtered ignored accepted\n" + + " Import updates: 20 21 22 23 24\n" + + " Import withdraws: 25 26 27 28 29\n" + + " Export updates: 30 31 32 33 34\n" + + " Export withdraws: 35 36 37 38 ---\n" + + p := parser.Parse([]byte(data), 0) + assert.IntEqual("protocols", 2, len(p), t) + + x := p[0] + assert.IntEqual("ipv4 ip version", 4, x.IpVersion, t) + assert.Int64Equal("ipv4 imported", 12, x.Imported, t) + assert.Int64Equal("ipv4 exported", 34, x.Exported, t) + assert.Int64Equal("ipv4 filtered", 1, x.Filtered, t) + assert.Int64Equal("ipv4 preferred", 100, x.Preferred, t) + assert.Int64Equal("ipv4 import updates received", 1, x.ImportUpdates.Received, t) + assert.Int64Equal("ipv4 import updates rejected", 2, x.ImportUpdates.Rejected, t) + assert.Int64Equal("ipv4 import updates filtered", 3, x.ImportUpdates.Filtered, t) + assert.Int64Equal("ipv4 import updates ignored", 4, x.ImportUpdates.Ignored, t) + assert.Int64Equal("ipv4 import updates accepted", 5, x.ImportUpdates.Accepted, t) + assert.Int64Equal("ipv4 import withdraws received", 6, x.ImportWithdraws.Received, t) + assert.Int64Equal("ipv4 import withdraws rejected", 7, x.ImportWithdraws.Rejected, t) + assert.Int64Equal("ipv4 import withdraws filtered", 8, x.ImportWithdraws.Filtered, t) + assert.Int64Equal("ipv4 import withdraws ignored", 9, x.ImportWithdraws.Ignored, t) + assert.Int64Equal("ipv4 import withdraws accepted", 10, x.ImportWithdraws.Accepted, t) + assert.Int64Equal("ipv4 export updates received", 11, x.ExportUpdates.Received, t) + assert.Int64Equal("ipv4 export updates rejected", 12, x.ExportUpdates.Rejected, t) + assert.Int64Equal("ipv4 export updates filtered", 13, x.ExportUpdates.Filtered, t) + assert.Int64Equal("ipv4 export updates ignored", 14, x.ExportUpdates.Ignored, t) + assert.Int64Equal("ipv4 export updates accepted", 15, x.ExportUpdates.Accepted, t) + assert.Int64Equal("ipv4 export withdraws received", 16, x.ExportWithdraws.Received, t) + assert.Int64Equal("ipv4 export withdraws rejected", 17, x.ExportWithdraws.Rejected, t) + assert.Int64Equal("ipv4 export withdraws filtered", 18, x.ExportWithdraws.Filtered, t) + assert.Int64Equal("ipv4 export withdraws ignored", 19, x.ExportWithdraws.Ignored, t) + assert.Int64Equal("ipv4 export withdraws accepted", 0, x.ExportWithdraws.Accepted, t) + + x = p[1] + assert.IntEqual("ipv6 ip version", 6, x.IpVersion, t) + assert.Int64Equal("ipv6 imported", 3, x.Imported, t) + assert.Int64Equal("ipv6 exported", 5, x.Exported, t) + assert.Int64Equal("ipv6 filtered", 7, x.Filtered, t) + assert.Int64Equal("ipv6 preferred", 13, x.Preferred, t) + assert.Int64Equal("ipv6 import updates received", 20, x.ImportUpdates.Received, t) + assert.Int64Equal("ipv6 import updates rejected", 21, x.ImportUpdates.Rejected, t) + assert.Int64Equal("ipv6 import updates filtered", 22, x.ImportUpdates.Filtered, t) + assert.Int64Equal("ipv6 import updates ignored", 23, x.ImportUpdates.Ignored, t) + assert.Int64Equal("ipv6 import updates accepted", 24, x.ImportUpdates.Accepted, t) + assert.Int64Equal("ipv6 import withdraws received", 25, x.ImportWithdraws.Received, t) + assert.Int64Equal("ipv6 import withdraws rejected", 26, x.ImportWithdraws.Rejected, t) + assert.Int64Equal("ipv6 import withdraws filtered", 27, x.ImportWithdraws.Filtered, t) + assert.Int64Equal("ipv6 import withdraws ignored", 28, x.ImportWithdraws.Ignored, t) + assert.Int64Equal("ipv6 import withdraws accepted", 29, x.ImportWithdraws.Accepted, t) + assert.Int64Equal("ipv6 export updates received", 30, x.ExportUpdates.Received, t) + assert.Int64Equal("ipv6 export updates rejected", 31, x.ExportUpdates.Rejected, t) + assert.Int64Equal("ipv6 export updates filtered", 32, x.ExportUpdates.Filtered, t) + assert.Int64Equal("ipv6 export updates ignored", 33, x.ExportUpdates.Ignored, t) + assert.Int64Equal("ipv6 export updates accepted", 34, x.ExportUpdates.Accepted, t) + assert.Int64Equal("ipv6 export withdraws received", 35, x.ExportWithdraws.Received, t) + assert.Int64Equal("ipv6 export withdraws rejected", 36, x.ExportWithdraws.Rejected, t) + assert.Int64Equal("ipv6 export withdraws filtered", 37, x.ExportWithdraws.Filtered, t) + assert.Int64Equal("ipv6 export withdraws ignored", 38, x.ExportWithdraws.Ignored, t) + assert.Int64Equal("ipv6 export withdraws accepted", 0, x.ExportWithdraws.Accepted, t) +} + func TestOspfOldTimeFormat(t *testing.T) { data := "ospf1 OSPF master up 1481973060 Running\ntest\nbar\n Routes: 12 imported, 34 exported, 100 preferred\nxxx" p := parser.Parse([]byte(data), 4)