Skip to content

Commit 77dbf88

Browse files
Merge branch 'main' into feature/sdn-connector-v7.6
2 parents 9550fbd + a03e09f commit 77dbf88

10 files changed

Lines changed: 409 additions & 5 deletions

.github/workflows/golangci-lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
with:
2929
persist-credentials: false
3030
- name: Install Go
31-
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
31+
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
3232
with:
3333
go-version: 1.25.x
3434
- name: Install snmp_exporter/generator dependencies

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ To improve security, limit permissions to required ones only (least privilege pr
182182
|System/AvailableCertificates | *any* |api/v2/monitor/system/available-certificates |
183183
|System/Central-management/Status | sysgrp.cfg |api/v2/monitor/system/central-management/status|
184184
|System/Fortimanager/Status | sysgrp.cfg |api/v2/monitor/system/fortimanager/status |
185+
|System/Global/Location | sysgrp.cfg |api/v2/cmdb/system/global |
185186
|System/HAStatistics | sysgrp.cfg |api/v2/monitor/system/ha-statistics<br>api/v2/cmdb/system/ha |
186187
|System/Ha-peer | sysgrp.cfg |api/v2/monitor/system/ha-peer |
187188
|System/Interface | netgrp.cfg |api/v2/monitor/system/interface/select |

metrics.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Global:
44

55
* _Network/Dns/Latency_
66
* `fortigate_network_dns_latency_`
7+
* _System/Global/Location_
8+
* `fortigate_location_info`
79
* _System/SensorInfo_
810
* `fortigate_sensor_alarm_status`
911
* `fortigate_sensor_fan_rpm`
@@ -12,6 +14,7 @@ Global:
1214
* `fortigate_sensor_thresholds`
1315
* _System/Status_
1416
* `fortigate_version_info`
17+
* `fortigate_system_status_log_disk_state`
1518
* _System/Transceivers_
1619
* `fortigate_interface_transceivers`
1720
* _System/Time/Clock_

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/Ha-peer", probeSystemHaPeer},
152153
{"System/Interface", probeSystemInterface},
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+
22+
"github.com/prometheus-community/fortigate_exporter/pkg/http"
23+
)
24+
25+
func probeSystemGlobalLocation(c http.FortiHTTP, _ *TargetMetadata) ([]prometheus.Metric, bool) {
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+
}

pkg/probe/system_status.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,28 @@ func probeSystemStatus(c http.FortiHTTP, _ *TargetMetadata) ([]prometheus.Metric
2626
mVersion := prometheus.NewDesc(
2727
"fortigate_version_info",
2828
"System version and build information",
29-
[]string{"serial", "version", "build"}, nil,
29+
[]string{"serial", "version", "build", "model_name", "model_number", "model", "hostname"}, nil,
3030
)
31+
mLogDiskState := prometheus.NewDesc(
32+
"fortigate_system_status_log_disk_state",
33+
"System log disk availability state",
34+
[]string{"state"}, nil,
35+
)
36+
37+
type systemResult struct {
38+
Name string `json:"model_name"`
39+
Number string `json:"model_number"`
40+
Model string `json:"model"`
41+
Hostname string `json:"hostname"`
42+
LogDiskStatus string `json:"log_disk_status"`
43+
}
3144

3245
type systemStatus struct {
3346
Status string
3447
Serial string
3548
Version string
3649
Build int64
50+
Results systemResult
3751
}
3852
var st systemStatus
3953

@@ -43,7 +57,18 @@ func probeSystemStatus(c http.FortiHTTP, _ *TargetMetadata) ([]prometheus.Metric
4357
}
4458

4559
m := []prometheus.Metric{
46-
prometheus.MustNewConstMetric(mVersion, prometheus.GaugeValue, 1.0, st.Serial, st.Version, fmt.Sprintf("%d", st.Build)),
60+
prometheus.MustNewConstMetric(mLogDiskState, prometheus.GaugeValue, 0.0, "available"),
61+
prometheus.MustNewConstMetric(mLogDiskState, prometheus.GaugeValue, 0.0, "need_format"),
62+
prometheus.MustNewConstMetric(mLogDiskState, prometheus.GaugeValue, 0.0, "not_available"),
63+
}
64+
switch st.Results.LogDiskStatus {
65+
case "available":
66+
m[0] = prometheus.MustNewConstMetric(mLogDiskState, prometheus.GaugeValue, 1.0, st.Results.LogDiskStatus)
67+
case "need_format":
68+
m[1] = prometheus.MustNewConstMetric(mLogDiskState, prometheus.GaugeValue, 1.0, st.Results.LogDiskStatus)
69+
case "not_available":
70+
m[2] = prometheus.MustNewConstMetric(mLogDiskState, prometheus.GaugeValue, 1.0, st.Results.LogDiskStatus)
4771
}
72+
m = append(m, prometheus.MustNewConstMetric(mVersion, prometheus.GaugeValue, 1.0, st.Serial, st.Version, fmt.Sprintf("%d", st.Build), st.Results.Name, st.Results.Number, st.Results.Model, st.Results.Hostname))
4873
return m, true
4974
}

pkg/probe/system_status_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ func TestSystemStatus(t *testing.T) {
3030
}
3131

3232
em := `
33+
# HELP fortigate_system_status_log_disk_state System log disk availability state
34+
# TYPE fortigate_system_status_log_disk_state gauge
35+
fortigate_system_status_log_disk_state{state="available"} 0
36+
fortigate_system_status_log_disk_state{state="need_format"} 0
37+
fortigate_system_status_log_disk_state{state="not_available"} 1
3338
# HELP fortigate_version_info System version and build information
3439
# TYPE fortigate_version_info gauge
35-
fortigate_version_info{build="1112",serial="FGVMEVZFNTS3OAC8",version="v6.2.4"} 1
40+
fortigate_version_info{build="1112",hostname="fgt-test-1",model="F2K60F",model_name="FortiGate",model_number="2600F",serial="FGVMEVZFNTS3OAC8",version="v6.2.4"} 1
3641
`
3742

3843
if err := testutil.GatherAndCompare(r, strings.NewReader(em)); err != nil {

pkg/probe/testdata/status.jsonnet

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
{
33
"http_method":"GET",
44
"results":{
5+
"model_name":"FortiGate",
6+
"model_number":"2600F",
7+
"model":"F2K60F",
8+
"hostname":"fgt-test-1",
9+
"log_disk_status":"not_available"
510
},
611
"vdom":"root",
712
"path":"system",
@@ -10,4 +15,4 @@
1015
"serial":"FGVMEVZFNTS3OAC8",
1116
"version":"v6.2.4",
1217
"build":1112
13-
}
18+
}

0 commit comments

Comments
 (0)