Adding List for Roles

Change-Id: Idea3ec6f3c7d74c4b754c4c143199a58a4855738
diff --git a/openstack/identity/v3/roles/requests.go b/openstack/identity/v3/roles/requests.go
index 8d701c0..3d7c179 100644
--- a/openstack/identity/v3/roles/requests.go
+++ b/openstack/identity/v3/roles/requests.go
@@ -5,6 +5,14 @@
 	"gerrit.mcp.mirantis.net/debian/gophercloud.git/pagination"
 )
 
+
+func List(client *gophercloud.ServiceClient) pagination.Pager {
+	url := listURL(client)
+	return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
+		return RolePage{pagination.LinkedPageBase{PageResult: r}}
+	})
+}
+
 // ListAssignmentsOptsBuilder allows extensions to add additional parameters to
 // the ListAssignments request.
 type ListAssignmentsOptsBuilder interface {
diff --git a/openstack/identity/v3/roles/results.go b/openstack/identity/v3/roles/results.go
index b32567b..9439ea9 100644
--- a/openstack/identity/v3/roles/results.go
+++ b/openstack/identity/v3/roles/results.go
@@ -40,6 +40,10 @@
 	pagination.LinkedPageBase
 }
 
+type RolePage struct {
+	pagination.LinkedPageBase
+}
+
 // IsEmpty returns true if the page contains no results.
 func (r RoleAssignmentPage) IsEmpty() (bool, error) {
 	roleAssignments, err := ExtractRoleAssignments(r)
@@ -65,3 +69,10 @@
 	err := (r.(RoleAssignmentPage)).ExtractInto(&s)
 	return s.RoleAssignments, err
 }
+func ExtractRoles(r pagination.Page) ([]Role, error) {
+	var s struct {
+		Roles []Role`json:"roles"`
+	}
+	err := (r.(RolePage)).ExtractInto(&s)
+	return s.Roles, err
+}
diff --git a/openstack/identity/v3/roles/urls.go b/openstack/identity/v3/roles/urls.go
index 1699617..da9ee77 100644
--- a/openstack/identity/v3/roles/urls.go
+++ b/openstack/identity/v3/roles/urls.go
@@ -5,3 +5,7 @@
 func listAssignmentsURL(client *gophercloud.ServiceClient) string {
 	return client.ServiceURL("role_assignments")
 }
+
+func listURL(client *gophercloud.ServiceClient) string{
+    return client.ServiceURL("roles")
+}