Skip to content

Commit b5b9c18

Browse files
committed
add system global location probe
Add a new probe that retrieves device latitude and longitude from /api/v2/cmdb/system/global and exposes them as an info metric: fortigate_location_info{latitude, longitude} 1 The probe is best-effort and returns success even when the location metadata is not configured.
1 parent aeea6c3 commit b5b9c18

4 files changed

Lines changed: 365 additions & 0 deletions

File tree

pkg/probe/probe.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ func (p *Collector) Probe(ctx context.Context, target map[string]string, hc *htt
147147
{"System/AvailableCertificates", probeSystemAvailableCertificates},
148148
{"System/Central-Management/Status", probeSystemCentralManagementStatus},
149149
{"System/Fortimanager/Status", probeSystemFortimanagerStatus},
150+
{"System/Global/Location",probeSystemGlobalLocation},
150151
{"System/HAStatistics", probeSystemHAStatistics},
151152
{"System/Interface", probeSystemInterface},
152153
{"System/Interface/Transceivers", probeSystemInterfaceTransceivers},
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package probe
15+
16+
import (
17+
"encoding/json"
18+
"log"
19+
20+
"github.com/prometheus/client_golang/prometheus"
21+
"github.com/prometheus-community/fortigate_exporter/pkg/http"
22+
)
23+
24+
func probeSystemGlobalLocation(c http.FortiHTTP, _ *TargetMetadata) ([]prometheus.Metric, bool) {
25+
26+
location := prometheus.NewDesc(
27+
"fortigate_location_info",
28+
"System geographic location (static metadata)",
29+
[]string{"latitude", "longitude"},
30+
nil,
31+
)
32+
33+
type SystemGlobalLocation struct {
34+
Latitude string `json:"gui-device-latitude"`
35+
Longitude string `json:"gui-device-longitude"`
36+
}
37+
38+
type systemGlobalLocationResponse struct {
39+
Results json.RawMessage `json:"results"`
40+
}
41+
42+
var resp systemGlobalLocationResponse
43+
44+
if err := c.Get("api/v2/cmdb/system/global", "vdom=root", &resp); err != nil {
45+
log.Printf("Error: %v", err)
46+
return nil, false
47+
}
48+
49+
var loc SystemGlobalLocation
50+
51+
// Try object first
52+
if err := json.Unmarshal(resp.Results, &loc); err != nil {
53+
// Fallback to array
54+
var arr []SystemGlobalLocation
55+
if err := json.Unmarshal(resp.Results, &arr); err != nil || len(arr) == 0 {
56+
return nil, true
57+
}
58+
loc = arr[0]
59+
}
60+
61+
if loc.Latitude == "" || loc.Longitude == "" {
62+
return nil, true
63+
}
64+
65+
m := []prometheus.Metric{
66+
prometheus.MustNewConstMetric(
67+
location,
68+
prometheus.GaugeValue,
69+
1,
70+
loc.Latitude,
71+
loc.Longitude,
72+
),
73+
}
74+
return m, true
75+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package probe
15+
16+
import (
17+
"strings"
18+
"testing"
19+
20+
"github.com/prometheus/client_golang/prometheus"
21+
"github.com/prometheus/client_golang/prometheus/testutil"
22+
)
23+
24+
func TestSystemGlobalLocation(t *testing.T) {
25+
c := newFakeClient()
26+
c.prepare("api/v2/cmdb/system/global", "testdata/system-global-location.jsonnet")
27+
r := prometheus.NewPedanticRegistry()
28+
if !testProbe(probeSystemGlobalLocation, c, r) {
29+
t.Errorf("probeSystemGlobalLocation() returned non-success")
30+
}
31+
32+
em := `
33+
# HELP fortigate_location_info System geographic location (static metadata)
34+
# TYPE fortigate_location_info gauge
35+
fortigate_location_info{latitude="66.543508", longitude="25.8467468"} 1
36+
`
37+
38+
if err := testutil.GatherAndCompare(r, strings.NewReader(em)); err != nil {
39+
t.Fatalf("metric compare: err %v", err)
40+
}
41+
}
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
{
2+
"http_method": "GET",
3+
"revision": "4c8a904dacbad878bcd3c7f132447340",
4+
"results": {
5+
"language": "english",
6+
"gui-ipv6": "disable",
7+
"gui-replacement-message-groups": "disable",
8+
"gui-local-out": "disable",
9+
"gui-certificates": "enable",
10+
"gui-custom-language": "disable",
11+
"gui-wireless-opensecurity": "disable",
12+
"gui-app-detection-sdwan": "disable",
13+
"gui-display-hostname": "disable",
14+
"gui-fortigate-cloud-sandbox": "disable",
15+
"gui-firmware-upgrade-warning": "disable",
16+
"gui-forticare-registration-setup-warning": "disable",
17+
"gui-auto-upgrade-setup-warning": "disable",
18+
"gui-workflow-management": "disable",
19+
"gui-cdn-usage": "enable",
20+
"admin-https-ssl-versions": "tlsv1-2 tlsv1-3",
21+
"admin-https-ssl-ciphersuites": "TLS-AES-128-GCM-SHA256 TLS-AES-256-GCM-SHA384 TLS-CHACHA20-POLY1305-SHA256",
22+
"admin-https-ssl-banned-ciphers": "",
23+
"admintimeout": 30,
24+
"admin-console-timeout": 0,
25+
"admin-concurrent": "enable",
26+
"admin-lockout-threshold": 3,
27+
"admin-lockout-duration": 600,
28+
"refresh": 0,
29+
"interval": 5,
30+
"failtime": 5,
31+
"purdue-level": "3",
32+
"daily-restart": "disable",
33+
"restart-time": "00:00",
34+
"wad-restart-mode": "none",
35+
"wad-restart-start-time": "01:30",
36+
"wad-restart-end-time": "04:00",
37+
"radius-port": 1812,
38+
"speedtestd-server-port": 5201,
39+
"speedtestd-ctrl-port": 5200,
40+
"admin-login-max": 100,
41+
"remoteauthtimeout": 5,
42+
"ldapconntimeout": 500,
43+
"batch-cmdb": "enable",
44+
"multi-factor-authentication": "optional",
45+
"ssl-min-proto-version": "TLSv1-2",
46+
"autorun-log-fsck": "disable",
47+
"timezone": "Europe/Helsinki",
48+
"traffic-priority": "tos",
49+
"traffic-priority-level": "medium",
50+
"quic-congestion-control-algo": "cubic",
51+
"quic-max-datagram-size": 1500,
52+
"quic-udp-payload-size-shaping-per-cid": "enable",
53+
"quic-ack-thresold": 3,
54+
"quic-pmtud": "enable",
55+
"quic-tls-handshake-timeout": 5,
56+
"anti-replay": "strict",
57+
"send-pmtu-icmp": "enable",
58+
"honor-df": "enable",
59+
"pmtu-discovery": "disable",
60+
"virtual-switch-vlan": "disable",
61+
"revision-image-auto-backup": "disable",
62+
"revision-backup-on-logout": "disable",
63+
"management-vdom": "mgmt",
64+
"hostname": "vpngw01",
65+
"alias": "FortiGate-60F",
66+
"strong-crypto": "enable",
67+
"ssl-static-key-ciphers": "enable",
68+
"snat-route-change": "disable",
69+
"speedtest-server": "disable",
70+
"cli-audit-log": "disable",
71+
"dh-params": "2048",
72+
"fds-statistics": "enable",
73+
"fds-statistics-period": 60,
74+
"tcp-option": "enable",
75+
"lldp-transmission": "disable",
76+
"lldp-reception": "disable",
77+
"proxy-auth-timeout": 10,
78+
"proxy-keep-alive-mode": "session",
79+
"proxy-re-authentication-time": 30,
80+
"proxy-auth-lifetime": "disable",
81+
"proxy-auth-lifetime-timeout": 480,
82+
"proxy-resource-mode": "disable",
83+
"proxy-cert-use-mgmt-vdom": "disable",
84+
"sys-perf-log-interval": 5,
85+
"check-protocol-header": "loose",
86+
"vip-arp-range": "restricted",
87+
"reset-sessionless-tcp": "disable",
88+
"allow-traffic-redirect": "enable",
89+
"ipv6-allow-traffic-redirect": "enable",
90+
"strict-dirty-session-check": "enable",
91+
"tcp-halfclose-timer": 120,
92+
"tcp-halfopen-timer": 10,
93+
"tcp-timewait-timer": 1,
94+
"tcp-rst-timer": 5,
95+
"udp-idle-timer": 180,
96+
"block-session-timer": 30,
97+
"ip-src-port-range": "1024-25000",
98+
"pre-login-banner": "disable",
99+
"post-login-banner": "disable",
100+
"tftp": "enable",
101+
"av-failopen": "pass",
102+
"av-failopen-session": "disable",
103+
"memory-use-threshold-extreme": 95,
104+
"memory-use-threshold-red": 88,
105+
"memory-use-threshold-green": 82,
106+
"ip-fragment-mem-thresholds": 32,
107+
"cpu-use-threshold": 90,
108+
"log-single-cpu-high": "disable",
109+
"check-reset-range": "disable",
110+
"vdom-mode": "multi-vdom",
111+
"vdom-admin": "",
112+
"long-vdom-name": "disable",
113+
"edit-vdom-prompt": "enable",
114+
"admin-port": 80,
115+
"admin-sport": 443,
116+
"admin-host": "",
117+
"admin-https-redirect": "disable",
118+
"admin-hsts-max-age": 63072000,
119+
"admin-ssh-password": "enable",
120+
"admin-restrict-local": "disable",
121+
"admin-ssh-port": 22,
122+
"admin-ssh-grace-time": 120,
123+
"admin-ssh-v1": "disable",
124+
"admin-telnet": "enable",
125+
"admin-telnet-port": 23,
126+
"admin-forticloud-sso-login": "disable",
127+
"admin-forticloud-sso-default-profile": "",
128+
"default-service-source-port": "1-65535",
129+
"admin-reset-button": "enable",
130+
"admin-server-cert": "Fortinet_GUI_Server",
131+
"admin-https-pki-required": "disable",
132+
"wifi-certificate": "Fortinet_Wifi",
133+
"dhcp-lease-backup-interval": 60,
134+
"wifi-ca-certificate": "Fortinet_Wifi_CA",
135+
"auth-http-port": 1000,
136+
"auth-https-port": 1003,
137+
"auth-ike-saml-port": 1001,
138+
"auth-keepalive": "disable",
139+
"policy-auth-concurrent": 0,
140+
"auth-session-limit": "block-new",
141+
"auth-cert": "Fortinet_Factory",
142+
"clt-cert-req": "disable",
143+
"fortiservice-port": 8013,
144+
"cfg-save": "manual",
145+
"cfg-revert-timeout": 600,
146+
"reboot-upon-config-restore": "enable",
147+
"admin-scp": "enable",
148+
"security-rating-run-on-schedule": "enable",
149+
"wireless-controller": "disable",
150+
"wireless-controller-port": 5246,
151+
"fortiextender-data-port": 25246,
152+
"fortiextender": "disable",
153+
"extender-controller-reserved-network": "192.168.2.1 255.255.255.0",
154+
"fortiextender-discovery-lockdown": "disable",
155+
"fortiextender-vlan-mode": "disable",
156+
"fortiextender-provision-on-authorization": "disable",
157+
"switch-controller": "disable",
158+
"switch-controller-reserved-network": "192.168.1.1 255.255.255.0",
159+
"dnsproxy-worker-count": 1,
160+
"url-filter-count": 1,
161+
"proxy-worker-count": 0,
162+
"scanunit-count": 0,
163+
"proxy-hardware-acceleration": "enable",
164+
"fgd-alert-subscription": "",
165+
"ipsec-hmac-offload": "enable",
166+
"ipv6-accept-dad": 1,
167+
"ipv6-allow-anycast-probe": "disable",
168+
"ipv6-allow-multicast-probe": "disable",
169+
"ipv6-allow-local-in-silent-drop": "enable",
170+
"csr-ca-attribute": "enable",
171+
"wimax-4g-usb": "disable",
172+
"cert-chain-max": 8,
173+
"sslvpn-max-worker-count": 0,
174+
"vpn-ems-sn-check": "disable",
175+
"sslvpn-web-mode": "disable",
176+
"two-factor-ftk-expiry": 60,
177+
"two-factor-email-expiry": 60,
178+
"two-factor-sms-expiry": 60,
179+
"two-factor-fac-expiry": 60,
180+
"two-factor-ftm-expiry": 72,
181+
"wad-worker-count": 0,
182+
"wad-csvc-cs-count": 1,
183+
"wad-csvc-db-count": 0,
184+
"wad-source-affinity": "enable",
185+
"wad-memory-change-granularity": 10,
186+
"login-timestamp": "disable",
187+
"ip-conflict-detection": "disable",
188+
"miglogd-children": 0,
189+
"special-file-23-support": "disable",
190+
"log-uuid-address": "disable",
191+
"log-ssl-connection": "disable",
192+
"gui-rest-api-cache": "disable",
193+
"http-request-limit": 524288000,
194+
"http-unauthenticated-request-limit": 131072,
195+
"rest-api-key-url-query": "disable",
196+
"arp-max-entry": 131072,
197+
"ha-affinity": "1",
198+
"bfd-affinity": "1",
199+
"cmdbsvr-affinity": "1",
200+
"ndp-max-entry": 0,
201+
"br-fdb-max-entry": 8192,
202+
"max-route-cache-size": 0,
203+
"ipsec-asic-offload": "enable",
204+
"ipsec-round-robin": "disable",
205+
"device-idle-timeout": 300,
206+
"user-device-store-max-devices": 20109,
207+
"user-device-store-max-users": 20109,
208+
"user-device-store-max-unified-mem": 100547993,
209+
"gui-device-latitude": "66.543508",
210+
"gui-device-longitude": "25.8467468",
211+
"private-data-encryption": "disable",
212+
"auto-auth-extension-device": "enable",
213+
"gui-theme": "neutrino",
214+
"gui-date-format": "yyyy/MM/dd",
215+
"gui-date-time-source": "system",
216+
"igmp-state-limit": 3200,
217+
"cloud-communication": "disable",
218+
"ipsec-ha-seqjump-rate": 10,
219+
"fortitoken-cloud": "enable",
220+
"fortitoken-cloud-push-status": "enable",
221+
"fortitoken-cloud-region": "",
222+
"fortitoken-cloud-sync-interval": 24,
223+
"faz-disk-buffer-size": 0,
224+
"irq-time-accounting": "auto",
225+
"management-ip": "",
226+
"management-port": 443,
227+
"management-port-use-admin-sport": "enable",
228+
"forticonverter-integration": "disable",
229+
"forticonverter-config-upload": "disable",
230+
"internet-service-database": "standard",
231+
"internet-service-download-list": [],
232+
"early-tcp-npu-session": "disable",
233+
"npu-neighbor-update": "disable",
234+
"delay-tcp-npu-session": "disable",
235+
"interface-subnet-usage": "enable",
236+
"sflowd-max-children-num": 6,
237+
"fortigslb-integration": "disable"
238+
},
239+
"vdom": "root",
240+
"path": "system",
241+
"name": "global",
242+
"action": "",
243+
"status": "success",
244+
"http_status": 200,
245+
"serial": "FGT60F0123456789",
246+
"version": "v7.4.8",
247+
"build": 2795
248+
}

0 commit comments

Comments
 (0)