@cryptotaxi247 / netdata-1 / commits / 8ff7503a9

fix(go.d/rabbitmq): handle insufficient perms when querying definitions (#19277)

Ilya Mashchenko committed Dec 23, 2024 at 16:06 UTC 8ff7503a9f920e1740eaffe503903bc95a2f4a12
6 files changed +48 -7
src/go/plugin/go.d/collector/rabbitmq/collect.go
+23 -2
@@ -6,17 +6,19 @@ import (
6 "encoding/json"
7 "fmt"
8 "net/http"
9 + "slices"
10 "strings"
11
12 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
13 )
14
15 func (c *Collector) collect() (map[string]int64, error) {
15 - if c.clusterName == "" {
16 + if c.queryClusterMeta {
17 id, name, err := c.getClusterMeta()
18 if err != nil {
19 return nil, err
20 }
21 + c.queryClusterMeta = false
22 c.clusterId = id
23 c.clusterName = name
24 }
@@ -46,7 +48,26 @@ func (c *Collector) collect() (map[string]int64, error) {
48 }
49
50 func (c *Collector) getClusterMeta() (id string, name string, err error) {
49 - req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathAPIDefinitions)
51 + req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathAPIWhoami)
52 + if err != nil {
53 + return "", "", fmt.Errorf("failed to create whoami request: %w", err)
54 + }
55 +
56 + var user apiWhoamiResp
57 + if err := c.webClient().RequestJSON(req, &user); err != nil {
58 + return "", "", fmt.Errorf("failed to send whoami request: %w", err)
59 + }
60 +
61 + if user.Name == "" {
62 + return "", "", fmt.Errorf("unexpected response: whoami: user name n is empty")
63 + }
64 +
65 + if !slices.Contains(user.Tags, "administrator") {
66 + c.Warningf("user %s lacks 'administrator' tag: cluster ID and name cannot be collected.", user.Name)
67 + return "", "", nil
68 + }
69 +
70 + req, err = web.NewHTTPRequestWithPath(c.RequestConfig, urlPathAPIDefinitions)
71 if err != nil {
72 return "", "", fmt.Errorf("failed to create definitions request: %w", err)
73 }
src/go/plugin/go.d/collector/rabbitmq/collect_nodes.go
+1
@@ -4,6 +4,7 @@ package rabbitmq
4
5 import (
6 "fmt"
7 +
8 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/metrix"
9
10 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"
src/go/plugin/go.d/collector/rabbitmq/collector.go
+7 -5
@@ -42,8 +42,9 @@ func New() *Collector {
42 CollectQueues: false,
43 },
44
45 - charts: &module.Charts{},
46 - cache: newCache(),
45 + charts: &module.Charts{},
46 + cache: newCache(),
47 + queryClusterMeta: true,
48 }
49 }
50
@@ -62,9 +63,10 @@ type Collector struct {
63
64 httpClient *http.Client
65
65 - clusterName string
66 - clusterId string
67 - cache *cache
66 + queryClusterMeta bool
67 + clusterName string
68 + clusterId string
69 + cache *cache
70 }
71
72 func (c *Collector) Configuration() any {
src/go/plugin/go.d/collector/rabbitmq/collector_test.go
+4
@@ -20,6 +20,7 @@ var (
20 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
21 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
22
23 + dataClusterWhoami, _ = os.ReadFile("testdata/v4.0.3/cluster/whoami.json")
24 dataClusterDefinitions, _ = os.ReadFile("testdata/v4.0.3/cluster/definitions.json")
25 dataClusterOverview, _ = os.ReadFile("testdata/v4.0.3/cluster/overview.json")
26 dataClusterNodes, _ = os.ReadFile("testdata/v4.0.3/cluster/nodes.json")
@@ -31,6 +32,7 @@ func Test_testDataIsValid(t *testing.T) {
32 for name, data := range map[string][]byte{
33 "dataConfigJSON": dataConfigJSON,
34 "dataConfigYAML": dataConfigYAML,
35 + "dataClusterWhoami": dataClusterWhoami,
36 "dataClusterDefinitions": dataClusterDefinitions,
37 "dataClusterOverview": dataClusterOverview,
38 "dataClusterNodes": dataClusterNodes,
@@ -379,6 +381,8 @@ func caseClusterOk() (*Collector, func()) {
381 http.HandlerFunc(
382 func(w http.ResponseWriter, r *http.Request) {
383 switch r.URL.Path {
384 + case urlPathAPIWhoami:
385 + _, _ = w.Write(dataClusterWhoami)
386 case urlPathAPIDefinitions:
387 _, _ = w.Write(dataClusterDefinitions)
388 case urlPathAPIOverview:
src/go/plugin/go.d/collector/rabbitmq/restapi.go
+6
@@ -3,6 +3,7 @@
3 package rabbitmq
4
5 const (
6 + urlPathAPIWhoami = "/api/whoami"
7 urlPathAPIDefinitions = "/api/definitions"
8 urlPathAPIOverview = "/api/overview"
9 urlPathAPINodes = "/api/nodes"
@@ -10,6 +11,11 @@ const (
11 urlPathAPIQueues = "/api/queues"
12 )
13
14 +type apiWhoamiResp struct {
15 + Name string `json:"name"`
16 + Tags []string `json:"tags"`
17 +}
18 +
19 type apiDefinitionsResp struct {
20 RabbitmqVersion string `json:"rabbitmq_version"`
21 GlobalParams []struct {
src/go/plugin/go.d/collector/rabbitmq/testdata/v4.0.3/cluster/whoami.json new
+7
@@ -0,0 +1,7 @@
1 +{
2 + "name": "guest",
3 + "tags": [
4 + "administrator"
5 + ],
6 + "is_internal_user": true
7 +}