Skip to content

Commit 9e424a1

Browse files
authored
Merge pull request #106 from chrroberts-pure/wwn-info
Collect Port Information (FC, iSCSI, NVMe) - purefa_network_interface_speed_bandwidth_bytes, purefa_network_port_info
2 parents f7e3694 + cea44b0 commit 9e424a1

17 files changed

+2089
-120
lines changed

internal/openmetrics-exporter/collector.go

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package collectors
22

33
import (
44
"context"
5+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
6+
57
"github.com/prometheus/client_golang/prometheus"
68
"github.com/prometheus/client_golang/prometheus/collectors"
7-
"purestorage/fa-openmetrics-exporter/internal/rest-client"
89
)
910

1011
func Collector(ctx context.Context, metrics string, registry *prometheus.Registry, faclient *client.FAClient) bool {
@@ -22,32 +23,36 @@ func Collector(ctx context.Context, metrics string, registry *prometheus.Registr
2223
hwcoll := NewHardwareCollector(faclient)
2324
drcoll := NewDriveCollector(faclient)
2425
nicsperfcoll := NewNetworkInterfacesPerformanceCollector(faclient)
26+
portscoll := NewPortsCollector(faclient)
27+
interfacecoll := NewNetworkInterfacesCollector(faclient)
2528
registry.MustRegister(
26-
alertscoll,
27-
arrayperfcoll,
28-
arrayspacecoll,
29-
hwcoll,
30-
drcoll,
31-
nicsperfcoll,
32-
)
29+
alertscoll,
30+
arrayperfcoll,
31+
arrayspacecoll,
32+
hwcoll,
33+
drcoll,
34+
nicsperfcoll,
35+
portscoll,
36+
interfacecoll,
37+
)
3338
}
3439
if metrics == "all" || metrics == "directories" {
3540
dirperfcoll := NewDirectoriesPerformanceCollector(faclient)
3641
dirspacecoll := NewDirectoriesSpaceCollector(faclient)
3742
registry.MustRegister(
38-
dirperfcoll,
39-
dirspacecoll,
40-
)
43+
dirperfcoll,
44+
dirspacecoll,
45+
)
4146
}
4247
if metrics == "all" || metrics == "hosts" {
4348
hostperfcoll := NewHostsPerformanceCollector(faclient)
4449
hostspacecoll := NewHostsSpaceCollector(faclient)
4550
hostconncoll := NewHostConnectionsCollector(faclient)
4651
registry.MustRegister(
47-
hostconncoll,
48-
hostperfcoll,
49-
hostspacecoll,
50-
)
52+
hostconncoll,
53+
hostperfcoll,
54+
hostspacecoll,
55+
)
5156
}
5257
if metrics == "all" || metrics == "pods" {
5358
podsperfcoll := NewPodsPerformanceCollector(faclient)
@@ -56,21 +61,21 @@ func Collector(ctx context.Context, metrics string, registry *prometheus.Registr
5661
podreplinkperfcoll := NewPodReplicaLinksPerformanceCollector(faclient)
5762
podreplinklagcoll := NewPodReplicaLinksLagCollector(faclient)
5863
registry.MustRegister(
59-
podsperfcoll,
60-
podsspacecoll,
61-
podsperfrepl,
62-
podreplinkperfcoll,
63-
podreplinklagcoll,
64-
)
64+
podsperfcoll,
65+
podsspacecoll,
66+
podsperfrepl,
67+
podreplinkperfcoll,
68+
podreplinklagcoll,
69+
)
6570
}
6671
if metrics == "all" || metrics == "volumes" {
6772
vols := faclient.GetVolumes()
6873
volperfcoll := NewVolumesPerformanceCollector(faclient, vols)
6974
volspacecoll := NewVolumesSpaceCollector(vols)
7075
registry.MustRegister(
71-
volperfcoll,
72-
volspacecoll,
73-
)
76+
volperfcoll,
77+
volspacecoll,
78+
)
7479
}
7580
return true
7681
}

internal/openmetrics-exporter/drives_collector.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package collectors
22

3-
43
import (
4+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
5+
56
"github.com/prometheus/client_golang/prometheus"
6-
"purestorage/fa-openmetrics-exporter/internal/rest-client"
77
)
88

99
type DriveCollector struct {
10-
CapacityDesc *prometheus.Desc
11-
Client *client.FAClient
10+
CapacityDesc *prometheus.Desc
11+
Client *client.FAClient
1212
}
1313

1414
func (c *DriveCollector) Describe(ch chan<- *prometheus.Desc) {
@@ -27,7 +27,7 @@ func (c *DriveCollector) Collect(ch chan<- prometheus.Metric) {
2727
d.Capacity,
2828
d.Name, d.Type, d.Status, d.Protocol,
2929
)
30-
}
30+
}
3131
}
3232

