From a56b401c64ab6ddb80007bcd49df92220f7d7606 Mon Sep 17 00:00:00 2001 From: andersh Date: Mon, 11 Nov 2024 11:37:38 +0100 Subject: [PATCH 1/3] fix: add a validation of the queries to be executed and if they do not exist in the configuration 400 is returned and log with warning --- aci-exporter.go | 30 ++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 3 files changed, 33 insertions(+) diff --git a/aci-exporter.go b/aci-exporter.go index d66425d..03bcf8d 100644 --- a/aci-exporter.go +++ b/aci-exporter.go @@ -28,6 +28,7 @@ import ( "net/http" + mapset "github.com/deckarep/golang-set/v2" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -77,6 +78,7 @@ func isFlagPassed(name string) bool { } var version = "undefined" +var querySet = mapset.NewSet[string]() func main() { @@ -248,6 +250,9 @@ func main() { GroupClassQueries: queries.GroupClassQueries, } + // Create a set of all query names - used to validate the query parameter + createQueryNameSet(allQueries) + // Init all fabrics allFabrics := make(map[string]*Fabric) @@ -341,6 +346,19 @@ func main() { log.Fatal(s.ListenAndServe()) } +func createQueryNameSet(allQueries AllQueries) { + for queryName, _ := range allQueries.ClassQueries { + querySet.Add(queryName) + } + for queryName, _ := range allQueries.CompoundClassQueries { + querySet.Add(queryName) + } + for queryName, _ := range allQueries.GroupClassQueries { + querySet.Add(queryName) + } + querySet.Add("faults") +} + func readConfigDirectory(configDirName *string, dirPath string, queries *AllQueries) { configDir := filepath.Join(dirPath, *configDirName) _, err := os.Stat(configDir) @@ -530,6 +548,18 @@ func (h HandlerInit) getMonitorMetrics(w http.ResponseWriter, r *http.Request) { // If the queries query parameter include a comma, split it and add to the queries array querySplit := strings.Split(queryString, ",") for _, query := range querySplit { + // Validate that the query is a valid query + if !querySet.Contains(query) { + w.Header().Set("Content-Type", "text/plain; version=0.0.4; charset=utf-8") + w.Header().Set("Content-Length", "0") + log.WithFields(log.Fields{ + LogFieldFabric: fabric, + "query": query, + }).Warning("not a valid query") + lrw := loggingResponseWriter{ResponseWriter: w} + lrw.WriteHeader(400) + return + } queries = append(queries, strings.TrimSpace(query)) } } diff --git a/go.mod b/go.mod index 4cc6716..1f16372 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/fsnotify/fsnotify v1.4.7 // indirect github.com/golang/protobuf v1.5.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect diff --git a/go.sum b/go.sum index 287a1e5..08e7b53 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= From d7439f0528b7a0252ea11715ddb493a12d61558c Mon Sep 17 00:00:00 2001 From: andersh Date: Mon, 11 Nov 2024 11:39:12 +0100 Subject: [PATCH 2/3] fix: issue #72, now return aci_up == 0 if no metrics is returned from the call assuming apic or node is down. --- aci-api.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/aci-api.go b/aci-api.go index 5fff373..49cdb9e 100644 --- a/aci-api.go +++ b/aci-api.go @@ -141,8 +141,15 @@ func (p aciAPI) CollectMetrics() (string, []MetricDefinition, error) { } end := time.Since(start) + + if metrics == nil { + // if no metrics are returned the apic or node may be down + metrics = append(metrics, *p.up(0.0)) + } else { + metrics = append(metrics, *p.up(1.0)) + } + metrics = append(metrics, *p.scrape(end.Seconds())) - metrics = append(metrics, *p.up(1.0)) log.WithFields(log.Fields{ LogFieldRequestID: p.ctx.Value(LogFieldRequestID), LogFieldExecTime: end.Microseconds(), From deb7ee81ddeffc50b2ff9459edf010fea6487337 Mon Sep 17 00:00:00 2001 From: andersh Date: Mon, 11 Nov 2024 11:40:12 +0100 Subject: [PATCH 3/3] docs: in discovery the query parameter is target and not fabric --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e57944f..c455bf7 100644 --- a/README.md +++ b/README.md @@ -449,7 +449,7 @@ to scrape. ## Service discovery The service discovery is exposed on the `/sd` endpoint where the query parameter `target` is the name of fabric in the -`config.yml` file, e.g. `'http://localhost:9643/sd?fabric=xyz'`. The output can look like this: +`config.yml` file, e.g. `'http://localhost:9643/sd?target=xyz'`. The output can look like this: ```json ....