Skip to content

Commit 12c5ab6

Browse files
init
1 parent f0153d3 commit 12c5ab6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+272
-242
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ make docker-build
7777
```
7878

7979

80+
8081
### Authentication
8182

8283
Authentication is used by the exporter as the mechanism to cross authenticate to the scraped appliance, therefore for each array it is required to provide the REST API token for an account that has a 'readonly' role. The api-token can be provided in two ways
@@ -91,6 +92,12 @@ The second option provides the FlashArray/api-token key-pair map for a list of a
9192

9293
The exporter can be started in TLS mode (HTTPS, mutually exclusive with the HTTP mode) by providing the X.509 certificate and key files in the command parameters. Self-signed certificates are also accepted.
9394

95+
### Supported Headers
96+
97+
#### X-Request-ID (Optional)
98+
99+
The `X-Request-ID` Header, as used in the Purity API, may be used when calling the OpenMetrics exporter by using the HTTP Header `X-Request-ID`. It will then be passed and used when requesting metrics from the Purity API.
100+
94101
### Usage
95102

96103
```shell

cmd/fa-om-exporter/main.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ func fileExists(args []string) error {
2828
}
2929

3030
func isFile(filename string) bool {
31-
info, err := os.Stat(filename)
32-
if os.IsNotExist(err) {
33-
return false
34-
}
35-
return !info.IsDir()
31+
info, err := os.Stat(filename)
32+
if os.IsNotExist(err) {
33+
return false
34+
}
35+
return !info.IsDir()
3636
}
3737

