Compare commits

...

58 Commits

Author SHA1 Message Date
e1e6d5c513 add drone
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2023-05-27 12:50:01 +01:00
1c1570db05
fix ubuntu
Some checks failed
continuous-integration/drone/push Build is failing
2023-05-27 11:12:21 +01:00
2fcd228f8b
update drone
Some checks reported errors
continuous-integration/drone Build encountered an error
2023-05-27 11:10:13 +01:00
0f8906abc2 add drone pipeline 2023-05-26 23:51:06 +01:00
dependabot[bot]
43b1050a87
Bump github.com/stretchr/testify from 1.8.2 to 1.8.3 (#91)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.3.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.3)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-20 13:41:37 +02:00
dependabot[bot]
75335d1fdb
Bump github.com/sirupsen/logrus from 1.9.0 to 1.9.2 (#90)
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.0 to 1.9.2.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.2)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-18 14:02:18 +02:00
kralewitz
356c13e20e
Add metric representing bird socket query result (#82)
A new gauge metric named `bird_socket_query_success` holds the result of
querying the bird socket for protocol status. If set to 1, the socket
was queried successfully. If the query fails for any of the configured
sockets (IPv4 / IPv6), the value of this metric will be 0.

Co-authored-by: Jan Kral <jan.kral@4net.tv>
2023-05-09 14:33:19 +02:00
Vladimir Shipilov
ca13cd9b96
Fix collecting for bfd sessions stucked in Init state (#86) 2023-05-09 14:32:05 +02:00
Fredrik Liv
446837936c
Added helm chart (#83) 2023-05-09 14:31:18 +02:00
dependabot[bot]
60e7d4f4bc
Bump github.com/prometheus/client_golang from 1.14.0 to 1.15.1 (#87) 2023-05-08 17:25:13 +02:00
Daniel Czerwonk
ca20239b5f
Update release.yml 2023-03-10 11:44:31 +01:00
Daniel Czerwonk
9ff27089a7
Update test.yml 2023-03-10 11:41:08 +01:00
Daniel Czerwonk
f01a153115
Update test.yml 2023-03-02 21:29:19 +01:00
Daniel Czerwonk
e87aef75a8
Create CODEOWNERS 2023-03-02 21:25:27 +01:00
dependabot[bot]
d3d9cdfbe6
Bump github.com/stretchr/testify from 1.8.1 to 1.8.2 (#84)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.1 to 1.8.2.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.1...v1.8.2)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-27 09:56:22 +01:00
Daniel Czerwonk
dd80f4ea21 Merge remote-tracking branch 'origin/master'
Signed-off-by: Daniel Czerwonk <daniel@dan-nrw.de>
2023-02-08 06:41:53 +01:00
Daniel Czerwonk
945b4e8c96 upgrade to go 1.20
Signed-off-by: Daniel Czerwonk <daniel@dan-nrw.de>
2023-02-08 06:35:21 +01:00
Daniel Czerwonk
02ddbc03ad bump version
Signed-off-by: Daniel Czerwonk <daniel@dan-nrw.de>
2023-02-08 06:34:07 +01:00
Daniel Czerwonk
3539ace96e add TLS
Signed-off-by: Daniel Czerwonk <daniel@dan-nrw.de>
2023-02-08 06:30:52 +01:00
Birger J. Nordølum
301f514d98
docs(readme): grammer & whitespace (#78)
Just some minor cleaning.
2022-11-22 16:57:39 +01:00
dependabot[bot]
8232f48a3f
Bump github.com/stretchr/testify from 1.8.0 to 1.8.1 (#77)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-22 16:57:07 +01:00
dependabot[bot]
e3da677d2e
Bump github.com/prometheus/client_golang from 1.13.0 to 1.14.0 (#80)
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.13.0 to 1.14.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.13.0...v1.14.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-22 16:56:54 +01:00
Daniel Czerwonk
3d95ac568f use go 1.19 2022-09-07 17:09:46 +02:00
Daniel Czerwonk
750c03a0fb use golang 1.19 2022-09-07 17:08:34 +02:00
dependabot[bot]
d740f50b48
Bump github.com/stretchr/testify from 1.7.1 to 1.8.0 (#70)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.1 to 1.8.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.7.1...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 17:07:41 +02:00
dependabot[bot]
92eb38ce4a
Bump github.com/sirupsen/logrus from 1.8.1 to 1.9.0 (#71)
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.8.1 to 1.9.0.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.8.1...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 17:06:46 +02:00
dependabot[bot]
57ca5c5165
Bump github.com/prometheus/client_golang from 1.12.2 to 1.13.0 (#72)
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.12.2 to 1.13.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.12.2...v1.13.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 17:04:06 +02:00
dependabot[bot]
0b648a695a
Bump github.com/stretchr/testify from 1.7.0 to 1.7.1 (#65)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.0 to 1.7.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.7.0...v1.7.1)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-03 13:08:04 +02:00
dependabot[bot]
a0b65528df
Bump github.com/prometheus/client_golang from 1.12.1 to 1.12.2 (#66)
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.12.1 to 1.12.2.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.12.1...v1.12.2)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-03 13:05:24 +02:00
Daniel Czerwonk
1a8e03f272 add test for default_label_strategy.go 2022-02-11 07:59:43 +01:00
Daniel Czerwonk
f7bc5148a4 reuse regex, ensure custom label names are trimmed 2022-02-11 07:19:04 +01:00
Daniel Czerwonk
f23e0d3b3e bump version 2022-02-11 07:06:14 +01:00
dependabot[bot]
6ac083926c
Bump github.com/stretchr/testify from 1.4.0 to 1.7.0 (#59)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.4.0 to 1.7.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.4.0...v1.7.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-11 07:02:41 +01:00
dependabot[bot]
034588ea02
Bump github.com/prometheus/client_golang from 1.12.0 to 1.12.1 (#60)
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.12.0 to 1.12.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.12.0...v1.12.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-11 07:02:31 +01:00
sgrade
ab8d64bd15
Allow regex to extract labels from protocol description (#61)
Co-authored-by: Roman Klyuev <rklyuev@subspace.com>
2022-02-11 07:01:04 +01:00
Daniel Czerwonk
ce4adf7c86 add BFD to feature list 2022-01-27 12:24:21 +01:00
Daniel Czerwonk
f13ef4bd7e
Add support for BFD protocol (#58) 2022-01-27 12:20:22 +01:00
Daniel Czerwonk
df3f06fe77
Merge pull request #57 from czerwonk/dependabot/go_modules/github.com/prometheus/client_golang-1.12.0
Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.0
2022-01-27 07:20:17 +01:00
dependabot[bot]
bccba1285c
Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.11.0 to 1.12.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.11.0...v1.12.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-20 01:24:50 +00:00
Daniel Czerwonk
934b26e64a rename parse func 2022-01-14 12:00:20 +01:00
Daniel Czerwonk
7799d636a4 move ospf test 2022-01-14 11:59:10 +01:00
Daniel Czerwonk
564a7b5b72 trim strings extracted from descriptions (fixes #51) 2022-01-14 11:49:52 +01:00
Daniel Czerwonk
c99e498508 remove bgp states introduced in by #46 since the information can now be extracted by using the up metric with better performance 2022-01-14 11:33:50 +01:00
Daniel Czerwonk
cde3432490 set new metric format as default, add RPKI protocol 2022-01-14 11:27:11 +01:00
Daniel Czerwonk
ae7bb26676 remove unused var 2022-01-14 10:08:46 +01:00
Daniel Czerwonk
4b8417493d BGP state exporter used deprecated log package 2022-01-14 09:29:53 +01:00
Daniel Czerwonk
be8305dd4b use go 1.17 2022-01-13 09:38:38 +01:00
Daniel Czerwonk
11d35e7ce5
Merge pull request #53 from czerwonk/dependabot/go_modules/github.com/sirupsen/logrus-1.8.1
Bump github.com/sirupsen/logrus from 1.6.0 to 1.8.1
2022-01-13 09:35:36 +01:00
Daniel Czerwonk
3f19d943a1
Update main.go
Bump version
2022-01-13 09:35:07 +01:00
Daniel Czerwonk
f0f068ca4c
Merge pull request #46 from ctripcloud/add-bgp-state-metrics
Add bgp state metrics
2022-01-13 09:33:48 +01:00
dependabot[bot]
ec3728ad00
Bump github.com/sirupsen/logrus from 1.6.0 to 1.8.1
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.6.0 to 1.8.1.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.6.0...v1.8.1)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-13 08:31:31 +00:00
Daniel Czerwonk
9d0ce2e117
Merge pull request #50 from micah/add_dependabot
Add dependabot configuration.
2022-01-13 09:31:09 +01:00
Micah Anderson
cecdd96518 Add dependabot configuration.
For more information, see:

https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically
2021-11-20 09:20:25 -05:00
Daniel Czerwonk
0bb1b6cedb
Merge pull request #48 from seoss/basic_babel
Add basic support for the Babel protocol.
2021-09-27 07:11:32 +02:00
Tim Small
d494720cc3 Add basic support for the Babel protocol.
This doesn't add a protocol specific parser, but does allow basic
information about babel imported and exported routes etc. to be exposed.
2021-09-23 13:20:19 +01:00
Daniel Czerwonk
088878a86d dep upgrade 2021-07-22 14:31:28 +02:00
Daniel Czerwonk
c9985a3895 migrated log from deprecated prom package to logrus 2021-07-02 11:44:13 +02:00
zhanghao
b09cde3210 Add bgp state metrics
This patch adds bgp state metrics as follows:
http://XXX:9324/metrics

bird_bgp_state{name="uplink0",proto="BGP",state="Active"} 1
bird_bgp_state{name="uplink1",proto="BGP",state="Idle"} 1
2021-07-02 05:14:30 -04:00
35 changed files with 946 additions and 324 deletions

40
.drone.yml Normal file
View File

@ -0,0 +1,40 @@
---
kind: pipeline
type: docker
name: default
steps:
- name: build
image: golang
environment:
CGO_ENABLED: 0
commands:
- go build
- name: extract version
image: ubuntu:latest
commands:
- grep 'const version string' main.go | tr -d ' "' | cut -d'=' -f2 > .version
- name: upload artifact
image: git.burble.dn42/burble.dn42/drone-gitea-pkg-plugin:latest
settings:
token:
from_secret: TOKEN
version: .version
artifact: bird_exporter
package: bird_exporter
owner: mirrors
---
kind: secret
name: TOKEN
get:
path: burble.dn42/kv/data/drone/git.burble.dn42
name: artifact-token
---
kind: signature
hmac: 757775a4643eedc3d70d60cc6eb009b5704f417245e1f0e66bdfc4e52505bd1a
...

6
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: gomod
directory: /
schedule:
interval: daily

View File

@ -15,7 +15,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.16
go-version: "1.20"
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2

View File

@ -1,17 +1,17 @@
on:
push:
branches:
- master
- main
pull_request:
branches:
- master
- main
name: Test
jobs:
test:
strategy:
matrix:
go-version: [1.16.x]
go-version: ["1.20.x"]
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}
steps:

1
CODEOWNERS Normal file
View File

@ -0,0 +1 @@
* @czerwonk

View File

@ -1,10 +1,13 @@
# bird_exporter
# bird_exporter
[![Build Status](https://ci.burble.dn42/api/badges/mirrors/bird_exporter/status.svg?ref=refs/heads/burble.dn42)](https://ci.burble.dn42/mirrors/bird_exporter)
[![Go Report Card](https://goreportcard.com/badge/github.com/czerwonk/bird_exporter)](https://goreportcard.com/report/github.com/czerwonk/bird_exporter)
Metric exporter for bird routing daemon to use with Prometheus
Metric exporter for bird routing daemon to use with Prometheus.
## Remarks
Since bird_exporter uses the bird unix sockets, bird has to be installed on the same maschine as bird_exporter. Also the user executing bird_exporter must have permission to access the bird socket files.
Since bird_exporter uses the bird unix sockets, bird has to be installed on the same machine as bird_exporter. Also the user executing bird_exporter must have permission to access the bird socket files.
### Bird configuration
To get meaningful uptime information bird has to be configured this way:
@ -13,19 +16,21 @@ timeformat protocol iso long;
```
## Important information for users of bird 2.0+
Version 2.0 of bird routing daemon does support IPv4 and IPv6 in one single daemon now.
For further information see [here](https://gitlab.labs.nic.cz/labs/bird/wikis/transition-notes-to-bird-2).
Since version 1.1 bird_exporter can be used with bird 2.0+ using the `-bird.v2` parameter.
When using this parameter bird_exporter queries the same bird socket for IPv4 and IPv6.
Version 2.0 of bird routing daemon does support IPv4 and IPv6 in one single daemon now.
For further information see [here](https://gitlab.labs.nic.cz/labs/bird/wikis/transition-notes-to-bird-2).
Since version 1.1 bird_exporter can be used with bird 2.0+ using the `-bird.v2` parameter.
When using this parameter bird_exporter queries the same bird socket for IPv4 and IPv6.
In this mode the IP protocol is determined by the channel information and parameters `-bird.ipv4`, `-bird.ipv6` and `-bird.socket6` are ignored.
## Metric formats
In version 1.0 a new metric format was introduced.
In version 1.0 a new metric format was introduced.
To prevent a breaking change the new format is optional and can be enabled by using the ```-format.new``` flag.
The new format handles protocols more generic and allows a better query structure.
Also it adheres more to the metric naming best practices.
In both formats protocol specific metrics are prefixed with the protocol name (e.g. OSPF running metric).
Since verson 1.3 the new metric format is the default.
This is a short example of the different formats:
### old format
@ -43,7 +48,7 @@ bird_ospfv3_running{name="ospf1"} 1
```
### Default Port
In version 0.7.1 the default port changed to 9324 since port 9200 is the default port of elasticsearch. The new port is now registered in the default port allocation list (https://github.com/prometheus/prometheus/wiki/Default-port-allocations)
In version 0.7.1 the default port changed to 9324 since port 9200 is the default port of Elasticsearch. The new port is now registered in the default port allocation list (https://github.com/prometheus/prometheus/wiki/Default-port-allocations)
### Sockets
In version 0.8 communication to bird changed to sockets. The default socket path is ```/var/run/bird.ctl``` (for bird) and ```/var/run/bird6.ctl``` (for bird6). In case you are using different paths in your installation, the socket path can be specified by usind the ```-bird.socket``` (for bird) and ```-bird.socket6``` (for bird6) flag.
@ -68,8 +73,9 @@ https://grafana.com/dashboards/5259
## Features
* BGP session state
* OSPF neighbor/interface count
* imported / exported / filtered prefix counts / route state changes (BGP, OSPF, Kernel, Static, Device, Direct)
* protocol uptimes (BGP, OSPF)
* imported / exported / filtered prefix counts / route state changes (BGP, OSPF, Kernel, Static, Device, Direct, Babel)
* protocol uptimes (BGP, OSPF, BFD)
* BFD session status
## Third Party Components
This software uses components of the following projects

View File

@ -60,6 +60,9 @@ bird_exporter must have read/write permission to access the BIRD Unix sockets.
**-proto.static**
Enables metrics for protocol Static
**-proto.babel**
Enables metrics for protocol Babel
**-version**
Print version information

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,8 @@
apiVersion: v2
name: bird-exporter
description: Exporter for bird-exporter
type: application
version: 0.1.0
appVersion: "1.4.1"
sources:
- https://github.com/czerwonk/bird-exporter

View File

@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "bird-exporter.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "bird-exporter.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "bird-exporter.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "bird-exporter.labels" -}}
helm.sh/chart: {{ include "bird-exporter.chart" . }}
{{ include "bird-exporter.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "bird-exporter.selectorLabels" -}}
app.kubernetes.io/name: {{ include "bird-exporter.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "bird-exporter.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "bird-exporter.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ include "bird-exporter.fullname" . }}
labels:
{{- include "bird-exporter.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
{{- include "bird-exporter.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "bird-exporter.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
args:
{{- toYaml .Values.exporter.args | nindent 12 }}
ports:
- name: http-metrics
containerPort: 9324
protocol: TCP
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- mountPath: /var/run/bird
name: bird-socket
readOnly: true
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: bird-socket
hostPath:
path: {{ .Values.exporter.birdSocketPath }}

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "bird-exporter.fullname" . }}-metrics
labels:
{{- include "bird-exporter.labels" . | nindent 4 }}
spec:
type: ClusterIP
ports:
- targetPort: http-metrics
protocol: TCP
port: 9324
name: http-metrics
selector:
{{- include "bird-exporter.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,24 @@
{{- if .Values.serviceMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ include "bird-exporter.fullname" . }}
spec:
jobLabel: {{ .Values.serviceMonitor.jobLabel | quote }}
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
{{- include "bird-exporter.labels" . | nindent 6 }}
endpoints:
- port: http-metrics
{{- if .Values.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{- toYaml .Values.serviceMonitor.metricRelabelings | nindent 6 }}
{{- end }}
{{- if .Values.serviceMonitor.relabelings }}
relabelings:
{{- toYaml .Values.serviceMonitor.relabelings | nindent 6 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,59 @@
image:
repository: czerwonk/bird_exporter
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
exporter:
args:
- "-format.new=true"
- "-bird.socket=/var/run/bird/bird.ctl"
- "-bird.socket6=/var/run/bird/bird6.ctl"
# Host path of where the bird socket is.
# This path will then be mounted into /var/run/bird in the container.
birdSocketPath: "/var/run/bird"
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceMonitor:
enabled: false
jobLabel: "app.kubernetes.io/name"
metricRelabelings: []
# - action: keep
# regex: 'bird_.+'
# sourceLabels: [__name__]
relabelings: []
# - action: replace
# sourceLabels: [__meta_kubernetes_pod_node_name]
# targetLabel: nodename
podAnnotations: {}
podSecurityContext:
fsGroup: 2000
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
resources: {}
# limits:
# cpu: 100m
# memory: 32Mi
# requests:
# cpu: 100m
# memory: 32Mi
nodeSelector: {}
tolerations: []
affinity: {}

View File

@ -41,14 +41,25 @@ func (c *BirdClient) GetProtocols() ([]*protocol.Protocol, error) {
}
// GetOSPFAreas retrieves OSPF specific information from bird
func (c *BirdClient) GetOSPFAreas(protocol *protocol.Protocol) ([]*protocol.OspfArea, error) {
func (c *BirdClient) GetOSPFAreas(protocol *protocol.Protocol) ([]*protocol.OSPFArea, error) {
sock := c.socketFor(protocol.IPVersion)
b, err := birdsocket.Query(sock, fmt.Sprintf("show ospf %s", protocol.Name))
if err != nil {
return nil, err
}
return parser.ParseOspf(b), nil
return parser.ParseOSPF(b), nil
}
// GetBFDSessions retrieves BFD specific information from bird
func (c *BirdClient) GetBFDSessions(protocol *protocol.Protocol) ([]*protocol.BFDSession, error) {
sock := c.socketFor(protocol.IPVersion)
b, err := birdsocket.Query(sock, fmt.Sprintf("show bfd sessions %s", protocol.Name))
if err != nil {
return nil, err
}
return parser.ParseBFDSessions(protocol.Name, b), nil
}
func (c *BirdClient) protocolsFromBird(ipVersions []string) ([]*protocol.Protocol, error) {

View File

@ -9,5 +9,8 @@ type Client interface {
GetProtocols() ([]*protocol.Protocol, error)
// GetOSPFAreas retrieves OSPF specific information from bird
GetOSPFAreas(protocol *protocol.Protocol) ([]*protocol.OspfArea, error)
GetOSPFAreas(protocol *protocol.Protocol) ([]*protocol.OSPFArea, error)
// GetBFDSessions retrieves BFD specific information from bird
GetBFDSessions(protocol *protocol.Protocol) ([]*protocol.BFDSession, error)
}

26
go.mod
View File

@ -1,10 +1,28 @@
module github.com/czerwonk/bird_exporter
go 1.16
go 1.20
require (
github.com/czerwonk/bird_socket v0.0.0-20170701072538-fe8194eb5598
github.com/czerwonk/bird_socket v0.0.0-20190111125930-6c39d61f8853
github.com/czerwonk/testutils v0.0.0-20170526233935-dd9dabe360d4
github.com/prometheus/client_golang v1.2.1
github.com/prometheus/common v0.7.0
github.com/prometheus/client_golang v1.15.1
github.com/sirupsen/logrus v1.9.2
github.com/stretchr/testify v1.8.3
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
golang.org/x/sys v0.6.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

120
go.sum
View File

@ -1,90 +1,56 @@
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
github.com/czerwonk/bird_socket v0.0.0-20170701072538-fe8194eb5598 h1:PoKf7YEmuDOGzXD52jaJhZeOuwRrgv9FbZF8yfyoF7A=
github.com/czerwonk/bird_socket v0.0.0-20170701072538-fe8194eb5598/go.mod h1:SQ2xpIC3W7ygMomUYEsxXBeun7RML/HCNXj24fbz+XI=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/czerwonk/bird_socket v0.0.0-20190111125930-6c39d61f8853 h1:XSnDYYRExBUBKn2K2fWE5Z4rYPkdsjBwN7SvU5CACzM=
github.com/czerwonk/bird_socket v0.0.0-20190111125930-6c39d61f8853/go.mod h1:SQ2xpIC3W7ygMomUYEsxXBeun7RML/HCNXj24fbz+XI=
github.com/czerwonk/testutils v0.0.0-20170526233935-dd9dabe360d4 h1:1QQjuJMb2LVM/sk4HS7svnGjM8um7EWk8lD5BwZ2X28=
github.com/czerwonk/testutils v0.0.0-20170526233935-dd9dabe360d4/go.mod h1:Xibh2UDW2TbNjbi8QON4p0QxiYK/RM5USagAW7J3jUM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=
github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

71
main.go
View File

@ -9,28 +9,35 @@ import (
"github.com/czerwonk/bird_exporter/protocol"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/log"
log "github.com/sirupsen/logrus"
)
const version string = "1.2.5"
const version string = "1.4.2"
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")
birdV2 = flag.Bool("bird.v2", false, "Bird major version >= 2.0 (multi channel protocols)")
newFormat = flag.Bool("format.new", false, "New metric format (more convenient / generic)")
enableBgp = flag.Bool("proto.bgp", true, "Enables metrics for protocol BGP")
enableOspf = flag.Bool("proto.ospf", true, "Enables metrics for protocol OSPF")
enableKernel = flag.Bool("proto.kernel", true, "Enables metrics for protocol Kernel")
enableStatic = flag.Bool("proto.static", true, "Enables metrics for protocol Static")
enableDirect = flag.Bool("proto.direct", true, "Enables metrics for protocol Direct")
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")
birdV2 = flag.Bool("bird.v2", false, "Bird major version >= 2.0 (multi channel protocols)")
tlsEnabled = flag.Bool("tls.enabled", false, "Enables TLS")
tlsCertChainPath = flag.String("tls.cert-file", "", "Path to TLS cert file")
tlsKeyPath = flag.String("tls.key-file", "", "Path to TLS key file")
newFormat = flag.Bool("format.new", true, "New metric format (more convenient / generic)")
enableBGP = flag.Bool("proto.bgp", true, "Enables metrics for protocol BGP")
enableOSPF = flag.Bool("proto.ospf", true, "Enables metrics for protocol OSPF")
enableKernel = flag.Bool("proto.kernel", true, "Enables metrics for protocol Kernel")
enableStatic = flag.Bool("proto.static", true, "Enables metrics for protocol Static")
enableDirect = flag.Bool("proto.direct", true, "Enables metrics for protocol Direct")
enableBabel = flag.Bool("proto.babel", true, "Enables metrics for protocol Babel")
enableRPKI = flag.Bool("proto.rpki", true, "Enables metrics for protocol RPKI")
enableBFD = flag.Bool("proto.bfd", true, "Enables metrics for protocol BFD")
// 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)")
descriptionLabels = flag.Bool("format.description-labels", false, "Add labels from protocol descriptions.")
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)")
descriptionLabels = flag.Bool("format.description-labels", false, "Add labels from protocol descriptions.")
descriptionLabelsRegex = flag.String("format.description-labels-regex", "(\\w+)=(\\w+)", "Regex to extract labels from protocol description")
)
func init() {
@ -60,7 +67,7 @@ func printVersion() {
}
func startServer() {
log.Infof("Starting bird exporter (Version: %s)\n", version)
log.Infof("Starting bird exporter (Version: %s)", version)
if !*newFormat {
log.Info("INFO: You are using the old metric format. Please consider using the new (more convenient one) by setting -format.new=true.")
@ -79,7 +86,12 @@ func startServer() {
})
http.HandleFunc(*metricsPath, handleMetricsRequest)
log.Infof("Listening for %s on %s\n", *metricsPath, *listenAddress)
log.Infof("Listening for %s on %s (TLS: %v)", *metricsPath, *listenAddress, *tlsEnabled)
if *tlsEnabled {
log.Fatal(http.ListenAndServeTLS(*listenAddress, *tlsCertChainPath, *tlsKeyPath, nil))
return
}
log.Fatal(http.ListenAndServe(*listenAddress, nil))
}
@ -89,18 +101,20 @@ func handleMetricsRequest(w http.ResponseWriter, r *http.Request) {
c := NewMetricCollector(*newFormat, p, *descriptionLabels)
reg.MustRegister(c)
l := log.New()
l.Level = log.ErrorLevel
promhttp.HandlerFor(reg, promhttp.HandlerOpts{
ErrorLog: log.NewErrorLogger(),
ErrorLog: l,
ErrorHandling: promhttp.ContinueOnError}).ServeHTTP(w, r)
}
func enabledProtocols() int {
res := 0
func enabledProtocols() protocol.Proto {
res := protocol.Proto(0)
if *enableBgp {
if *enableBGP {
res |= protocol.BGP
}
if *enableOspf {
if *enableOSPF {
res |= protocol.OSPF
}
if *enableKernel {
@ -112,6 +126,15 @@ func enabledProtocols() int {
if *enableDirect {
res |= protocol.Direct
}
if *enableBabel {
res |= protocol.Babel
}
if *enableRPKI {
res |= protocol.RPKI
}
if *enableBFD {
res |= protocol.BFD
}
return res
}

View File

@ -5,19 +5,19 @@ import (
"github.com/czerwonk/bird_exporter/metrics"
"github.com/czerwonk/bird_exporter/protocol"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
log "github.com/sirupsen/logrus"
)
type MetricCollector struct {
exporters map[int][]metrics.MetricExporter
exporters map[protocol.Proto][]metrics.MetricExporter
client *client.BirdClient
enabledProtocols int
enabledProtocols protocol.Proto
newFormat bool
}
func NewMetricCollector(newFormat bool, enabledProtocols int, descriptionLabels bool) *MetricCollector {
func NewMetricCollector(newFormat bool, enabledProtocols protocol.Proto, descriptionLabels bool) *MetricCollector {
c := getClient()
var e map[int][]metrics.MetricExporter
var e map[protocol.Proto][]metrics.MetricExporter
if newFormat {
e = exportersForDefault(c, descriptionLabels)
@ -45,32 +45,48 @@ func getClient() *client.BirdClient {
return &client.BirdClient{Options: o}
}
func exportersForLegacy(c *client.BirdClient) map[int][]metrics.MetricExporter {
func exportersForLegacy(c *client.BirdClient) map[protocol.Proto][]metrics.MetricExporter {
l := metrics.NewLegacyLabelStrategy()
return map[int][]metrics.MetricExporter{
return map[protocol.Proto][]metrics.MetricExporter{
protocol.BGP: {metrics.NewLegacyMetricExporter("bgp4_session", "bgp6_session", l)},
protocol.Direct: {metrics.NewLegacyMetricExporter("direct4", "direct6", l)},
protocol.Kernel: {metrics.NewLegacyMetricExporter("kernel4", "kernel6", l)},
protocol.OSPF: {metrics.NewLegacyMetricExporter("ospf", "ospfv3", l), metrics.NewOSPFExporter("", c)},
protocol.Static: {metrics.NewLegacyMetricExporter("static4", "static6", l)},
protocol.Babel: {metrics.NewLegacyMetricExporter("babel4", "babel6", l)},
protocol.RPKI: {metrics.NewLegacyMetricExporter("rpki4", "rpki6", l)},
protocol.BFD: {metrics.NewBFDExporter(c)},
}
}
func exportersForDefault(c *client.BirdClient, descriptionLabels bool) map[int][]metrics.MetricExporter {
l := metrics.NewDefaultLabelStrategy(descriptionLabels)
func exportersForDefault(c *client.BirdClient, descriptionLabels bool) map[protocol.Proto][]metrics.MetricExporter {
l := metrics.NewDefaultLabelStrategy(descriptionLabels, *descriptionLabelsRegex)
e := metrics.NewGenericProtocolMetricExporter("bird_protocol", true, l)
return map[int][]metrics.MetricExporter{
return map[protocol.Proto][]metrics.MetricExporter{
protocol.BGP: {e},
protocol.Direct: {e},
protocol.Kernel: {e},
protocol.OSPF: {e, metrics.NewOSPFExporter("bird_", c)},
protocol.Static: {e},
protocol.Babel: {e},
protocol.RPKI: {e},
protocol.BFD: {metrics.NewBFDExporter(c)},
}
}
var socketQueryDesc = prometheus.NewDesc(
"bird_socket_query_success",
"Result of querying bird socket: 0 = failed, 1 = suceeded",
nil,
nil,
)
func (m *MetricCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- socketQueryDesc
for _, v := range m.exporters {
for _, e := range v {
e.Describe(ch)
@ -79,7 +95,15 @@ func (m *MetricCollector) Describe(ch chan<- *prometheus.Desc) {
}
func (m *MetricCollector) Collect(ch chan<- prometheus.Metric) {
protocols, err := m.client.GetProtocols()
var queryResult float64 = 1
if err != nil {
queryResult = 0
}
ch <- prometheus.MustNewConstMetric(socketQueryDesc, prometheus.GaugeValue, queryResult)
if err != nil {
log.Errorln(err)
return

73
metrics/bfd_exporter.go Normal file
View File

@ -0,0 +1,73 @@
package metrics
import (
"github.com/czerwonk/bird_exporter/client"
"github.com/czerwonk/bird_exporter/protocol"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
)
var (
bfdUpDesc *prometheus.Desc
bfdUptimeDesc *prometheus.Desc
bfdIntervalDesc *prometheus.Desc
bfdTimoutDesc *prometheus.Desc
)
func init() {
l := []string{"name", "ip", "interface"}
prefix := "bird_bfd_session_"
bfdUpDesc = prometheus.NewDesc(prefix+"up", "Session is up", l, nil)
bfdUptimeDesc = prometheus.NewDesc(prefix+"uptime_seconds", "Session uptime in seconds", l, nil)
bfdIntervalDesc = prometheus.NewDesc(prefix+"interval_seconds", "Session uptime in seconds", l, nil)
bfdTimoutDesc = prometheus.NewDesc(prefix+"timeout_seconds", "Session timeout in seconds", l, nil)
}
type bfdMetricExporter struct {
client client.Client
}
// NewBFDExporter creates a new MetricExporter for BFD metrics
func NewBFDExporter(client client.Client) MetricExporter {
return &bfdMetricExporter{client: client}
}
func (m *bfdMetricExporter) Describe(ch chan<- *prometheus.Desc) {
ch <- bfdUpDesc
ch <- bfdUptimeDesc
ch <- bfdIntervalDesc
ch <- bfdTimoutDesc
}
func (m *bfdMetricExporter) Export(p *protocol.Protocol, ch chan<- prometheus.Metric, newFormat bool) {
if p.Proto != protocol.BFD {
return
}
sessions, err := m.client.GetBFDSessions(p)
if err != nil {
log.Errorln(err)
return
}
for _, s := range sessions {
m.exportSession(s, p.Name, ch)
}
}
func (m *bfdMetricExporter) exportSession(s *protocol.BFDSession, protocolName string, ch chan<- prometheus.Metric) {
l := []string{protocolName, s.IP, s.Interface}
var up float64
var uptime float64
if s.Up {
up = 1
uptime = float64(s.Since)
}
ch <- prometheus.MustNewConstMetric(bfdUpDesc, prometheus.GaugeValue, up, l...)
ch <- prometheus.MustNewConstMetric(bfdUptimeDesc, prometheus.GaugeValue, uptime, l...)
ch <- prometheus.MustNewConstMetric(bfdIntervalDesc, prometheus.GaugeValue, s.Interval, l...)
ch <- prometheus.MustNewConstMetric(bfdTimoutDesc, prometheus.GaugeValue, s.Timeout, l...)
}

View File

@ -1,6 +1,7 @@
package metrics
import (
"regexp"
"strings"
"github.com/czerwonk/bird_exporter/protocol"
@ -8,12 +9,14 @@ import (
// DefaultLabelStrategy defines the labels to add to an metric and its data retrieval method
type DefaultLabelStrategy struct {
descriptionLabels bool
descriptionLabels bool
descriptionLabelsRegex *regexp.Regexp
}
func NewDefaultLabelStrategy(descriptionLabels bool) *DefaultLabelStrategy {
func NewDefaultLabelStrategy(descriptionLabels bool, descriptionLabelsRegex string) *DefaultLabelStrategy {
return &DefaultLabelStrategy{
descriptionLabels: descriptionLabels,
descriptionLabels: descriptionLabels,
descriptionLabelsRegex: regexp.MustCompile(descriptionLabelsRegex),
}
}
@ -21,7 +24,7 @@ func NewDefaultLabelStrategy(descriptionLabels bool) *DefaultLabelStrategy {
func (d *DefaultLabelStrategy) LabelNames(p *protocol.Protocol) []string {
res := []string{"name", "proto", "ip_version", "import_filter", "export_filter"}
if d.descriptionLabels && p.Description != "" {
res = append(res, labelKeysFromDescription(p.Description)...)
res = append(res, labelKeysFromDescription(p.Description, d)...)
}
return res
@ -31,36 +34,32 @@ func (d *DefaultLabelStrategy) LabelNames(p *protocol.Protocol) []string {
func (d *DefaultLabelStrategy) LabelValues(p *protocol.Protocol) []string {
res := []string{p.Name, protoString(p), p.IPVersion, p.ImportFilter, p.ExportFilter}
if d.descriptionLabels && p.Description != "" {
res = append(res, labelValuesFromDescription(p.Description)...)
res = append(res, labelValuesFromDescription(p.Description, d)...)
}
return res
}
func labelKeysFromDescription(desc string) (res []string) {
for _, x := range strings.Split(desc, ",") {
tmp := strings.Split(x, "=")
if len(tmp) != 2 {
continue
}
func labelKeysFromDescription(desc string, d *DefaultLabelStrategy) []string {
res := []string{}
res = append(res, tmp[0])
matches := d.descriptionLabelsRegex.FindAllStringSubmatch(desc, -1)
for _, submatch := range matches {
res = append(res, strings.TrimSpace(submatch[1]))
}
return
return res
}
func labelValuesFromDescription(desc string) (res []string) {
for _, x := range strings.Split(desc, ",") {
tmp := strings.Split(x, "=")
if len(tmp) != 2 {
continue
}
func labelValuesFromDescription(desc string, d *DefaultLabelStrategy) []string {
res := []string{}
res = append(res, tmp[1])
matches := d.descriptionLabelsRegex.FindAllStringSubmatch(desc, -1)
for _, submatch := range matches {
res = append(res, strings.TrimSpace(submatch[2]))
}
return
return res
}
func protoString(p *protocol.Protocol) string {
@ -78,6 +77,12 @@ func protoString(p *protocol.Protocol) string {
return "Kernel"
case protocol.Direct:
return "Direct"
case protocol.Babel:
return "Babel"
case protocol.RPKI:
return "RPKI"
case protocol.BFD:
return "BFD"
}
return ""

View File

@ -0,0 +1,38 @@
package metrics
import (
"testing"
"github.com/czerwonk/bird_exporter/protocol"
"github.com/stretchr/testify/assert"
)
func TestLabelNames(t *testing.T) {
s := NewDefaultLabelStrategy(true, `(\w+\s*)=(\s*\w+)`)
labels := s.LabelNames(&protocol.Protocol{
Name: "test",
Description: " foo = bar x: y",
ImportFilter: "in",
ExportFilter: "out",
IPVersion: "6",
Proto: protocol.BGP,
})
expected := []string{"name", "proto", "ip_version", "import_filter", "export_filter", "foo"}
assert.Equal(t, expected, labels)
}
func TestLabelValues(t *testing.T) {
s := NewDefaultLabelStrategy(true, `(\w+\s*)=(\s*\w+)`)
values := s.LabelValues(&protocol.Protocol{
Name: "test",
Description: " foo = bar x: y",
ImportFilter: "in",
ExportFilter: "out",
IPVersion: "6",
Proto: protocol.BGP,
})
expected := []string{"test", "BGP", "6", "in", "out", "bar"}
assert.Equal(t, expected, values)
}

View File

@ -32,7 +32,7 @@ func (m *GenericProtocolMetricExporter) Export(p *protocol.Protocol, ch chan<- p
var filterCountDesc *prometheus.Desc
var preferredCountDesc *prometheus.Desc
upDesc := prometheus.NewDesc(m.prefix+"_up", "Protocol is up", labels, nil)
upDesc := prometheus.NewDesc(m.prefix+"_up", "Protocol is up", append(labels, "state"), nil)
if newNaming {
importCountDesc = prometheus.NewDesc(m.prefix+"_prefix_import_count", "Number of imported routes", labels, nil)
@ -69,7 +69,7 @@ func (m *GenericProtocolMetricExporter) Export(p *protocol.Protocol, ch chan<- p
withdrawsExportReceiveCountDesc := prometheus.NewDesc(m.prefix+"_changes_withdraw_export_receive_count", "Number of outgoing withdraws", labels, nil)
l := m.labelStrategy.LabelValues(p)
ch <- prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, float64(p.Up), l...)
ch <- prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, float64(p.Up), append(l, p.State)...)
ch <- prometheus.MustNewConstMetric(importCountDesc, prometheus.GaugeValue, float64(p.Imported), l...)
ch <- prometheus.MustNewConstMetric(exportCountDesc, prometheus.GaugeValue, float64(p.Exported), l...)
ch <- prometheus.MustNewConstMetric(filterCountDesc, prometheus.GaugeValue, float64(p.Filtered), l...)

View File

@ -4,7 +4,7 @@ import (
"github.com/czerwonk/bird_exporter/client"
"github.com/czerwonk/bird_exporter/protocol"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
log "github.com/sirupsen/logrus"
)
type ospfDesc struct {
@ -57,7 +57,13 @@ func (m *ospfMetricExporter) describe(ipVersion string, ch chan<- *prometheus.De
func (m *ospfMetricExporter) Export(p *protocol.Protocol, ch chan<- prometheus.Metric, newFormat bool) {
d := m.descriptions[p.IPVersion]
ch <- prometheus.MustNewConstMetric(d.runningDesc, prometheus.GaugeValue, p.Attributes["running"], p.Name)
var running float64
if p.State == "Running" {
running = 1
}
ch <- prometheus.MustNewConstMetric(d.runningDesc, prometheus.GaugeValue, running, p.Name)
areas, err := m.client.GetOSPFAreas(p)
if err != nil {

63
parser/bfd.go Normal file
View File

@ -0,0 +1,63 @@
package parser
import (
"bufio"
"bytes"
"regexp"
"strings"
"github.com/czerwonk/bird_exporter/protocol"
)
var (
bfdSessionRegex *regexp.Regexp
)
func init() {
bfdSessionRegex = regexp.MustCompile(`^([^\s]+)\s+([^\s]+)\s+(Up|Down|Init)\s+(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}|[^\s]+)\s+([0-9\.]+)\s+([0-9\.]+)$`)
}
type bfdContext struct {
line string
sessions []*protocol.BFDSession
protocol string
}
func ParseBFDSessions(protocolName string, data []byte) []*protocol.BFDSession {
reader := bytes.NewReader(data)
scanner := bufio.NewScanner(reader)
c := &bfdContext{
sessions: make([]*protocol.BFDSession, 0),
protocol: protocolName,
}
for scanner.Scan() {
c.line = strings.TrimSpace(scanner.Text())
parseBFDSessionLine(c)
}
return c.sessions
}
func parseBFDSessionLine(c *bfdContext) {
m := bfdSessionRegex.FindStringSubmatch(c.line)
if m == nil {
return
}
sess := protocol.BFDSession{
ProtocolName: c.protocol,
IP: m[1],
Interface: m[2],
Since: parseUptime(m[4]),
Interval: parseFloat(m[5]),
Timeout: parseFloat(m[6]),
}
if m[3] == "Up" {
sess.Up = true
}
c.sessions = append(c.sessions, &sess)
}

55
parser/bfd_test.go Normal file
View File

@ -0,0 +1,55 @@
package parser
import (
"testing"
"time"
"github.com/czerwonk/bird_exporter/protocol"
"github.com/stretchr/testify/assert"
)
func TestParseBFDSessions(t *testing.T) {
overrideNowFunc(func() time.Time {
return time.Date(2022, 1, 27, 10, 0, 0, 0, time.Local)
})
data := `BIRD 2.0.7 ready.
bfd1:
IP address Interface State Since Interval Timeout
192.168.64.9 enp0s2 Up 2022-01-27 09:00:00 0.100 1.000
192.168.64.10 enp0s2 Down 2022-01-27 08:00:00 0.300 0.000
192.168.64.12 enp0s2 Init 2022-01-27 08:00:00 0.300 5.000`
s := ParseBFDSessions("bfd1", []byte(data))
assert.Equal(t, 3, len(s), "session count")
s1 := protocol.BFDSession{
ProtocolName: "bfd1",
IP: "192.168.64.9",
Interface: "enp0s2",
Up: true,
Since: 3600,
Interval: 0.1,
Timeout: 1,
}
s2 := protocol.BFDSession{
ProtocolName: "bfd1",
IP: "192.168.64.10",
Interface: "enp0s2",
Up: false,
Since: 7200,
Interval: 0.3,
Timeout: 0,
}
s3 := protocol.BFDSession{
ProtocolName: "bfd1",
IP: "192.168.64.12",
Interface: "enp0s2",
Up: false,
Since: 7200,
Interval: 0.3,
Timeout: 5,
}
assert.Equal(t, []*protocol.BFDSession{&s1, &s2, &s3}, s, "sessions")
}

82
parser/helper.go Normal file
View File

@ -0,0 +1,82 @@
package parser
import (
"fmt"
"strconv"
"time"
log "github.com/sirupsen/logrus"
)
var (
nowFunc func() time.Time
)
func init() {
nowFunc = func() time.Time {
return time.Now()
}
}
func overrideNowFunc(f func() time.Time) {
nowFunc = f
}
func currentTime() time.Time {
return nowFunc()
}
func parseInt(value string) int64 {
i, err := strconv.ParseInt(value, 10, 64)
if err != nil {
log.Errorln(err)
return 0
}
return i
}
func parseFloat(value string) float64 {
i, err := strconv.ParseFloat(value, 64)
if err != nil {
log.Errorln(err)
return 0
}
return i
}
func parseUptimeForIso(s string) int {
start, err := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local)
if err != nil {
log.Errorln(err)
return 0
}
return int(currentTime().Sub(start).Seconds())
}
func parseUptimeForDuration(duration []string) int {
h := parseInt(duration[2])
m := parseInt(duration[3])
s := parseInt(duration[4])
str := fmt.Sprintf("%dh%dm%ds", h, m, s)
d, err := time.ParseDuration(str)
if err != nil {
log.Errorln(err)
return 0
}
return int(d.Seconds())
}
func parseUptimeForTimestamp(timestamp string) int {
since := parseInt(timestamp)
s := time.Unix(since, 0)
d := currentTime().Sub(s)
return int(d.Seconds())
}

View File

@ -17,8 +17,8 @@ type ospfRegex struct {
type ospfContext struct {
line string
areas []*protocol.OspfArea
current *protocol.OspfArea
areas []*protocol.OSPFArea
current *protocol.OSPFArea
}
func init() {
@ -30,12 +30,12 @@ func init() {
var ospf *ospfRegex
func ParseOspf(data []byte) []*protocol.OspfArea {
func ParseOSPF(data []byte) []*protocol.OSPFArea {
reader := bytes.NewReader(data)
scanner := bufio.NewScanner(reader)
c := &ospfContext{
areas: make([]*protocol.OspfArea, 0),
areas: make([]*protocol.OSPFArea, 0),
}
for scanner.Scan() {
@ -53,7 +53,7 @@ func parseLineForOspfArea(c *ospfContext) {
return
}
a := &protocol.OspfArea{Name: m[1]}
a := &protocol.OSPFArea{Name: m[1]}
c.current = a
c.areas = append(c.areas, a)
}

44
parser/ospf_test.go Normal file
View File

@ -0,0 +1,44 @@
package parser
import (
"testing"
"github.com/czerwonk/testutils/assert"
)
func TestOSPFArea(t *testing.T) {
data := "ospf1:\n" +
"RFC1583 compatibility: disabled\n" +
"Stub router: No\n" +
"RT scheduler tick: 1\n" +
"Number of areas: 2\n" +
"Number of LSAs in DB: 33\n" +
" Area: 0.0.0.0 (0) [BACKBONE]\n" +
" Stub: No\n" +
" NSSA: No\n" +
" Transit: No\n" +
" Number of interfaces: 3\n" +
" Number of neighbors: 2\n" +
" Number of adjacent neighbors: 1\n" +
" Area: 0.0.0.1 (1)\n" +
" Stub: No\n" +
" NSSA: No\n" +
" Transit: No\n" +
" Number of interfaces: 4\n" +
" Number of neighbors: 6\n" +
" Number of adjacent neighbors: 5\n"
a := ParseOSPF([]byte(data))
assert.IntEqual("areas", 2, len(a), t)
a1 := a[0]
assert.StringEqual("Area1 Name", "0", a1.Name, t)
assert.Int64Equal("Area1 InterfaceCount", 3, a1.InterfaceCount, t)
assert.Int64Equal("Area1 NeighborCount", 2, a1.NeighborCount, t)
assert.Int64Equal("Area1 NeighborAdjacentCount", 1, a1.NeighborAdjacentCount, t)
a2 := a[1]
assert.StringEqual("Area2 Name", "1", a2.Name, t)
assert.Int64Equal("Area2 InterfaceCount", 4, a2.InterfaceCount, t)
assert.Int64Equal("Area2 NeighborCount", 6, a2.NeighborCount, t)
assert.Int64Equal("Area2 NeighborAdjacentCount", 5, a2.NeighborAdjacentCount, t)
}

View File

@ -3,14 +3,11 @@ package parser
import (
"bufio"
"bytes"
"fmt"
"regexp"
"strconv"
"strings"
"time"
"github.com/czerwonk/bird_exporter/protocol"
"github.com/prometheus/common/log"
)
var (
@ -93,8 +90,7 @@ func parseLineForProtocol(c *context) {
c.current = protocol.NewProtocol(match[1], proto, c.ipVersion, ut)
c.current.Up = parseState(match[4])
fillAttributes(c.current, match)
c.current.State = match[6]
c.protocols = append(c.protocols, c.current)
c.handled = true
@ -114,7 +110,7 @@ func parseLineForDescription(c *context) {
c.current.Description = strings.Join(match[1:], " ")
}
func parseProto(val string) int {
func parseProto(val string) protocol.Proto {
switch val {
case "BGP":
return protocol.BGP
@ -126,6 +122,12 @@ func parseProto(val string) int {
return protocol.Kernel
case "Static":
return protocol.Static
case "Babel":
return protocol.Babel
case "RPKI":
return protocol.RPKI
case "BFD":
return protocol.BFD
}
return protocol.PROTO_UNKNOWN
@ -157,39 +159,6 @@ func parseUptime(value string) int {
return parseUptimeForIso(value)
}
func parseUptimeForIso(s string) int {
start, err := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local)
if err != nil {
log.Errorln(err)
return 0
}
return int(time.Since(start).Seconds())
}
func parseUptimeForDuration(duration []string) int {
h := parseInt(duration[2])
m := parseInt(duration[3])
s := parseInt(duration[4])
str := fmt.Sprintf("%dh%dm%ds", h, m, s)
d, err := time.ParseDuration(str)
if err != nil {
log.Errorln(err)
return 0
}
return int(d.Seconds())
}
func parseUptimeForTimestamp(timestamp string) int {
since := parseInt(timestamp)
s := time.Unix(since, 0)
d := time.Since(s)
return int(d.Seconds())
}
func parseLineForChannel(c *context) {
if c.ipVersion != "" || c.current == nil {
return
@ -302,28 +271,3 @@ func parseLineForFilterName(c *context) {
c.handled = true
}
func parseInt(value string) int64 {
i, err := strconv.ParseInt(value, 10, 64)
if err != nil {
log.Errorln(err)
return 0
}
return i
}
func fillAttributes(p *protocol.Protocol, m []string) {
if p.Proto == protocol.OSPF {
p.Attributes["running"] = float64(parseOspfRunning(m[6]))
}
}
func parseOspfRunning(state string) int {
if state == "Running" {
return 1
}
return 0
}

View File

@ -9,22 +9,23 @@ import (
)
func TestEstablishedBgpOldTimeFormat(t *testing.T) {
overrideNowFunc(func() time.Time {
return time.Date(2018, 1, 1, 2, 0, 0, 0, time.UTC)
})
data := "foo BGP master up 1514768400 Established\ntest\nbar\n Routes: 12 imported, 1 filtered, 34 exported, 100 preferred\nxxx"
s := time.Date(2018, time.January, 1, 1, 0, 0, 0, time.UTC)
min := int(time.Since(s).Seconds())
p := ParseProtocols([]byte(data), "4")
max := int(time.Since(s).Seconds())
x := p[0]
assert.StringEqual("name", "foo", x.Name, t)
assert.IntEqual("proto", protocol.BGP, x.Proto, t)
assert.IntEqual("proto", int(protocol.BGP), int(x.Proto), t)
assert.IntEqual("established", 1, x.Up, t)
assert.Int64Equal("imported", 12, x.Imported, t)
assert.Int64Equal("exported", 34, x.Exported, t)
assert.Int64Equal("filtered", 1, x.Filtered, t)
assert.Int64Equal("preferred", 100, x.Preferred, t)
assert.StringEqual("ipVersion", "4", x.IPVersion, t)
assert.That("uptime", "uptime is feasable", func() bool { return x.Uptime >= min && max <= x.Uptime }, t)
assert.Int64Equal("uptime", 3600, int64(x.Uptime), t)
}
func TestEstablishedBgpCurrentTimeFormat(t *testing.T) {
@ -34,7 +35,7 @@ func TestEstablishedBgpCurrentTimeFormat(t *testing.T) {
x := p[0]
assert.StringEqual("name", "foo", x.Name, t)
assert.IntEqual("proto", protocol.BGP, x.Proto, t)
assert.IntEqual("proto", int(protocol.BGP), int(x.Proto), t)
assert.IntEqual("established", 1, x.Up, t)
assert.Int64Equal("imported", 12, x.Imported, t)
assert.Int64Equal("exported", 34, x.Exported, t)
@ -45,27 +46,28 @@ func TestEstablishedBgpCurrentTimeFormat(t *testing.T) {
}
func TestEstablishedBgpIsoLongTimeFormat(t *testing.T) {
overrideNowFunc(func() time.Time {
return time.Date(2018, 1, 1, 2, 0, 0, 0, time.Local)
})
data := "foo BGP master up 2018-01-01 01:00:00 Established\ntest\nbar\n Routes: 12 imported, 1 filtered, 34 exported, 100 preferred\nxxx"
s := time.Date(2018, time.January, 1, 1, 0, 0, 0, time.UTC)
min := int(time.Since(s).Seconds())
p := ParseProtocols([]byte(data), "4")
max := int(time.Since(s).Seconds())
assert.IntEqual("protocols", 1, len(p), t)
x := p[0]
assert.StringEqual("name", "foo", x.Name, t)
assert.IntEqual("proto", protocol.BGP, x.Proto, t)
assert.IntEqual("proto", int(protocol.BGP), int(x.Proto), t)
assert.IntEqual("established", 1, x.Up, t)
assert.Int64Equal("imported", 12, x.Imported, t)
assert.Int64Equal("exported", 34, x.Exported, t)
assert.Int64Equal("filtered", 1, x.Filtered, t)
assert.Int64Equal("preferred", 100, x.Preferred, t)
assert.StringEqual("ipVersion", "4", x.IPVersion, t)
assert.That("uptime", "uptime is feasable", func() bool { return x.Uptime >= min && max <= x.Uptime }, t)
assert.Int64Equal("uptime", 3600, int64(x.Uptime), t)
}
func TestIpv6Bgp(t *testing.T) {
func TestIpv6BGP(t *testing.T) {
data := "foo BGP master up 00:01:00 Established\ntest\nbar\n Routes: 12 imported, 1 filtered, 34 exported, 100 preferred\nxxx"
p := ParseProtocols([]byte(data), "6")
assert.IntEqual("protocols", 1, len(p), t)
@ -74,14 +76,14 @@ func TestIpv6Bgp(t *testing.T) {
assert.StringEqual("ipVersion", "6", x.IPVersion, t)
}
func TestActiveBgp(t *testing.T) {
func TestActiveBGP(t *testing.T) {
data := "bar BGP master start 2016-01-01 Active\ntest\nbar"
p := ParseProtocols([]byte(data), "4")
assert.IntEqual("protocols", 1, len(p), t)
x := p[0]
assert.StringEqual("name", "bar", x.Name, t)
assert.IntEqual("proto", protocol.BGP, x.Proto, t)
assert.IntEqual("proto", int(protocol.BGP), int(x.Proto), t)
assert.IntEqual("established", 0, x.Up, t)
assert.IntEqual("imported", 0, int(x.Imported), t)
assert.IntEqual("exported", 0, int(x.Exported), t)
@ -89,7 +91,7 @@ func TestActiveBgp(t *testing.T) {
assert.IntEqual("uptime", 0, int(x.Uptime), t)
}
func Test2BgpSessions(t *testing.T) {
func Test2BGPSessions(t *testing.T) {
data := "foo BGP master up 00:01:00 Established\ntest\n Routes: 12 imported, 1 filtered, 34 exported, 100 preferred\nbar BGP master start 2016-01-01 Active\nxxx"
p := ParseProtocols([]byte(data), "4")
assert.IntEqual("protocols", 2, len(p), t)
@ -172,7 +174,7 @@ func TestWithBird2(t *testing.T) {
x := p[0]
assert.StringEqual("BGP ipv6 name", "bgp1", x.Name, t)
assert.IntEqual("BGP ipv6 proto", protocol.BGP, x.Proto, t)
assert.IntEqual("BGP ipv6 proto", int(protocol.BGP), int(x.Proto), t)
assert.StringEqual("BGP ipv6 ip version", "6", x.IPVersion, t)
assert.Int64Equal("BGP ipv6 imported", 1, x.Imported, t)
assert.Int64Equal("BGP ipv6 exported", 3, x.Exported, t)
@ -183,7 +185,7 @@ func TestWithBird2(t *testing.T) {
x = p[1]
assert.StringEqual("Direct ipv4 name", "direct1", x.Name, t)
assert.IntEqual("Direct ipv4 proto", protocol.Direct, x.Proto, t)
assert.IntEqual("Direct ipv4 proto", int(protocol.Direct), int(x.Proto), t)
assert.StringEqual("Direct ipv4 ip version", "4", x.IPVersion, t)
assert.Int64Equal("Direct ipv4 imported", 12, x.Imported, t)
assert.Int64Equal("Direct ipv4 exported", 34, x.Exported, t)
@ -212,7 +214,7 @@ func TestWithBird2(t *testing.T) {
x = p[2]
assert.StringEqual("Direct ipv6 name", "direct1", x.Name, t)
assert.IntEqual("Direct ipv6 proto", protocol.Direct, x.Proto, t)
assert.IntEqual("Direct ipv6 proto", int(protocol.Direct), int(x.Proto), t)
assert.StringEqual("Direct ipv6 ip version", "6", x.IPVersion, t)
assert.Int64Equal("Direct ipv6 imported", 3, x.Imported, t)
assert.Int64Equal("Direct ipv6 exported", 5, x.Exported, t)
@ -241,7 +243,7 @@ func TestWithBird2(t *testing.T) {
x = p[3]
assert.StringEqual("OSPF ipv4 name", "ospf1", x.Name, t)
assert.IntEqual("OSPF ipv4 proto", protocol.OSPF, x.Proto, t)
assert.IntEqual("OSPF ipv4 proto", int(protocol.OSPF), int(x.Proto), t)
assert.StringEqual("OSPF ipv4 ip version", "4", x.IPVersion, t)
assert.Int64Equal("OSPF ipv4 imported", 4, x.Imported, t)
assert.Int64Equal("OSPF ipv4 exported", 2, x.Exported, t)
@ -249,14 +251,14 @@ func TestWithBird2(t *testing.T) {
assert.Int64Equal("OSPF ipv4 preferred", 1, x.Preferred, t)
}
func TestOspfOldTimeFormat(t *testing.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 := ParseProtocols([]byte(data), "4")
assert.IntEqual("protocols", 1, len(p), t)
x := p[0]
assert.StringEqual("name", "ospf1", x.Name, t)
assert.IntEqual("proto", protocol.OSPF, x.Proto, t)
assert.IntEqual("proto", int(protocol.OSPF), int(x.Proto), t)
assert.IntEqual("up", 1, x.Up, t)
assert.Int64Equal("imported", 12, x.Imported, t)
assert.Int64Equal("exported", 34, x.Exported, t)
@ -264,14 +266,14 @@ func TestOspfOldTimeFormat(t *testing.T) {
assert.StringEqual("ipVersion", "4", x.IPVersion, t)
}
func TestOspfCurrentTimeFormat(t *testing.T) {
func TestOSPFCurrentTimeFormat(t *testing.T) {
data := "ospf1 OSPF master up 00:01:00 Running\ntest\nbar\n Routes: 12 imported, 34 exported, 100 preferred\nxxx"
p := ParseProtocols([]byte(data), "4")
assert.IntEqual("protocols", 1, len(p), t)
x := p[0]
assert.StringEqual("name", "ospf1", x.Name, t)
assert.IntEqual("proto", protocol.OSPF, x.Proto, t)
assert.IntEqual("proto", int(protocol.OSPF), int(x.Proto), t)
assert.IntEqual("up", 1, x.Up, t)
assert.Int64Equal("imported", 12, x.Imported, t)
assert.Int64Equal("exported", 34, x.Exported, t)
@ -280,71 +282,14 @@ func TestOspfCurrentTimeFormat(t *testing.T) {
assert.IntEqual("uptime", 60, x.Uptime, t)
}
func TestOspfProtocolDown(t *testing.T) {
data := "o_hrz OSPF t_hrz down 1494926415 \n Preference: 150\n Input filter: ACCEPT\n Output filter: REJECT\nxxx"
p := ParseProtocols([]byte(data), "6")
assert.IntEqual("protocols", 1, len(p), t)
x := p[0]
assert.StringEqual("name", "o_hrz", x.Name, t)
assert.IntEqual("proto", protocol.OSPF, x.Proto, t)
assert.IntEqual("up", 0, x.Up, t)
assert.Int64Equal("imported", 0, x.Imported, t)
assert.Int64Equal("exported", 0, x.Exported, t)
assert.StringEqual("ipVersion", "6", x.IPVersion, t)
}
func TestOspfRunning(t *testing.T) {
data := "ospf1 OSPF master up 00:01:00 Running\ntest\nbar\n Routes: 12 imported, 34 exported, 100 preferred\nxxx"
func TestRPKIUp(t *testing.T) {
data := "rpki1 RPKI --- up 2021-12-31 13:04:29 Established"
p := ParseProtocols([]byte(data), "4")
assert.IntEqual("protocols", 1, len(p), t)
x := p[0]
assert.Float64Equal("running", 1, x.Attributes["running"], t)
}
func TestOspfAlone(t *testing.T) {
data := "ospf1 OSPF master up 00:01:00 Alone\ntest\nbar\n Routes: 12 imported, 34 exported, 100 preferred\nxxx"
p := ParseProtocols([]byte(data), "4")
assert.IntEqual("protocols", 1, len(p), t)
x := p[0]
assert.Float64Equal("running", 0, x.Attributes["running"], t)
}
func TestOspfArea(t *testing.T) {
data := "ospf1:\n" +
"RFC1583 compatibility: disabled\n" +
"Stub router: No\n" +
"RT scheduler tick: 1\n" +
"Number of areas: 2\n" +
"Number of LSAs in DB: 33\n" +
" Area: 0.0.0.0 (0) [BACKBONE]\n" +
" Stub: No\n" +
" NSSA: No\n" +
" Transit: No\n" +
" Number of interfaces: 3\n" +
" Number of neighbors: 2\n" +
" Number of adjacent neighbors: 1\n" +
" Area: 0.0.0.1 (1)\n" +
" Stub: No\n" +
" NSSA: No\n" +
" Transit: No\n" +
" Number of interfaces: 4\n" +
" Number of neighbors: 6\n" +
" Number of adjacent neighbors: 5\n"
a := ParseOspf([]byte(data))
assert.IntEqual("areas", 2, len(a), t)
a1 := a[0]
assert.StringEqual("Area1 Name", "0", a1.Name, t)
assert.Int64Equal("Area1 InterfaceCount", 3, a1.InterfaceCount, t)
assert.Int64Equal("Area1 NeighborCount", 2, a1.NeighborCount, t)
assert.Int64Equal("Area1 NeighborAdjacentCount", 1, a1.NeighborAdjacentCount, t)
a2 := a[1]
assert.StringEqual("Area2 Name", "1", a2.Name, t)
assert.Int64Equal("Area2 InterfaceCount", 4, a2.InterfaceCount, t)
assert.Int64Equal("Area2 NeighborCount", 6, a2.NeighborCount, t)
assert.Int64Equal("Area2 NeighborAdjacentCount", 5, a2.NeighborAdjacentCount, t)
assert.StringEqual("name", "rpki1", x.Name, t)
assert.IntEqual("proto", int(protocol.RPKI), int(x.Proto), t)
assert.StringEqual("state", "Established", x.State, t)
assert.IntEqual("up", 1, x.Up, t)
}

11
protocol/bfd_session.go Normal file
View File

@ -0,0 +1,11 @@
package protocol
type BFDSession struct {
ProtocolName string
IP string
Interface string
Up bool
Since int
Interval float64
Timeout float64
}

View File

@ -1,6 +1,6 @@
package protocol
type OspfArea struct {
type OSPFArea struct {
Name string
InterfaceCount int64
NeighborCount int64

View File

@ -1,28 +1,33 @@
package protocol
const (
PROTO_UNKNOWN = 0
BGP = 1
OSPF = 2
Kernel = 4
Static = 8
Direct = 16
PROTO_UNKNOWN = Proto(0)
BGP = Proto(1)
OSPF = Proto(2)
Kernel = Proto(4)
Static = Proto(8)
Direct = Proto(16)
Babel = Proto(32)
RPKI = Proto(64)
BFD = Proto(128)
)
type Proto int
type Protocol struct {
Name string
Description string
IPVersion string
ImportFilter string
ExportFilter string
Proto int
Proto Proto
Up int
State string
Imported int64
Exported int64
Filtered int64
Preferred int64
Uptime int
Attributes map[string]float64
ImportUpdates RouteChangeCount
ImportWithdraws RouteChangeCount
ExportUpdates RouteChangeCount
@ -37,6 +42,6 @@ type RouteChangeCount struct {
Accepted int64
}
func NewProtocol(name string, proto int, ipVersion string, uptime int) *Protocol {
return &Protocol{Name: name, Proto: proto, IPVersion: ipVersion, Uptime: uptime, Attributes: make(map[string]float64)}
func NewProtocol(name string, proto Proto, ipVersion string, uptime int) *Protocol {
return &Protocol{Name: name, Proto: proto, IPVersion: ipVersion, Uptime: uptime}
}