Skip to content

Commit 655166f

Browse files
authored
Merge pull request grafana#151 from skatsaounis/add-get-roles
Add GetRoles call to fetch all Grafana roles
2 parents e5fb6a3 + 2081248 commit 655166f

File tree

2 files changed

+110
-7
lines changed

2 files changed

+110
-7
lines changed

role.go

+27
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package gapi
33
import (
44
"encoding/json"
55
"fmt"
6+
"net/url"
67
)
78

89
type Role struct {
@@ -22,6 +23,32 @@ type Permission struct {
2223
Scope string `json:"scope"`
2324
}
2425

26+
// GetRole fetches and returns Grafana roles. Available only in Grafana Enterprise 8.+.
27+
func (c *Client) GetRoles() ([]Role, error) {
28+
const limit = 1000
29+
var (
30+
page = 0
31+
newRoles []Role
32+
roles []Role
33+
query = make(url.Values)
34+
)
35+
query.Set("limit", fmt.Sprint(limit))
36+
for {
37+
page++
38+
query.Set("page", fmt.Sprint(page))
39+
40+
if err := c.request("GET", "/api/access-control/roles", query, nil, &newRoles); err != nil {
41+
return nil, err
42+
}
43+
44+
roles = append(roles, newRoles...)
45+
46+
if len(newRoles) < limit {
47+
return roles, nil
48+
}
49+
}
50+
}
51+
2552
// GetRole gets a role with permissions for the given UID. Available only in Grafana Enterprise 8.+.
2653
func (c *Client) GetRole(uid string) (*Role, error) {
2754
r := &Role{}

role_test.go

+83-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gapi
22

33
import (
4+
"strings"
45
"testing"
56

67
"github.com/gobs/pretty"
@@ -55,8 +56,86 @@ const (
5556

5657
updatedRoleResponse = `{"message":"Role updated"}`
5758
deleteRoleResponse = `{"message":"Role deleted"}`
59+
60+
roleUID = "vc3SCSsGz"
5861
)
5962

63+
func TestRoles(t *testing.T) {
64+
mockData := strings.Repeat(getRoleResponse+",", 1000) // make 1000 roles.
65+
mockData = "[" + mockData[:len(mockData)-1] + "]" // remove trailing comma; make a json list.
66+
67+
// This creates 1000 + 1000 + 1 (2001, 3 calls) worth of roles.
68+
client := gapiTestToolsFromCalls(t, []mockServerCall{
69+
{200, mockData},
70+
{200, mockData},
71+
{200, "[" + getRoleResponse + "]"},
72+
})
73+
74+
const dashCount = 2001
75+
76+
roles, err := client.GetRoles()
77+
if err != nil {
78+
t.Fatal(err)
79+
}
80+
81+
t.Log(pretty.PrettyFormat(roles))
82+
83+
if len(roles) != dashCount {
84+
t.Fatalf("Length of returned roles should be %d", dashCount)
85+
}
86+
if roles[0].UID != roleUID || roles[0].Name != "test:policy" {
87+
t.Error("Not correctly parsing returned roles.")
88+
}
89+
if roles[dashCount-1].UID != roleUID || roles[dashCount-1].Name != "test:policy" {
90+
t.Error("Not correctly parsing returned roles.")
91+
}
92+
}
93+
94+
func TestRolesZeroResults(t *testing.T) {
95+
// This return zero roles.
96+
client := gapiTestToolsFromCalls(t, []mockServerCall{
97+
{200, "[]"},
98+
})
99+
100+
roles, err := client.GetRoles()
101+
if err != nil {
102+
t.Fatal(err)
103+
}
104+
105+
if len(roles) != 0 {
106+
t.Errorf("Length of returned roles should be zero")
107+
}
108+
}
109+
110+
func TestRolesSinglePage(t *testing.T) {
111+
mockData := strings.Repeat(getRoleResponse+",", 999) // make 999 roles.
112+
mockData = "[" + mockData[:len(mockData)-1] + "]" // remove trailing comma; make a json list.
113+
114+
// This creates 999 worth of roles.
115+
client := gapiTestToolsFromCalls(t, []mockServerCall{
116+
{200, mockData},
117+
})
118+
119+
const dashCount = 999
120+
121+
roles, err := client.GetRoles()
122+
if err != nil {
123+
t.Fatal(err)
124+
}
125+
126+
t.Log(pretty.PrettyFormat(roles))
127+
128+
if len(roles) != dashCount {
129+
t.Fatalf("Length of returned roles should be %d", dashCount)
130+
}
131+
if roles[0].UID != roleUID || roles[0].Name != "test:policy" {
132+
t.Error("Not correctly parsing returned roles.")
133+
}
134+
if roles[dashCount-1].UID != roleUID || roles[dashCount-1].Name != "test:policy" {
135+
t.Error("Not correctly parsing returned roles.")
136+
}
137+
}
138+
60139
func TestNewRole(t *testing.T) {
61140
client := gapiTestTools(t, 201, newRoleResponse)
62141

@@ -79,26 +158,23 @@ func TestNewRole(t *testing.T) {
79158

80159
t.Log(pretty.PrettyFormat(resp))
81160

82-
if resp.UID != "vc3SCSsGz" {
161+
if resp.UID != roleUID {
83162
t.Error("Not correctly parsing returned role uid.")
84163
}
85164
}
86165

87166
func TestGetRole(t *testing.T) {
88167
client := gapiTestTools(t, 200, getRoleResponse)
89168

90-
uid := "vc3SCSsGz"
91-
92-
resp, err := client.GetRole(uid)
93-
169+
resp, err := client.GetRole(roleUID)
94170
if err != nil {
95171
t.Error(err)
96172
}
97173

98174
expected := Role{
99175
Global: false,
100176
Version: 1,
101-
UID: "vc3SCSsGz",
177+
UID: roleUID,
102178
Name: "test:policy",
103179
Description: "Test policy description",
104180
Group: "test group",
@@ -143,7 +219,7 @@ func TestUpdateRole(t *testing.T) {
143219
func TestDeleteRole(t *testing.T) {
144220
client := gapiTestTools(t, 200, deleteRoleResponse)
145221

146-
err := client.DeleteRole("vc3SCSsGz", false)
222+
err := client.DeleteRole(roleUID, false)
147223
if err != nil {
148224
t.Error(err)
149225
}

0 commit comments

Comments
 (0)