code styling, paging fix
diff --git a/openstack/identity/v3/roles/requests.go b/openstack/identity/v3/roles/requests.go
index cfa1b38..d95c1e5 100644
--- a/openstack/identity/v3/roles/requests.go
+++ b/openstack/identity/v3/roles/requests.go
@@ -5,8 +5,18 @@
"github.com/rackspace/gophercloud/pagination"
)
-// RoleAssignmentsOpts allows you to query the RoleAssignments method.
-type RoleAssignmentsOpts struct {
+// ListAssignmentsOptsBuilder allows extensions to add additional parameters to
+// the ListAssignments request.
+type ListAssignmentsOptsBuilder interface {
+ ToRolesListAssignmentsQuery() (string, error)
+}
+
+// ListAssignmentsOpts allows you to query the ListAssignments method.
+// Specify one of or a combination of GroupId, RoleId, ScopeDomainId, ScopeProjectId,
+// and/or UserId to search for roles assigned to corresponding entities.
+// Effective lists effective assignments at the user, project, and domain level,
+// allowing for the effects of group membership.
+type ListAssignmentsOpts struct {
GroupId string `q:"group.id"`
RoleId string `q:"role.id"`
ScopeDomainId string `q:"scope.domain.id"`
@@ -15,17 +25,26 @@
Effective bool `q:"effective"`
}
-// RoleAssignments enumerates the roles assigned to a specified resource.
-func RoleAssignments(client *gophercloud.ServiceClient, opts RoleAssignmentsOpts) pagination.Pager {
- u := roleAssignmentsURL(client)
+// ToRolesListAssignmentsQuery formats a ListAssignmentsOpts into a query string.
+func (opts ListAssignmentsOpts) ToRolesListAssignmentsQuery() (string, error) {
q, err := gophercloud.BuildQueryString(opts)
if err != nil {
+ return "", err
+ }
+ return q.String(), nil
+}
+
+// ListAssignments enumerates the roles assigned to a specified resource.
+func ListAssignments(client *gophercloud.ServiceClient, opts ListAssignmentsOptsBuilder) pagination.Pager {
+ url := listAssignmentsURL(client)
+ query, err := opts.ToRolesListAssignmentsQuery()
+ if err != nil {
return pagination.Pager{Err: err}
}
- u += q.String()
+ url += query
createPage := func(r pagination.PageResult) pagination.Page {
return RoleAssignmentsPage{pagination.LinkedPageBase{PageResult: r}}
}
- return pagination.NewPager(client, u, createPage)
+ return pagination.NewPager(client, url, createPage)
}
diff --git a/openstack/identity/v3/roles/requests_test.go b/openstack/identity/v3/roles/requests_test.go
index 3ce88b4..d62dbff 100644
--- a/openstack/identity/v3/roles/requests_test.go
+++ b/openstack/identity/v3/roles/requests_test.go
@@ -67,7 +67,7 @@
})
count := 0
- err := RoleAssignments(client.ServiceClient(), RoleAssignmentsOpts{}).EachPage(func(page pagination.Page) (bool, error) {
+ err := ListAssignments(client.ServiceClient(), ListAssignmentsOpts{}).EachPage(func(page pagination.Page) (bool, error) {
count++
actual, err := ExtractRoleAssignments(page)
if err != nil {
@@ -76,16 +76,16 @@
expected := []RoleAssignment{
RoleAssignment{
- Role: &Role{ID: "123456"},
- Scope: &Scope{Domain: &Domain{ID: "161718"}},
- User: &User{ID: "313233"},
- Group: nil,
+ Role: Role{ID: "123456"},
+ Scope: Scope{Domain: Domain{ID: "161718"}},
+ User: User{ID: "313233"},
+ Group: Group{},
},
RoleAssignment{
- Role: &Role{ID: "123456"},
- Scope: &Scope{Project: &Project{ID: "456789"}},
- User: &User{ID: "313233"},
- Group: nil,
+ Role: Role{ID: "123456"},
+ Scope: Scope{Project: Project{ID: "456789"}},
+ User: User{ID: "313233"},
+ Group: Group{},
},
}
diff --git a/openstack/identity/v3/roles/results.go b/openstack/identity/v3/roles/results.go
index 31cb7a3..d25abd2 100644
--- a/openstack/identity/v3/roles/results.go
+++ b/openstack/identity/v3/roles/results.go
@@ -8,10 +8,10 @@
// RoleAssignment is the result of a role assignments query.
type RoleAssignment struct {
- Role *Role `json:"role,omitempty"`
- Scope *Scope `json:"scope,omitempty"`
- User *User `json:"user,omitempty"`
- Group *Group `json:"group,omitempty"`
+ Role Role `json:"role,omitempty"`
+ Scope Scope `json:"scope,omitempty"`
+ User User `json:"user,omitempty"`
+ Group Group `json:"group,omitempty"`
}
type Role struct {
@@ -19,8 +19,8 @@
}
type Scope struct {
- Domain *Domain `json:"domain,omitempty"`
- Project *Project `json:"domain,omitempty"`
+ Domain Domain `json:"domain,omitempty"`
+ Project Project `json:"domain,omitempty"`
}
type Domain struct {
@@ -53,6 +53,23 @@
return len(roleAssignments) == 0, nil
}
+// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
+func (page RoleAssignmentsPage) NextPageURL() (string, error) {
+ type resp struct {
+ Links struct {
+ Next string `mapstructure:"next"`
+ } `mapstructure:"links"`
+ }
+
+ var r resp
+ err := mapstructure.Decode(page.Body, &r)
+ if err != nil {
+ return "", err
+ }
+
+ return r.Links.Next, nil
+}
+
// ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection acquired from List.
func ExtractRoleAssignments(page pagination.Page) ([]RoleAssignment, error) {
var response struct {
diff --git a/openstack/identity/v3/roles/urls.go b/openstack/identity/v3/roles/urls.go
index 8068ac3..b009340 100644
--- a/openstack/identity/v3/roles/urls.go
+++ b/openstack/identity/v3/roles/urls.go
@@ -2,6 +2,6 @@
import "github.com/rackspace/gophercloud"
-func roleAssignmentsURL(client *gophercloud.ServiceClient) string {
+func listAssignmentsURL(client *gophercloud.ServiceClient) string {
return client.ServiceURL("role_assignments")
}
diff --git a/openstack/identity/v3/roles/urls_test.go b/openstack/identity/v3/roles/urls_test.go
index 8e70e22..04679da 100644
--- a/openstack/identity/v3/roles/urls_test.go
+++ b/openstack/identity/v3/roles/urls_test.go
@@ -6,9 +6,9 @@
"github.com/rackspace/gophercloud"
)
-func TestRoleAssignmentsURL(t *testing.T) {
+func TestListAssignmentsURL(t *testing.T) {
client := gophercloud.ServiceClient{Endpoint: "http://localhost:5000/v3/"}
- url := roleAssignmentsURL(&client)
+ url := listAssignmentsURL(&client)
if url != "http://localhost:5000/v3/role_assignments" {
t.Errorf("Unexpected list URL generated: [%s]", url)
}