3838
func main() {
@@ -72,14 +72,14 @@ func main() {
7272
}
7373
if (len(*cert) > 0 && len(*key) == 0) || (len(*cert) == 0 && len(*key) > 0) {
7474
log.Fatal("Both certificate and key must be specified to enable TLS")
75-
}
76-
if (len(*cert) > 0 && len(*key) > 0) {
75+
}
76+
if len(*cert) > 0 && len(*key) > 0 {
7777
if !isFile(*cert) {
7878
log.Fatal("TLS cert file not found")
79-
} else if !isFile (*key) {
79+
} else if !isFile(*key) {
8080
log.Fatal("TLS key file not found")
8181
}
82-
}
82+
}
8383
debug = *d
8484
addr := fmt.Sprintf("%s:%d", *host, *port)
8585
log.Printf("Start Pure FlashArray exporter %s on %s", version, addr)
@@ -143,16 +143,18 @@ func metricsHandler(w http.ResponseWriter, r *http.Request) {
143143
address, apitoken := arraytokens.GetArrayParams(endpoint)
144144
if len(authFields) == 2 && strings.ToLower(authFields[0]) == "bearer" {
145145
apitoken = authFields[1]
146-
address = endpoint
146+
address = endpoint
147147
}
148148
if apitoken == "" {
149149
http.Error(w, "Target authorization token is missing", http.StatusBadRequest)
150150
return
151151
}
152152

153-
uagent := r.Header.Get("User-Agent")
153+
uagent := r.Header.Get("User-Agent")
154+
rid := r.Header.Get("X-Request-ID")
155+
154156
registry := prometheus.NewRegistry()
155-
faclient := client.NewRestClient(address, apitoken, apiver, uagent, debug)
157+
faclient := client.NewRestClient(address, apitoken, apiver, uagent, rid, debug)
156158
if faclient.Error != nil {
157159
http.Error(w, "Error connecting to FlashArray. Check your management endpoint and/or api token are correct.", http.StatusBadRequest)
158160
return

internal/openmetrics-exporter/alerts_collector_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ func TestAlertsCollector(t *testing.T) {
5252

5353
want[fmt.Sprintf("label:{name:\"category\" value:\"%s\"} label:{name:\"code\" value:\"%s\"} label:{name:\"component_type\" value:\"%s\"} label:{name:\"created\" value:\"%s\"} label:{name:\"issue\" value:\"%s\"} label:{name:\"name\" value:\"%s\"} label:{name:\"severity\" value:\"%s\"} label:{name:\"summary\" value:\"%s\"} gauge:{value:%g}", alert[0], alert[1], alert[2], alert[3], alert[4], alert[5], alert[6], alert[7], n)] = true
5454
}
55-
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", false)
55+
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", "test-X-Request-Id-string", false)
56+
5657
ac := NewAlertsCollector(c)
5758
metricsCheck(t, ac, want)
5859
server.Close()

internal/openmetrics-exporter/arrays_collector_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ func TestArraysCollector(t *testing.T) {
4949

5050
want[fmt.Sprintf("label:{name:\"array_name\" value:\"%s\"} label:{name:\"os\" value:\"%s\"} label:{name:\"subscription_type\" value:\"%s\"} label:{name:\"system_id\" value:\"%s\"} label:{name:\"version\" value:\"%s\"} gauge:{value:1}", a.Name, a.Os, s.Service, a.Id, a.Version)] = true
5151

52-
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", false)
52+
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", "test-X-Request-Id-string", false)
53+
5354
ac := NewArraysCollector(c)
5455
metricsCheck(t, ac, want)
5556
server.Close()

internal/openmetrics-exporter/arrays_controllers_collector_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ func TestArrayControllersCollector(t *testing.T) {
3939
want[fmt.Sprintf("label:{name:\"mode\" value:\"%s\"} label:{name:\"model\"value:\"%s\"} label:{name:\"name\" value:\"%s\"} label:{name:\"status\" value:\"%s\"} label:{name:\"type\" value:\"%s\"} label:{name:\"version\" value:\"%s\"} gauge:{value:\"%g\"}", ctl.Mode, ctl.Model, ctl.Name, ctl.Status, ctl.Type, ctl.Version, (float64(ctl.ModeSince)/1000))] = true
4040
}
4141

42-
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", false)
42+
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", "test-X-Request-Id-string", false)
43+
4344
dc := NewControllersCollector(c)
4445
metricsCheck(t, dc, want)
4546
server.Close()

internal/openmetrics-exporter/arrays_performance_collector_test.go

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

3-
43
import (
4+
"encoding/json"
55
"fmt"
6-
"testing"
7-
"regexp"
8-
"strings"
96
"net/http"
107
"net/http/httptest"
11-
"encoding/json"
128
"os"
9+
"regexp"
10+
"strings"
11+
"testing"
1312

14-
"purestorage/fa-openmetrics-exporter/internal/rest-client"
13+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
1514
)
1615

1716
func TestArrayPerformanceCollector(t *testing.T) {
@@ -23,16 +22,16 @@ func TestArrayPerformanceCollector(t *testing.T) {
2322
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2423
valid := regexp.MustCompile(`^/api/([0-9]+.[0-9]+)?/arrays/performance$`)
2524
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))
25+
w.Header().Set("Content-Type", "application/json")
26+
w.WriteHeader(http.StatusOK)
27+
w.Write([]byte(vers))
2928
} else if valid.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(res))
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(res))
3433
}
35-
}))
34+
}))
3635
endp := strings.Split(server.URL, "/")
3736
e := endp[len(endp)-1]
3837
defer server.Close()
@@ -65,7 +64,8 @@ func TestArrayPerformanceCollector(t *testing.T) {
6564
want[fmt.Sprintf("label:{name:\"dimension\" value:\"bytes_per_read\"} gauge:{value:%g}", p.BytesPerRead)] = true
6665
want[fmt.Sprintf("label:{name:\"dimension\" value:\"bytes_per_write\"} gauge:{value:%g}", p.BytesPerWrite)] = true
6766
want[fmt.Sprintf("gauge:{value:%g}", p.QueueDepth)] = true
68-
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", false)
67+
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", "test-X-Request-Id-string", false)
68+
6969
pc := NewArraysPerformanceCollector(c)
7070
metricsCheck(t, pc, want)
7171
}

