Skip to content

Commit

Permalink
feat: added OSPF metrics and corresponding testcase (#255)
Browse files Browse the repository at this point in the history
Co-authored-by: Joel Norberg <[email protected]>
  • Loading branch information
xerox81 and Joel Norberg authored Nov 24, 2023
1 parent 9da7dd6 commit fd7b9b6
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ Per-VDOM:
* `fortigate_bgp_neighbor_ipv6_paths`
* `fortigate_bgp_neighbor_ipv6_best_paths`

Per-OSPF-Neighbor and VDOM:
* _OSPF/Neighbors_
* `fortigate_ospf_neighbor_info`

Per-VirtualServer and VDOM:
* _Firewall/LoadBalance_
* `fortigate_lb_virtual_server_info`
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
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=
Expand Down
74 changes: 74 additions & 0 deletions pkg/probe/ospf_neighbors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package probe

import (
"log"
"strconv"

"github.com/bluecmd/fortigate_exporter/pkg/http"
"github.com/prometheus/client_golang/prometheus"
)

type OSPFNeighbor struct {
NeighborIP string `json:"neighbor_ip"`
RouterID string `json:"router_id"`
State string `json:"state"`
Priority int `json:"priority"`
}

type OSPFNeighborResponse struct {
Results []OSPFNeighbor `json:"results"`
VDOM string `json:"vdom"`
Version string `json:"version"`
}

func probeOSPFNeighbors(c http.FortiHTTP, meta *TargetMetadata) ([]prometheus.Metric, bool) {
if meta.VersionMajor < 7 {
// not supported version. Before 7.0.0 the requested endpoint doesn't exist
return nil, true
}
var (
mOSPFNeighbor = prometheus.NewDesc(
"fortigate_ospf_neighbor_info",
"List all discovered OSPF neighbors, return state as value (1 - Down, 2 - Attempt, 3 - Init, 4 - Two way, 5 - Exchange start, 6 - Exchange, 7 - Loading, 8 - Full)",
[]string{"vdom", "state", "priority", "router_id", "neighbor_ip"}, nil,
)
)

var rs []OSPFNeighborResponse

if err := c.Get("api/v2/monitor/router/ospf/neighbors", "vdom=*", &rs); err != nil {
log.Printf("Error: %v", err)
return nil, false
}

m := []prometheus.Metric{}

for _, r := range rs {
for _, peer := range r.Results {
m = append(m, prometheus.MustNewConstMetric(mOSPFNeighbor, prometheus.GaugeValue, ospfStateToNumber(peer.State), r.VDOM, peer.State, strconv.Itoa(peer.Priority), peer.RouterID, peer.NeighborIP))
}
}

return m, true
}

func ospfStateToNumber(ospfState string) float64 {
switch ospfState {
case "Attempt":
return 1
case "Init":
return 2
case "Two way":
return 3
case "Exchange start":
return 4
case "Exchange":
return 5
case "Loading":
return 6
case "Full":
return 7
default: // Down
return 0
}
}
28 changes: 28 additions & 0 deletions pkg/probe/ospf_neighbors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package probe

import (
"strings"
"testing"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/testutil"
)

func TestOSPFNeighborsIPv4(t *testing.T) {
c := newFakeClient()
c.prepare("api/v2/monitor/router/ospf/neighbors", "testdata/router-ospf-neighbors.jsonnet")
r := prometheus.NewPedanticRegistry()
if !testProbe(probeOSPFNeighbors, c, r) {
t.Errorf("probeOSPFNeighbors() returned non-success")
}

em := `
# HELP fortigate_ospf_neighbor_info List all discovered OSPF neighbors, return state as value (1 - Down, 2 - Attempt, 3 - Init, 4 - Two way, 5 - Exchange start, 6 - Exchange, 7 - Loading, 8 - Full)
# TYPE fortigate_ospf_neighbor_info gauge
fortigate_ospf_neighbor_info{neighbor_ip="10.0.0.1",priority="3",router_id="12345",state="Full",vdom="root"} 7
`

if err := testutil.GatherAndCompare(r, strings.NewReader(em)); err != nil {
t.Fatalf("metric compare: err %v", err)
}
}
1 change: 1 addition & 0 deletions pkg/probe/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ func (p *ProbeCollector) Probe(ctx context.Context, target map[string]string, hc
{"Wifi/Clients", probeWifiClients},
{"Wifi/ManagedAP", probeWifiManagedAP},
{"Switch/ManagedSwitch", probeManagedSwitch},
{"OSPF/Neighbors", probeOSPFNeighbors},
} {
wanted := false

Expand Down
22 changes: 22 additions & 0 deletions pkg/probe/testdata/router-ospf-neighbors.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# api/v2/monitor/router/ospf/neighbors?vdom=*
[
{
"http_method":"GET",
"results":[
{
"neighbor_ip":"10.0.0.1",
"priority":3,
"state":"Full",
"router_id":"12345"
}
],
"vdom":"root",
"path":"router",
"name":"ospf",
"action":"neighbors",
"status":"success",
"serial":"FGT61FT000000000",
"version":"v7.0.0",
"build":66
}
]

0 comments on commit fd7b9b6

Please sign in to comment.