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

Commit

Permalink
Merge pull request #167 from grafana/feat/resource-permissions-methods
Browse files Browse the repository at this point in the history
RBAC assignment methods
  • Loading branch information
Aaron Godin authored Nov 6, 2023
2 parents 6d42666 + fdea1ff commit b041ab2
Show file tree
Hide file tree
Showing 22 changed files with 448 additions and 66 deletions.
2 changes: 1 addition & 1 deletion .drone/drone.jsonnet
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local image = 'grafana/build-container:1.2.27';
local image = 'grafana/build-container:1.7.7';

local pipeline(name, trigger) = {
kind: 'pipeline',
Expand Down
4 changes: 2 additions & 2 deletions .drone/drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ platform:

steps:
- name: test
image: grafana/build-container:1.2.27
image: grafana/build-container:1.7.7
commands:
- make test

Expand All @@ -28,7 +28,7 @@ platform:

steps:
- name: test
image: grafana/build-container:1.2.27
image: grafana/build-container:1.7.7
commands:
- make test

Expand Down
7 changes: 2 additions & 5 deletions .golangci.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
[run]
timeout = "10m"

[linters-settings.golint]
min-confidence = 3

[linters-settings.goconst]
min-len = 5
min-occurrences = 5
Expand All @@ -13,14 +10,13 @@ disable-all = true
enable = [
"bodyclose",
"deadcode",
"depguard",
"dogsled",
"errcheck",
"gochecknoinits",
"goconst",
"gocritic",
"goimports",
"golint",
"revive",
"goprintffuncname",
"gosec",
"gosimple",
Expand Down Expand Up @@ -81,3 +77,4 @@ text = "404"
[[issues.exclude-rules]]
linters = ["misspell"]
text = "Unknwon` is a misspelling of `Unknown"

3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ drone:

test:
go version
golangci-lint --version
golangci-lint run ./...
go run github.com/golangci/golangci-lint/cmd/[email protected] run ./...
go test -cover -race -vet all -mod readonly ./...

2 changes: 1 addition & 1 deletion api_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (
"role": "Admin",
"expiration": "2021-10-30T10:52:03+03:00"
}
]` //#nosec
]` //#nosec
)

func TestCreateAPIKey(t *testing.T) {
Expand Down
3 changes: 1 addition & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/url"
Expand Down Expand Up @@ -112,7 +111,7 @@ func (c *Client) request(method, requestPath string, query url.Values, body []by
}

// read the body (even on non-successful HTTP status codes), as that's what the unit tests expect
bodyContents, err = ioutil.ReadAll(resp.Body)
bodyContents, err = io.ReadAll(resp.Body)
resp.Body.Close() //nolint:errcheck

// if there was an error reading the body, try again
Expand Down
4 changes: 2 additions & 2 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"io"
"net/http"
"net/http/httptest"
"net/url"
Expand Down Expand Up @@ -195,7 +195,7 @@ func TestClient_requestWithRetries(t *testing.T) {

try++

got, err := ioutil.ReadAll(r.Body)
got, err := io.ReadAll(r.Body)
if err != nil {
t.Errorf("retry %d: unexpected error reading body: %v", try, err)
}
Expand Down
4 changes: 2 additions & 2 deletions cloud_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package gapi
import (
"encoding/json"
"fmt"
"io/ioutil"
"io"
"net/http"
)

Expand Down Expand Up @@ -74,7 +74,7 @@ func (c *Client) IsCloudPluginInstalled(stackSlug string, pluginSlug string) (bo
if resp.StatusCode == http.StatusNotFound {
return false, nil
}
bodyContents, err := ioutil.ReadAll(resp.Body)
bodyContents, err := io.ReadAll(resp.Body)
if err != nil {
return false, err
}
Expand Down
53 changes: 53 additions & 0 deletions dashboard_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,56 @@ func (c *Client) UpdateDashboardPermissionsByUID(uid string, items *PermissionIt

return c.request("POST", path, nil, data, nil)
}

func (c *Client) ListDashboardResourcePermissions(uid string) ([]*ResourcePermission, error) {
return c.listResourcePermissions(DashboardsResource, ResourceUID(uid))
}

func (c *Client) SetDashboardResourcePermissions(uid string, body SetResourcePermissionsBody) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissions(DashboardsResource, ResourceUID(uid), body)
}

func (c *Client) SetUserDashboardResourcePermissions(dashboardUID string, userID int64, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
DashboardsResource,
ResourceUID(dashboardUID),
UsersResource,
ResourceID(userID),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
UserID: userID,
Permission: permission,
},
},
)
}

func (c *Client) SetTeamDashboardResourcePermissions(dashboardUID string, teamID int64, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
DashboardsResource,
ResourceUID(dashboardUID),
TeamsResource,
ResourceID(teamID),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
TeamID: teamID,
Permission: permission,
},
},
)
}