3333
func NewDriveCollector(fa *client.FAClient) *DriveCollector {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package collectors
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"net/http/httptest"
8+
"os"
9+
"regexp"
10+
"strconv"
11+
"strings"
12+
"testing"
13+
14+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
15+
)
16+
17+
func TestNetworkInterfacesCollectorTest(t *testing.T) {
18+
19+
rhw, _ := os.ReadFile("../../test/data/network_interfaces.json")
20+
vers, _ := os.ReadFile("../../test/data/versions.json")
21+
var hwl client.NetworkInterfacesList
22+
json.Unmarshal(rhw, &hwl)
23+
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
24+
url := regexp.MustCompile(`^/api/([0-9]+.[0-9]+)?/network-interfaces$`)
25+
if r.URL.Path == "/api/api_version" {
26+
w.Header().Set("Content-Type", "application/json")
27+
w.WriteHeader(http.StatusOK)
28+
w.Write([]byte(vers))
29+
} else if url.MatchString(r.URL.Path) {
30+
w.Header().Set("x-auth-token", "faketoken")
31+
w.Header().Set("Content-Type", "application/json")
32+
w.WriteHeader(http.StatusOK)
33+
w.Write([]byte(rhw))
34+
}
35+
}))
36+
endp := strings.Split(server.URL, "/")
37+
e := endp[len(endp)-1]
38+
want := make(map[string]bool)
39+
for _, h := range hwl.Items {
40+
want[fmt.Sprintf("label:{name:\"enabled\" value:\"%s\"} label:{name:\"ethsubtype\" value:\"%s\"} label:{name:\"name\" value:\"%s\"} label:{name:\"services\" value:\"%s\"} label:{name:\"type\" value:\"%s\"} gauge:{value:%g}", strconv.FormatBool(h.Enabled), h.Eth.Subtype, h.Name, strings.Join(h.Services, ", "), h.InterfaceType, float64(h.Speed))] = true
41+
}
42+
c := client.NewRestClient(e, "fake-api-token", "latest", false)
43+
nc := NewNetworkInterfacesCollector(c)
44+
metricsCheck(t, nc, want)
45+
server.Close()
46+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package collectors
2+
3+
import (
4+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
5+
"strconv"
6+
"strings"
7+
8+
"github.com/prometheus/client_golang/prometheus"
9+
)
10+
11+
type NetworkInterfacesCollector struct {
12+
NetworkInterfaceInfoDesc *prometheus.Desc
13+
Client *client.FAClient
14+
}
15+
16+
func (c *NetworkInterfacesCollector) Describe(ch chan<- *prometheus.Desc) {
17+
prometheus.DescribeByCollect(c, ch)
18+
}
19+
20+
func (c *NetworkInterfacesCollector) Collect(ch chan<- prometheus.Metric) {
21+
nwl := c.Client.GetNetworkInterfaces()
22+
if len(nwl.Items) == 0 {
23+
return
24+
}
25+
for _, h := range nwl.Items {
26+
ch <- prometheus.MustNewConstMetric(
27+
c.NetworkInterfaceInfoDesc,
28+
prometheus.GaugeValue,
29+
float64(h.Speed),
30+
strconv.FormatBool(h.Enabled), h.Eth.Subtype, h.Name, strings.Join(h.Services, ", "), h.InterfaceType,
31+
)
32+
}
33+
}
34+
35+
func NewNetworkInterfacesCollector(fa *client.FAClient) *NetworkInterfacesCollector {
36+
return &NetworkInterfacesCollector{
37+
NetworkInterfaceInfoDesc: prometheus.NewDesc(
38+
"purefa_network_interface_speed_bandwidth_bytes",
39+
"FlashArray network interface speed in bytes per second",
40+
[]string{"enabled", "ethsubtype", "name", "services", "type"},
41+
prometheus.Labels{},
42+
),
43+
Client: fa,
44+
}
45+
}

internal/openmetrics-exporter/network_interfaces_performance_collector.go

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package collectors
22

3-
43
import (
4+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
5+
56
"github.com/prometheus/client_golang/prometheus"
6-
"purestorage/fa-openmetrics-exporter/internal/rest-client"
77
)
88

99
type NetworkInterfacesPerformanceCollector struct {
10-
BandwidthDesc *prometheus.Desc
11-
ThroughputDesc *prometheus.Desc
12-
ErrorsDesc *prometheus.Desc
13-
Client *client.FAClient
10+
BandwidthDesc *prometheus.Desc
11+
ThroughputDesc *prometheus.Desc
12+
ErrorsDesc *prometheus.Desc
13+
Client *client.FAClient
1414
}
1515

