Skip to content
This repository was archived by the owner on Jan 15, 2024. It is now read-only.

Commit 4568268

Browse files
authored
Merge branch 'master' into alexweav/alerting-templates
2 parents 68093c5 + 6ee7f30 commit 4568268

File tree

4 files changed

+335
-4
lines changed

4 files changed

+335
-4
lines changed

api_key_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
)
88

99
const (
10-
createAPIKeyJSON = `{"name":"key-name", "key":"mock-api-key"}`
11-
deleteAPIKeyJSON = `{"message":"API key deleted"}`
10+
createAPIKeyJSON = `{"name":"key-name", "key":"mock-api-key"}` //#nosec
11+
deleteAPIKeyJSON = `{"message":"API key deleted"}` //#nosec
1212

1313
getAPIKeysJSON = `[
1414
{
@@ -22,7 +22,7 @@ const (
2222
"role": "Admin",
2323
"expiration": "2021-10-30T10:52:03+03:00"
2424
}
25-
]`
25+
]` //#nosec
2626
)
2727

2828
func TestCreateAPIKey(t *testing.T) {

playlist_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestPlaylistCreateAndUpdate(t *testing.T) {
4545
Name: "my playlist",
4646
Interval: "5m",
4747
Items: []PlaylistItem{
48-
PlaylistItem{},
48+
{},
4949
},
5050
}
5151

service_account.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package gapi
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"net/http"
8+
"time"
9+
)
10+
11+
// CreateServiceAccountTokenRequest represents the request body for creating a new service account token.
12+
type CreateServiceAccountTokenRequest struct {
13+
Name string `json:"name"`
14+
ServiceAccountID int64 `json:"-"`
15+
SecondsToLive int64 `json:"secondsToLive,omitempty"`
16+
}
17+
18+
// CreateServiceAccountRequest is the request body for creating a new service account.
19+
type CreateServiceAccountRequest struct {
20+
Name string `json:"name"`
21+
}
22+
23+
// UpdateServiceAccountRequest is the request body for modifying a service account.
24+
type UpdateServiceAccountRequest struct {
25+
Name string `json:"name,omitempty"`
26+
Role string `json:"role,omitempty"`
27+
IsDisabled *bool `json:"isDisabled,omitempty"`
28+
}
29+
30+
// ServiceAccountDTO represents a Grafana service account.
31+
type ServiceAccountDTO struct {
32+
ID int64 `json:"id"`
33+
Name string `json:"name"`
34+
Login string `json:"login"`
35+
OrgID int64 `json:"orgId"`
36+
IsDisabled bool `json:"isDisabled"`
37+
Role string `json:"role"`
38+
Tokens int64 `json:"tokens"`
39+
AvatarURL string `json:"avatarUrl"`
40+
}
41+
42+
type RetrieveServiceAccountResponse struct {
43+
TotalCount int64 `json:"totalCount"`
44+
ServiceAccounts []ServiceAccountDTO `json:"serviceAccounts"`
45+
Page int64 `json:"page"`
46+
PerPage int64 `json:"perPage"`
47+
}
48+
49+
// CreateServiceAccountTokenResponse represents the response
50+
// from the Grafana API when creating a service account token.
51+
type CreateServiceAccountTokenResponse struct {
52+
ID int64 `json:"id"`
53+
Name string `json:"name"`
54+
Key string `json:"key"`
55+
}
56+
57+
// GetServiceAccountTokensResponse represents a Grafana service account token.
58+
type GetServiceAccountTokensResponse struct {
59+
ID int64 `json:"id"`
60+
Name string `json:"name"`
61+
Created time.Time `json:"created,omitempty"`
62+
Expiration *time.Time `json:"expiration,omitempty"`
63+
SecondsUntilExpiration *float64 `json:"secondsUntilExpiration,omitempty"`
64+
HasExpired bool `json:"hasExpired,omitempty"`
65+
}
66+
67+
// DeleteServiceAccountResponse represents the response from deleting a service account
68+
// or a service account token.
69+
type DeleteServiceAccountResponse struct {
70+
Message string `json:"message"`
71+
}
72+
73+
// CreateServiceAccount creates a new Grafana service account.
74+
func (c *Client) CreateServiceAccount(request CreateServiceAccountRequest) (*ServiceAccountDTO, error) {
75+
response := ServiceAccountDTO{}
76+
77+
data, err := json.Marshal(request)
78+
if err != nil {
79+
return nil, err
80+
}
81+
82+
err = c.request(http.MethodPost, "/api/serviceaccounts/", nil, bytes.NewBuffer(data), &response)
83+
return &response, err
84+
}
85+
86+
// CreateServiceAccountToken creates a new Grafana service account token.
87+
func (c *Client) CreateServiceAccountToken(request CreateServiceAccountTokenRequest) (*CreateServiceAccountTokenResponse, error) {
88+
response := CreateServiceAccountTokenResponse{}
89+
90+
data, err := json.Marshal(request)
91+
if err != nil {
92+
return nil, err
93+
}
94+
95+
err = c.request(http.MethodPost,
96+
fmt.Sprintf("/api/serviceaccounts/%d/tokens", request.ServiceAccountID),
97+
nil, bytes.NewBuffer(data), &response)
98+
return &response, err
99+
}
100+
101+
// UpdateServiceAccount updates a specific serviceAccountID
102+
func (c *Client) UpdateServiceAccount(serviceAccountID int64, request UpdateServiceAccountRequest) (*ServiceAccountDTO, error) {
103+
response := ServiceAccountDTO{}
104+
105+
data, err := json.Marshal(request)
106+
if err != nil {
107+
return nil, err
108+
}
109+
110+
err = c.request(http.MethodPatch,
111+
fmt.Sprintf("/api/serviceaccounts/%d", serviceAccountID),
112+
nil, bytes.NewBuffer(data), &response)
113+
return &response, err
114+
}
115+
116+
// GetServiceAccounts retrieves a list of all service accounts for the organization.
117+
func (c *Client) GetServiceAccounts() ([]ServiceAccountDTO, error) {
118+
response := RetrieveServiceAccountResponse{}
119+
120+
if err := c.request(http.MethodGet, "/api/serviceaccounts/search", nil, nil, &response); err != nil {
121+
return nil, err
122+
}
123+
124+
return response.ServiceAccounts, nil
125+
}
126+
127+
// GetServiceAccountTokens retrieves a list of all service account tokens for a specific service account.
128+
func (c *Client) GetServiceAccountTokens(serviceAccountID int64) ([]GetServiceAccountTokensResponse, error) {
129+
response := make([]GetServiceAccountTokensResponse, 0)
130+
131+
err := c.request(http.MethodGet,
132+
fmt.Sprintf("/api/serviceaccounts/%d/tokens", serviceAccountID),
133+
nil, nil, &response)
134+
return response, err
135+
}
136+
137+
// DeleteServiceAccount deletes the Grafana service account with the specified ID.
138+
func (c *Client) DeleteServiceAccount(serviceAccountID int64) (*DeleteServiceAccountResponse, error) {
139+
response := DeleteServiceAccountResponse{}
140+
141+
path := fmt.Sprintf("/api/serviceaccounts/%d", serviceAccountID)
142+
err := c.request(http.MethodDelete, path, nil, nil, &response)
143+
return &response, err
144+
}
145+
146+
// DeleteServiceAccountToken deletes the Grafana service account token with the specified ID.
147+
func (c *Client) DeleteServiceAccountToken(serviceAccountID, tokenID int64) (*DeleteServiceAccountResponse, error) {
148+
response := DeleteServiceAccountResponse{}
149+
150+
path := fmt.Sprintf("/api/serviceaccounts/%d/tokens/%d", serviceAccountID, tokenID)
151+
err := c.request(http.MethodDelete, path, nil, nil, &response)
152+
return &response, err
153+
}

service_account_test.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package gapi
2+
3+
import (
4+
"net/http"
5+
"testing"
6+
7+
"github.com/gobs/pretty"
8+
)
9+
10+
const (
11+
serviceAccountJSON = `{
12+
"id": 8,
13+
"name": "newSA",
14+
"login": "sa-newsa",
15+
"orgId": 1,
16+
"isDisabled": false,
17+
"role": "",
18+
"tokens": 0,
19+
"avatarUrl": ""
20+
}`
21+
searchServiceAccountsJSON = `{
22+
"totalCount": 2,
23+
"serviceAccounts": [
24+
{
25+
"id": 8,
26+
"name": "newSA",
27+
"login": "sa-newsa",
28+
"orgId": 1,
29+
"isDisabled": false,
30+
"role": "",
31+
"tokens": 1,
32+
"avatarUrl": "/avatar/0e94f33c929884a5163d953582f27fec"
33+
},
34+
{
35+
"id": 9,
36+
"name": "newnewSA",
37+
"login": "sa-newnewsa",
38+
"orgId": 1,
39+
"isDisabled": true,
40+
"role": "Admin",
41+
"tokens": 2,
42+
"avatarUrl": "/avatar/0e29f33c929824a5163d953582e83abe"
43+
}
44+
],
45+
"page": 1,
46+
"perPage": 1000
47+
}`
48+
createServiceAccountTokenJSON = `{"name":"key-name", "key":"mock-api-key"}` //#nosec
49+
deleteServiceAccountTokenJSON = `{"message":"Service account token deleted"}` //#nosec
50+
deleteServiceAccountJSON = `{"message":"service account deleted"}`
51+
52+
getServiceAccountTokensJSON = `[
53+
{
54+
"id": 4,
55+
"name": "testToken",
56+
"created": "2022-06-15T15:19:00+02:00",
57+
"expiration": "2022-06-15T16:17:20+02:00",
58+
"secondsUntilExpiration": 3412.443626017,
59+
"hasExpired": false
60+
},
61+
{
62+
"id": 1,
63+
"name": "testToken2",
64+
"created": "2022-01-15T15:19:00+02:00",
65+
"expiration": "2022-02-15T16:17:20+02:00",
66+
"secondsUntilExpiration": 0,
67+
"hasExpired": true
68+
},
69+
{
70+
"id": 6,
71+
"name": "testTokenzx",
72+
"created": "2022-06-15T15:39:54+02:00",
73+
"expiration": null,
74+
"secondsUntilExpiration": 0,
75+
"hasExpired": false
76+
}
77+
]` //#nosec
78+
)
79+
80+
func TestCreateServiceAccountToken(t *testing.T) {
81+
server, client := gapiTestTools(t, http.StatusOK, createServiceAccountTokenJSON)
82+
defer server.Close()
83+
84+
req := CreateServiceAccountTokenRequest{
85+
Name: "key-name",
86+
SecondsToLive: 0,
87+
}
88+
89+
res, err := client.CreateServiceAccountToken(req)
90+
if err != nil {
91+
t.Error(err)
92+
}
93+
94+
t.Log(pretty.PrettyFormat(res))
95+
}
96+
97+
func TestCreateServiceAccount(t *testing.T) {
98+
server, client := gapiTestTools(t, http.StatusOK, serviceAccountJSON)
99+
defer server.Close()
100+
101+
req := CreateServiceAccountRequest{
102+
Name: "newSA",
103+
}
104+
105+
res, err := client.CreateServiceAccount(req)
106+
if err != nil {
107+
t.Error(err)
108+
}
109+
110+
t.Log(pretty.PrettyFormat(res))
111+
}
112+
113+
func TestUpdateServiceAccount(t *testing.T) {
114+
server, client := gapiTestTools(t, http.StatusOK, serviceAccountJSON)
115+
defer server.Close()
116+
117+
isDisabled := false
118+
req := UpdateServiceAccountRequest{
119+
Name: "",
120+
Role: "Admin",
121+
IsDisabled: &isDisabled,
122+
}
123+
124+
res, err := client.UpdateServiceAccount(5, req)
125+
if err != nil {
126+
t.Error(err)
127+
}
128+
129+
t.Log(pretty.PrettyFormat(res))
130+
}
131+
132+
func TestDeleteServiceAccount(t *testing.T) {
133+
server, client := gapiTestTools(t, http.StatusOK, deleteServiceAccountJSON)
134+
defer server.Close()
135+
136+
res, err := client.DeleteServiceAccount(int64(1))
137+
if err != nil {
138+
t.Error(err)
139+
}
140+
141+
t.Log(pretty.PrettyFormat(res))
142+
}
143+
144+
func TestDeleteServiceAccountToken(t *testing.T) {
145+
server, client := gapiTestTools(t, http.StatusOK, deleteServiceAccountTokenJSON)
146+
defer server.Close()
147+
148+
res, err := client.DeleteServiceAccountToken(int64(1), int64(1))
149+
if err != nil {
150+
t.Error(err)
151+
}
152+
153+
t.Log(pretty.PrettyFormat(res))
154+
}
155+
156+
func TestGetServiceAccounts(t *testing.T) {
157+
server, client := gapiTestTools(t, http.StatusOK, searchServiceAccountsJSON)
158+
defer server.Close()
159+
160+
res, err := client.GetServiceAccounts()
161+
if err != nil {
162+
t.Error(err)
163+
}
164+
165+
t.Log(pretty.PrettyFormat(res))
166+
}
167+
168+
func TestGetServiceAccountTokens(t *testing.T) {
169+
server, client := gapiTestTools(t, http.StatusOK, getServiceAccountTokensJSON)
170+
defer server.Close()
171+
172+
res, err := client.GetServiceAccountTokens(5)
173+
if err != nil {
174+
t.Error(err)
175+
}
176+
177+
t.Log(pretty.PrettyFormat(res))
178+
}

0 commit comments

Comments
 (0)