func (c *Client) SetBuiltInRoleDashboardResourcePermissions(dashboardUID string, builtInRole string, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
DashboardsResource,
ResourceUID(dashboardUID),
BuiltInRolesResource,
ResourceUID(builtInRole),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
BuiltinRole: builtInRole,
Permission: permission,
},
},
)
}
2 changes: 1 addition & 1 deletion datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func JSONDataWithHeaders(jsonData, secureJSONData map[string]interface{}, header
for name, value := range headers {
jsonData[fmt.Sprintf("httpHeaderName%d", idx)] = name
secureJSONData[fmt.Sprintf("httpHeaderValue%d", idx)] = value
idx += 1
idx++
}

return jsonData, secureJSONData
Expand Down
53 changes: 53 additions & 0 deletions datasource_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,56 @@ func (c *Client) RemoveDatasourcePermission(id, permissionID int64) error {

return nil
}

func (c *Client) ListDatasourceResourcePermissions(uid string) ([]*ResourcePermission, error) {
return c.listResourcePermissions(DatasourcesResource, ResourceUID(uid))
}

func (c *Client) SetDatasourceResourcePermissions(uid string, body SetResourcePermissionsBody) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissions(DatasourcesResource, ResourceUID(uid), body)
}

func (c *Client) SetUserDatasourceResourcePermissions(datasourceUID string, userID int64, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
DatasourcesResource,
ResourceUID(datasourceUID),
UsersResource,
ResourceID(userID),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
UserID: userID,
Permission: permission,
},
},
)
}

func (c *Client) SetTeamDatasourceResourcePermissions(datasourceUID string, teamID int64, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
DatasourcesResource,
ResourceUID(datasourceUID),
TeamsResource,
ResourceID(teamID),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
TeamID: teamID,
Permission: permission,
},
},
)
}

func (c *Client) SetBuiltInRoleDatasourceResourcePermissions(datasourceUID string, builtInRole string, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
DatasourcesResource,
ResourceUID(datasourceUID),
BuiltInRolesResource,
ResourceUID(builtInRole),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
BuiltinRole: builtInRole,
Permission: permission,
},
},
)
}
53 changes: 53 additions & 0 deletions folder_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,56 @@ func (c *Client) UpdateFolderPermissions(fid string, items *PermissionItems) err

return c.request("POST", path, nil, data, nil)
}

func (c *Client) ListFolderResourcePermissions(uid string) ([]*ResourcePermission, error) {
return c.listResourcePermissions(FoldersResource, ResourceUID(uid))
}

func (c *Client) SetFolderResourcePermissions(uid string, body SetResourcePermissionsBody) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissions(FoldersResource, ResourceUID(uid), body)
}

func (c *Client) SetUserFolderResourcePermissions(folderUID string, userID int64, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
FoldersResource,
ResourceUID(folderUID),
UsersResource,
ResourceID(userID),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
UserID: userID,
Permission: permission,
},
},
)
}

func (c *Client) SetTeamFolderResourcePermissions(folderUID string, teamID int64, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
FoldersResource,
ResourceUID(folderUID),
TeamsResource,
ResourceID(teamID),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
TeamID: teamID,
Permission: permission,
},
},
)
}

func (c *Client) SetBuiltInRoleFolderResourcePermissions(folderUID string, builtInRole string, permission string) (*SetResourcePermissionsResponse, error) {
return c.setResourcePermissionByAssignment(
FoldersResource,
ResourceUID(folderUID),
BuiltInRolesResource,
ResourceUID(builtInRole),
SetResourcePermissionBody{
Permission: SetResourcePermissionItem{
BuiltinRole: builtInRole,
Permission: permission,
},
},
)
}
9 changes: 8 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
module github.com/grafana/grafana-api-golang-client

go 1.14
go 1.21

require (
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/stretchr/testify v1.8.4
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA=
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
35 changes: 35 additions & 0 deletions resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package gapi

import (
"fmt"
"strconv"
)

const (
DashboardsResource = "dashboards"
DatasourcesResource = "datasources"
FoldersResource = "folders"
ServiceAccountsResource = "serviceaccounts"
TeamsResource = "teams"
UsersResource = "users"
BuiltInRolesResource = "builtInRoles"
)

// ResourceIdent represents anything that can be considered a resource identifier.
type ResourceIdent interface {
fmt.Stringer
}

// ResourceID wraps `int64` to be a valid `ResourceIdent`
type ResourceID int64

func (id ResourceID) String() string {
return strconv.FormatInt(int64(id), 10)
}

// ResourceUID wraps `string` to be a valid `ResourceIdent`
type ResourceUID string

func (id ResourceUID) String() string {
return string(id)
}
Loading

0 comments on commit b041ab2

Please sign in to comment.