internal/openmetrics-exporter/arrays_space_collector_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ func TestArraySpaceCollector(t *testing.T) {
8686
want[fmt.Sprintf("label:{name:\"space\" value:\"empty\"} gauge:{value:%g}", a.Capacity-(float64(*a.Space.System)+float64(*a.Space.Replication)+float64(*a.Space.Shared)+float64(*a.Space.Snapshots)+float64(*a.Space.Unique)))] = true
8787
want[fmt.Sprintf("gauge:{value:%g}", (float64(*a.Space.System)+float64(*a.Space.Replication)+float64(*a.Space.Shared)+float64(*a.Space.Snapshots)+float64(*a.Space.Unique))/a.Capacity*100)] = true
8888
defer server.Close()
89-
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", false)
89+
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", "test-X-Request-Id-string", false)
90+
9091
ac := NewArraySpaceCollector(c)
9192
metricsCheck(t, ac, want)
9293
}
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
package collectors
22

3-
43
import (
4+
"encoding/json"
55
"fmt"
6-
"testing"
7-
"regexp"
8-
"strings"
96
"net/http"
107
"net/http/httptest"
11-
"encoding/json"
128
"os"
9+
"regexp"
10+
"strings"
11+
"testing"
1312

14-
"purestorage/fa-openmetrics-exporter/internal/rest-client"
13+
client "purestorage/fa-openmetrics-exporter/internal/rest-client"
1514
)
1615

1716
func TestDirectoriesPerformanceCollector(t *testing.T) {
@@ -23,16 +22,16 @@ func TestDirectoriesPerformanceCollector(t *testing.T) {
2322
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2423
valid := regexp.MustCompile(`^/api/([0-9]+.[0-9]+)?/directories/performance$`)
2524
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))
25+
w.Header().Set("Content-Type", "application/json")
26+
w.WriteHeader(http.StatusOK)
27+
w.Write([]byte(vers))
2928
} else if valid.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(res))
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(res))
3433
}
35-
}))
34+
}))
3635
endp := strings.Split(server.URL, "/")
3736
e := endp[len(endp)-1]
3837
defer server.Close()
@@ -50,7 +49,8 @@ func TestDirectoriesPerformanceCollector(t *testing.T) {
5049
want[fmt.Sprintf("label:{name:\"dimension\" value:\"bytes_per_read\"} label:{name:\"name\" value:\"%s\"} gauge:{value:%g}", p.Name, p.BytesPerRead)] = true
5150
want[fmt.Sprintf("label:{name:\"dimension\" value:\"bytes_per_write\"} label:{name:\"name\" value:\"%s\"} gauge:{value:%g}", p.Name, p.BytesPerWrite)] = true
5251
}
53-
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", false)
52+
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", "test-X-Request-Id-string", false)
53+
5454
pc := NewDirectoriesPerformanceCollector(c)
5555
metricsCheck(t, pc, want)
5656
}

internal/openmetrics-exporter/dirs_space_collector_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ func TestDirectoriesSpaceCollector(t *testing.T) {
8383
}
8484
}
8585
defer server.Close()
86-
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", false)
86+
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", "test-X-Request-Id-string", false)
87+
8788
hc := NewDirectoriesSpaceCollector(c)
8889
metricsCheck(t, hc, want)
8990
}

internal/openmetrics-exporter/drives_collector_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ func TestDriveCollector(t *testing.T) {
3939
want[fmt.Sprintf("label:{name:\"component_name\" value:\"%s\"} label:{name:\"component_status\" value:\"%s\"} label:{name:\"component_type\" value:\"%s\"} label:{name:\"component_type\" value:\"%s\"} gauge:{value:\"%g\"}", d.Name, d.Type, d.Status, d.Protocol, d.Capacity)] = true
4040
}
4141

42-
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", false)
42+
c := client.NewRestClient(e, "fake-api-token", "latest", "test-user-agent-string", "test-X-Request-Id-string", false)
43+
4344
dc := NewDriveCollector(c)
4445
metricsCheck(t, dc, want)
4546
server.Close()

0 commit comments

Comments
 (0)