1616
func (c *NetworkInterfacesPerformanceCollector) Describe(ch chan<- *prometheus.Desc) {
@@ -153,24 +153,24 @@ func (c *NetworkInterfacesPerformanceCollector) Collect(ch chan<- prometheus.Met
153153

154154
func NewNetworkInterfacesPerformanceCollector(fa *client.FAClient) *NetworkInterfacesPerformanceCollector {
155155
return &NetworkInterfacesPerformanceCollector{
156-
BandwidthDesc: prometheus.NewDesc(
157-
"purefa_network_interface_performance_bandwidth_bytes",
158-
"FlashArray network interface bandwidth",
159-
[]string{"name", "dimension", "type"},
160-
prometheus.Labels{},
161-
),
162-
ThroughputDesc: prometheus.NewDesc(
163-
"purefa_network_interface_performance_throughput_pkts",
164-
"FlashArray network interface throughput",
165-
[]string{"name", "dimension", "type"},
166-
prometheus.Labels{},
167-
),
168-
ErrorsDesc: prometheus.NewDesc(
169-
"purefa_network_interface_performance_errors",
170-
"FlashArray network interface errors",
171-
[]string{"name", "dimension", "type"},
172-
prometheus.Labels{},
173-
),
156+
BandwidthDesc: prometheus.NewDesc(
157+
"purefa_network_interface_performance_bandwidth_bytes",
158+
"FlashArray network interface bandwidth",
159+
[]string{"name", "dimension", "type"},
160+
prometheus.Labels{},
161+
),
162+
ThroughputDesc: prometheus.NewDesc(
163+
"purefa_network_interface_performance_throughput_pkts",
164+
"FlashArray network interface throughput",
165+
[]string{"name", "dimension", "type"},
166+
prometheus.Labels{},
167+
),
168+
ErrorsDesc: prometheus.NewDesc(
169+
"purefa_network_interface_performance_errors",
170+
"FlashArray network interface errors",
171+
[]string{"name", "dimension", "type"},
172+
prometheus.Labels{},
173+
),
174174
Client: fa,
175175
}
176176
}

internal/openmetrics-exporter/network_interfaces_performance_collector_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
func TestNetworkInterfacesPerformanceCollector(t *testing.T) {
1818
res, _ := os.ReadFile("../../test/data/network_interfaces_performance.json")
1919
vers, _ := os.ReadFile("../../test/data/versions.json")
20-
var nics client.NetworkInterfacesList
20+
var nics client.NetworkInterfacesPerformanceList
2121
json.Unmarshal(res, &nics)
2222
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2323
valid := regexp.MustCompile(`^/api/([0-9]+.[0-9]+)?/network-interfaces/performance$`)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package collectors
2+
3+
import (
4+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
5+
6+
"github.com/prometheus/client_golang/prometheus"
7+
)
8+
9+
type PortsCollector struct {
10+
PortInfoDesc *prometheus.Desc
11+
Client *client.FAClient
12+
}
13+
14+
func (c *PortsCollector) Describe(ch chan<- *prometheus.Desc) {
15+
prometheus.DescribeByCollect(c, ch)
16+
}
17+
18+
func (c *PortsCollector) Collect(ch chan<- prometheus.Metric) {
19+
hwl := c.Client.GetPorts()
20+
if len(hwl.Items) == 0 {
21+
return
22+
}
23+
for _, h := range hwl.Items {
24+
ch <- prometheus.MustNewConstMetric(
25+
c.PortInfoDesc,
26+
prometheus.GaugeValue,
27+
1,
28+
h.Iqn, h.Name, h.Nqn, h.Portal, h.Wwn,
29+
)
30+
}
31+
}
32+
33+
func NewPortsCollector(fa *client.FAClient) *PortsCollector {
34+
return &PortsCollector{
35+
PortInfoDesc: prometheus.NewDesc(
36+
"purefa_network_port_info",
37+
"FlashArray network port info",
38+
[]string{"iqn", "name", "nqn", "portal", "wwn"},
39+
prometheus.Labels{},
40+
),
41+
Client: fa,
42+
}
43+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package collectors
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"net/http/httptest"
8+
"os"
9+
"regexp"
10+
"strings"
11+
"testing"
12+
13+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
14+
)
15+
16+
func TestPortsCollector(t *testing.T) {
17+
18+
rhw, _ := os.ReadFile("../../test/data/ports.json")
19+
vers, _ := os.ReadFile("../../test/data/versions.json")
20+
var hwl client.PortsList
21+
json.Unmarshal(rhw, &hwl)
22+
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
23+
url := regexp.MustCompile(`^/api/([0-9]+.[0-9]+)?/ports$`)
24+
if r.URL.Path == "/api/api_version" {
25+
w.Header().Set("Content-Type", "application/json")
26+
w.WriteHeader(http.StatusOK)
27+
w.Write([]byte(vers))
28+
} else if url.MatchString(r.URL.Path) {
29+
w.Header().Set("x-auth-token", "faketoken")
30+
w.Header().Set("Content-Type", "application/json")
31+
w.WriteHeader(http.StatusOK)
32+
w.Write([]byte(rhw))
33+
}
34+
}))
35+
endp := strings.Split(server.URL, "/")
36+
e := endp[len(endp)-1]
37+
want := make(map[string]bool)
38+
for _, h := range hwl.Items {
39+
want[fmt.Sprintf("label:{name:\"iqn\" value:\"%s\"} label:{name:\"name\" value:\"%s\"} label:{name:\"nqn\" value:\"%s\"} label:{name:\"portal\" value:\"%s\"} label:{name:\"wwn\" value:\"%s\"} gauge:{value:1}", h.Iqn, h.Name, h.Nqn, h.Portal, h.Wwn)] = true
40+
}
41+
c := client.NewRestClient(e, "fake-api-token", "latest", false)
42+
pc := NewPortsCollector(c)
43+
metricsCheck(t, pc, want)
44+
server.Close()
45+
}

0 commit comments

Comments
 (0)