Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit 44e3b54

Browse files
committed
Keystone Identity /v3/role_assignments
1 parent 1d8b6f1 commit 44e3b54

File tree

6 files changed

+224
-0
lines changed

6 files changed

+224
-0
lines changed

openstack/identity/v3/roles/doc.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Package roles provides information and interaction with the roles API
2+
// resource for the OpenStack Identity service.
3+
package roles
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package roles
2+
3+
import (
4+
"github.com/rackspace/gophercloud"
5+
"github.com/rackspace/gophercloud/pagination"
6+
)
7+
8+
// RoleAssignmentsOpts allows you to query the RoleAssignments method.
9+
type RoleAssignmentsOpts struct {
10+
GroupId string `q:"group.id"`
11+
RoleId string `q:"role.id"`
12+
ScopeDomainId string `q:"scope.domain.id"`
13+
ScopeProjectId string `q:"scope.project.id"`
14+
UserId string `q:"user.id"`
15+
Effective bool `q:"effective"`
16+
}
17+
18+
// RoleAssignments enumerates the roles assigned to a specified resource.
19+
func RoleAssignments(client *gophercloud.ServiceClient, opts RoleAssignmentsOpts) pagination.Pager {
20+
u := roleAssignmentsURL(client)
21+
q, err := gophercloud.BuildQueryString(opts)
22+
if err != nil {
23+
return pagination.Pager{Err: err}
24+
}
25+
u += q.String()
26+
createPage := func(r pagination.PageResult) pagination.Page {
27+
return RoleAssignmentsPage{pagination.LinkedPageBase{PageResult: r}}
28+
}
29+
30+
return pagination.NewPager(client, u, createPage)
31+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package roles
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"reflect"
7+
"testing"
8+
9+
"github.com/rackspace/gophercloud/pagination"
10+
"github.com/rackspace/gophercloud/testhelper"
11+
"github.com/rackspace/gophercloud/testhelper/client"
12+
)
13+
14+
func TestListSinglePage(t *testing.T) {
15+
testhelper.SetupHTTP()
16+
defer testhelper.TeardownHTTP()
17+
18+
testhelper.Mux.HandleFunc("/role_assignments", func(w http.ResponseWriter, r *http.Request) {
19+
testhelper.TestMethod(t, r, "GET")
20+
testhelper.TestHeader(t, r, "X-Auth-Token", client.TokenID)
21+
22+
w.Header().Add("Content-Type", "application/json")
23+
fmt.Fprintf(w, `
24+
{
25+
"role_assignments": [
26+
{
27+
"links": {
28+
"assignment": "http://identity:35357/v3/domains/161718/users/313233/roles/123456"
29+
},
30+
"role": {
31+
"id": "123456"
32+
},
33+
"scope": {
34+
"domain": {
35+
"id": "161718"
36+
}
37+
},
38+
"user": {
39+
"id": "313233"
40+
}
41+
},
42+
{
43+
"links": {
44+
"assignment": "http://identity:35357/v3/projects/456789/groups/101112/roles/123456",
45+
"membership": "http://identity:35357/v3/groups/101112/users/313233"
46+
},
47+
"role": {
48+
"id": "123456"
49+
},
50+
"scope": {
51+
"project": {
52+
"id": "456789"
53+
}
54+
},
55+
"user": {
56+
"id": "313233"
57+
}
58+
}
59+
],
60+
"links": {
61+
"self": "http://identity:35357/v3/role_assignments?effective",
62+
"previous": null,
63+
"next": null
64+
}
65+
}
66+
`)
67+
})
68+
69+
count := 0
70+
err := RoleAssignments(client.ServiceClient(), RoleAssignmentsOpts{}).EachPage(func(page pagination.Page) (bool, error) {
71+
count++
72+
actual, err := ExtractRoleAssignments(page)
73+
if err != nil {
74+
return false, err
75+
}
76+
77+
expected := []RoleAssignment{
78+
RoleAssignment{
79+
Role: &Role{ID: "123456"},
80+
Scope: &Scope{Domain: &Domain{ID: "161718"}},
81+
User: &User{ID: "313233"},
82+
Group: nil,
83+
},
84+
RoleAssignment{
85+
Role: &Role{ID: "123456"},
86+
Scope: &Scope{Project: &Project{ID: "456789"}},
87+
User: &User{ID: "313233"},
88+
Group: nil,
89+
},
90+
}
91+
92+
if !reflect.DeepEqual(expected, actual) {
93+
t.Errorf("Expected %#v, got %#v", expected, actual)
94+
}
95+
96+
return true, nil
97+
})
98+
if err != nil {
99+
t.Errorf("Unexpected error while paging: %v", err)
100+
}
101+
if count != 1 {
102+
t.Errorf("Expected 1 page, got %d", count)
103+
}
104+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package roles
2+
3+
import (
4+
"github.com/rackspace/gophercloud/pagination"
5+
6+
"github.com/mitchellh/mapstructure"
7+
)
8+
9+
// RoleAssignment is the result of a role assignments query.
10+
type RoleAssignment struct {
11+
Role *Role `json:"role,omitempty"`
12+
Scope *Scope `json:"scope,omitempty"`
13+
User *User `json:"user,omitempty"`
14+
Group *Group `json:"group,omitempty"`
15+
}
16+
17+
type Role struct {
18+
ID string `json:"id,omitempty"`
19+
}
20+
21+
type Scope struct {
22+
Domain *Domain `json:"domain,omitempty"`
23+
Project *Project `json:"domain,omitempty"`
24+
}
25+
26+
type Domain struct {
27+
ID string `json:"id,omitempty"`
28+
}
29+
30+
type Project struct {
31+
ID string `json:"id,omitempty"`
32+
}
33+
34+
type User struct {
35+
ID string `json:"id,omitempty"`
36+
}
37+
38+
type Group struct {
39+
ID string `json:"id,omitempty"`
40+
}
41+
42+
// RoleAssignmentsPage is a single page of RoleAssignments results.
43+
type RoleAssignmentsPage struct {
44+
pagination.LinkedPageBase
45+
}
46+
47+
// IsEmpty returns true if the page contains no results.
48+
func (p RoleAssignmentsPage) IsEmpty() (bool, error) {
49+
roleAssignments, err := ExtractRoleAssignments(p)
50+
if err != nil {
51+
return true, err
52+
}
53+
return len(roleAssignments) == 0, nil
54+
}
55+
56+
// ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection acquired from List.
57+
func ExtractRoleAssignments(page pagination.Page) ([]RoleAssignment, error) {
58+
var response struct {
59+
RoleAssignments []RoleAssignment `mapstructure:"role_assignments"`
60+
}
61+
62+
err := mapstructure.Decode(page.(RoleAssignmentsPage).Body, &response)
63+
return response.RoleAssignments, err
64+
}

openstack/identity/v3/roles/urls.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package roles
2+
3+
import "github.com/rackspace/gophercloud"
4+
5+
func roleAssignmentsURL(client *gophercloud.ServiceClient) string {
6+
return client.ServiceURL("role_assignments")
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package roles
2+
3+
import (
4+
"testing"
5+
6+
"github.com/rackspace/gophercloud"
7+
)
8+
9+
func TestRoleAssignmentsURL(t *testing.T) {
10+
client := gophercloud.ServiceClient{Endpoint: "http://localhost:5000/v3/"}
11+
url := roleAssignmentsURL(&client)
12+
if url != "http://localhost:5000/v3/role_assignments" {
13+
t.Errorf("Unexpected list URL generated: [%s]", url)
14+
}
15+
}

0 commit comments

Comments
 (0)