master
go 139 lines 2.86 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package ceph
4
5 import (
6 "bytes"
7 "encoding/json"
8 "errors"
9 "io"
10 "net/http"
11 "net/url"
12
13 "github.com/netdata/netdata/go/plugins/pkg/web"
14 )
15
16 type (
17 authLoginResp struct {
18 Token string `json:"token"`
19 }
20 authCheckResp struct {
21 Username string `json:"username"`
22 Permissions map[string]any `json:"permissions"`
23 }
24 )
25
26 func (c *Collector) authLogin() (string, error) {
27 // https://docs.ceph.com/en/reef/mgr/ceph_api/#post--api-auth
28
29 req, err := func() (*http.Request, error) {
30 var credentials = struct {
31 Username string `json:"username"`
32 Password string `json:"password"`
33 }{
34 Username: c.Username,
35 Password: c.Password,
36 }
37
38 bs, err := json.Marshal(credentials)
39 if err != nil {
40 return nil, err
41 }
42
43 req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiAuth)
44 if err != nil {
45 return nil, err
46 }
47
48 body := bytes.NewReader(bs)
49
50 req.Body = io.NopCloser(body)
51 req.ContentLength = int64(body.Len())
52 req.Method = http.MethodPost
53 req.Header.Set("Accept", hdrAcceptVersion)
54 req.Header.Set("Content-Type", hdrContentTypeJson)
55
56 return req, nil
57 }()
58 if err != nil {
59 return "", err
60 }
61
62 var tok authLoginResp
63
64 if err := c.webClient(201).RequestJSON(req, &tok); err != nil {
65 return "", err
66 }
67
68 if tok.Token == "" {
69 return "", errors.New("empty token")
70 }
71
72 return tok.Token, nil
73 }
74
75 func (c *Collector) authCheck() (bool, error) {
76 // https://docs.ceph.com/en/reef/mgr/ceph_api/#post--api-auth-check
77 if c.token == "" {
78 return false, nil
79 }
80
81 req, err := func() (*http.Request, error) {
82 bs, err := json.Marshal(authLoginResp{Token: c.token})
83 if err != nil {
84 return nil, err
85 }
86
87 req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiAuthCheck)
88 if err != nil {
89 return nil, err
90 }
91
92 body := bytes.NewReader(bs)
93
94 req.Body = io.NopCloser(body)
95 req.ContentLength = int64(body.Len())
96 req.URL.RawQuery = url.Values{"token": {c.token}}.Encode() // TODO: it seems not necessary?
97 req.Method = http.MethodPost
98 req.Header.Set("Accept", hdrAcceptVersion)
99 req.Header.Set("Content-Type", hdrContentTypeJson)
100 return req, nil
101 }()
102 if err != nil {
103 return false, err
104 }
105
106 var resp authCheckResp
107
108 if err := c.webClient().RequestJSON(req, &resp); err != nil {
109 return false, err
110 }
111
112 return resp.Username != "", nil
113 }
114
115 func (c *Collector) authLogout() error {
116 // https://docs.ceph.com/en/reef/mgr/ceph_api/#post--api-auth-logout
117
118 if c.token == "" {
119 return nil
120 }
121 defer func() { c.token = "" }()
122
123 req, err := func() (*http.Request, error) {
124 req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathApiAuthLogout)
125 if err != nil {
126 return nil, err
127 }
128
129 req.Method = http.MethodPost
130 req.Header.Set("Accept", hdrAcceptVersion)
131 req.Header.Set("Authorization", "Bearer "+c.token)
132 return req, nil
133 }()
134 if err != nil {
135 return err
136 }
137
138 return c.webClient().Request(req, nil)
139 }