diff --git a/README.md b/README.md index 0e4cc46..628a446 100755 --- a/README.md +++ b/README.md @@ -63,6 +63,13 @@ Per-VDOM: * `fortigate_policy_bytes_total` * `fortigate_policy_hit_count_total` * `fortigate_policy_packets_total` + * _Firewall/IpPool_ + * `fortigate_ippool_available_ratio` + * `fortigate_ippool_used_ips` + * `fortigate_ippool_total_ips` + * `fortigate_ippool_clients` + * `fortigate_ippool_used_items` + * `fortigate_ippool_total_items` * _System/Fortimanager/Status_ * `fortigate_fortimanager_connection_status` * `fortigate_fortimanager_registration_status` @@ -386,6 +393,7 @@ To improve security, limit permissions to required ones only (least privilege pr |BGP/NeighborPaths/IPv6 | netgrp.route-cfg |api/v2/monitor/router/bgp/paths6 | |BGP/Neighbors/IPv4 | netgrp.route-cfg |api/v2/monitor/router/bgp/neighbors | |BGP/Neighbors/IPv6 | netgrp.route-cfg |api/v2/monitor/router/bgp/neighbors6 | +|Firewall/IpPool | fwgrp.policy |api/v2/monitor/firewall/ippool | |Firewall/LoadBalance | fwgrp.others |api/v2/monitor/firewall/load-balance | |Firewall/Policies | fwgrp.policy |api/v2/monitor/firewall/policy/select
api/v2/monitor/firewall/policy6/select
api/v2/cmdb/firewall/policy
api/v2/cmdb/firewall/policy6 | |License/Status | *any* |api/v2/monitor/license/status/select | diff --git a/pkg/probe/firewall_ippool.go b/pkg/probe/firewall_ippool.go new file mode 100644 index 0000000..2ff7203 --- /dev/null +++ b/pkg/probe/firewall_ippool.go @@ -0,0 +1,91 @@ +package probe + +import ( + "log" + + "github.com/bluecmd/fortigate_exporter/pkg/http" + "github.com/prometheus/client_golang/prometheus" +) + +type IpPool struct { + Name string `json:"name"` + IPTotal int `json:"natip_total"` + IPInUse int `json:"natip_in_use"` + Clients int `json:"clients"` + Available float64 `json:"available"` + Used int `json:"used"` + Total int `json:"total"` +} + +type IpPoolResponse struct { + Results map[string]IpPool `json:"results"` + VDOM string `json:"vdom"` + Version string `json:"version"` +} + +func probeFirewallIpPool(c http.FortiHTTP, meta *TargetMetadata) ([]prometheus.Metric, bool) { + var ( + mAvailable = prometheus.NewDesc( + "fortigate_ippool_available_ratio", + "Percentage available in ippool (0 - 1.0)", + []string{"vdom", "name"}, nil, + ) + ) + var ( + mIpUsed = prometheus.NewDesc( + "fortigate_ippool_used_ips", + "Ip addresses in use in ippool", + []string{"vdom", "name"}, nil, + ) + ) + var ( + mIpTotal = prometheus.NewDesc( + "fortigate_ippool_total_ips", + "Ip addresses total in ippool", + []string{"vdom", "name"}, nil, + ) + ) + var ( + mClients = prometheus.NewDesc( + "fortigate_ippool_clients", + "Amount of clients using ippool", + []string{"vdom", "name"}, nil, + ) + ) + var ( + mUsed = prometheus.NewDesc( + "fortigate_ippool_used_items", + "Amount of items used in ippool", + []string{"vdom", "name"}, nil, + ) + ) + var ( + mTotal = prometheus.NewDesc( + "fortigate_ippool_total_items", + "Amount of items total in ippool", + []string{"vdom", "name"}, nil, + ) + ) + + var rs []IpPoolResponse + + if err := c.Get("api/v2/monitor/firewall/ippool", "vdom=*", &rs); err != nil { + log.Printf("Error: %v", err) + return nil, false + } + + m := []prometheus.Metric{} + + for _, r := range rs { + for _, ippool := range r.Results { + m = append(m, prometheus.MustNewConstMetric(mAvailable, prometheus.GaugeValue, ippool.Available/100, r.VDOM, ippool.Name)) + m = append(m, prometheus.MustNewConstMetric(mIpUsed, prometheus.GaugeValue, float64(ippool.IPInUse), r.VDOM, ippool.Name)) + m = append(m, prometheus.MustNewConstMetric(mIpTotal, prometheus.GaugeValue, float64(ippool.IPTotal), r.VDOM, ippool.Name)) + m = append(m, prometheus.MustNewConstMetric(mClients, prometheus.GaugeValue, float64(ippool.Clients), r.VDOM, ippool.Name)) + m = append(m, prometheus.MustNewConstMetric(mUsed, prometheus.GaugeValue, float64(ippool.Used), r.VDOM, ippool.Name)) + m = append(m, prometheus.MustNewConstMetric(mTotal, prometheus.GaugeValue, float64(ippool.Total), r.VDOM, ippool.Name)) + } + } + + return m, true +} diff --git a/pkg/probe/firewall_ippool_test.go b/pkg/probe/firewall_ippool_test.go new file mode 100644 index 0000000..dbce34e --- /dev/null +++ b/pkg/probe/firewall_ippool_test.go @@ -0,0 +1,42 @@ +package probe + +import ( + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil" +) + +func TestFirewallIpPool(t *testing.T) { + c := newFakeClient() + c.prepare("api/v2/monitor/firewall/ippool", "testdata/fw-ippool.jsonnet") + r := prometheus.NewPedanticRegistry() + if !testProbe(probeFirewallIpPool, c, r) { + t.Errorf("probeFirewallIpPool() returned non-success") + } + + em := ` + # HELP fortigate_ippool_available_ratio Percentage available in ippool (0 - 1.0) + # TYPE fortigate_ippool_available_ratio gauge + fortigate_ippool_available_ratio{name="ippool_name",vdom="FG-traffic"} 1 + # HELP fortigate_ippool_clients Amount of clients using ippool + # TYPE fortigate_ippool_clients gauge + fortigate_ippool_clients{name="ippool_name",vdom="FG-traffic"} 0 + # HELP fortigate_ippool_total_ips Ip addresses total in ippool + # TYPE fortigate_ippool_total_ips gauge + fortigate_ippool_total_ips{name="ippool_name",vdom="FG-traffic"} 1 + # HELP fortigate_ippool_total_items Amount of items total in ippool + # TYPE fortigate_ippool_total_items gauge + fortigate_ippool_total_items{name="ippool_name",vdom="FG-traffic"} 472 + # HELP fortigate_ippool_used_ips Ip addresses in use in ippool + # TYPE fortigate_ippool_used_ips gauge + fortigate_ippool_used_ips{name="ippool_name",vdom="FG-traffic"} 0 + # HELP fortigate_ippool_used_items Amount of items used in ippool + # TYPE fortigate_ippool_used_items gauge + fortigate_ippool_used_items{name="ippool_name",vdom="FG-traffic"} 0 + ` + if err := testutil.GatherAndCompare(r, strings.NewReader(em)); err != nil { + t.Fatalf("metric compare: err %v", err) + } +} diff --git a/pkg/probe/probe.go b/pkg/probe/probe.go index a44ab69..7104283 100644 --- a/pkg/probe/probe.go +++ b/pkg/probe/probe.go @@ -122,6 +122,7 @@ func (p *ProbeCollector) Probe(ctx context.Context, target map[string]string, hc {"BGP/Neighbors/IPv6", probeBGPNeighborsIPv6}, {"Firewall/LoadBalance", probeFirewallLoadBalance}, {"Firewall/Policies", probeFirewallPolicies}, + {"Firewall/IpPool", probeFirewallIpPool}, {"License/Status", probeLicenseStatus}, {"Log/Fortianalyzer/Status", probeLogAnalyzer}, {"Log/Fortianalyzer/Queue", probeLogAnalyzerQueue}, diff --git a/pkg/probe/testdata/fw-ippool.jsonnet b/pkg/probe/testdata/fw-ippool.jsonnet new file mode 100644 index 0000000..cc23978 --- /dev/null +++ b/pkg/probe/testdata/fw-ippool.jsonnet @@ -0,0 +1,30 @@ +# api/v2/monitor/firewall/ippool?vdom=* + +[ + { + "http_method": "GET", + "results": { + "ippool_name": { + "name": "ippool_name", + "blocks": 8, + "block_size": 128, + "fixed_port": false, + "pba_per_ip": 472, + "used": 0, + "total": 472, + "available": 100.0, + "clients": 0, + "natip_in_use": 0, + "natip_total": 1 + } + }, + "vdom":"FG-traffic", + "path":"firewall", + "name":"ippool", + "action":"", + "status":"success", + "serial":"FGVMEVZFNTS3OAC8", + "version":"v7.0.11", + "build":489 + } +]