master
go 109 lines 2.18 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package ceph
4
5 import (
6 "encoding/json"
7 "errors"
8 "fmt"
9 "net/http"
10 "slices"
11
12 "github.com/netdata/netdata/go/plugins/pkg/web"
13 )
14
15 const precision = 1000
16
17 func (c *Collector) collect() (map[string]int64, error) {
18 mx := make(map[string]int64)
19
20 if err := c.auth(); err != nil {
21 return nil, err
22 }
23
24 if c.fsid == "" {
25 fsid, err := c.getFsid()
26 if err != nil {
27 return nil, fmt.Errorf("failed to get fsid: %v", err)
28 }
29 c.fsid = fsid
30 c.addClusterChartsOnce.Do(c.addClusterCharts)
31 }
32
33 if err := c.collectHealth(mx); err != nil {
34 return nil, fmt.Errorf("failed to collect health: %v", err)
35 }
36 if err := c.collectOsds(mx); err != nil {
37 return nil, fmt.Errorf("failed to collect osds: %v", err)
38 }
39 if err := c.collectPools(mx); err != nil {
40 return nil, fmt.Errorf("failed to collect pools: %v", err)
41 }
42
43 return mx, nil
44 }
45
46 func (c *Collector) auth() error {
47 if c.token != "" {
48 ok, err := c.authCheck()
49 if err != nil {
50 return err
51 }
52 if ok {
53 return nil
54 }
55 c.token = ""
56 }
57
58 tok, err := c.authLogin()
59 if err != nil {
60 return err
61 }
62 c.token = tok
63
64 return nil
65 }
66
67 func (c *Collector) getFsid() (string, error) {
68 req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiMonitor)
69 if err != nil {
70 return "", err
71 }
72
73 req.Header.Set("Accept", hdrAcceptVersion)
74 req.Header.Set("Content-Type", hdrContentTypeJson)
75 req.Header.Set("Authorization", "Bearer "+c.token)
76
77 var resp struct {
78 MonStatus struct {
79 MonMap struct {
80 FSID string `json:"fsid"`
81 } `json:"monmap"`
82 } `json:"mon_status"`
83 }
84
85 if err := c.webClient().RequestJSON(req, &resp); err != nil {
86 return "", err
87 }
88
89 if resp.MonStatus.MonMap.FSID == "" {
90 return "", errors.New("no fsid")
91 }
92
93 return resp.MonStatus.MonMap.FSID, nil
94 }
95
96 func (c *Collector) webClient(statusCodes ...int) *web.Client {
97 return web.DoHTTP(c.httpClient).OnNokCode(func(resp *http.Response) (bool, error) {
98 if slices.Contains(statusCodes, resp.StatusCode) {
99 return true, nil
100 }
101 var msg struct {
102 Detail string `json:"detail"`
103 }
104 if err := json.NewDecoder(resp.Body).Decode(&msg); err == nil && msg.Detail != "" {
105 return false, errors.New(msg.Detail)
106 }
107 return false, nil
108 })
109 }