Feature/filestorage sharetype list (#143)
* sfs: Add support for share type List
* sfs: Add acceptance tests for share type List
* sfs: Fix unit test for share type List
diff --git a/acceptance/openstack/sharedfilesystems/v2/sharetypes_test.go b/acceptance/openstack/sharedfilesystems/v2/sharetypes_test.go
index f38b1ab..4f1787c 100644
--- a/acceptance/openstack/sharedfilesystems/v2/sharetypes_test.go
+++ b/acceptance/openstack/sharedfilesystems/v2/sharetypes_test.go
@@ -4,6 +4,7 @@
"testing"
"github.com/gophercloud/gophercloud/acceptance/clients"
+ "github.com/gophercloud/gophercloud/openstack/sharedfilesystems/v2/sharetypes"
)
func TestShareTypeCreateDestroy(t *testing.T) {
@@ -21,3 +22,24 @@
defer DeleteShareType(t, client, shareType)
}
+
+func TestShareTypeList(t *testing.T) {
+ client, err := clients.NewSharedFileSystemV2Client()
+ if err != nil {
+ t.Fatalf("Unable to create a shared file system client: %v", err)
+ }
+
+ allPages, err := sharetypes.List(client, sharetypes.ListOpts{}).AllPages()
+ if err != nil {
+ t.Fatalf("Unable to retrieve share types: %v", err)
+ }
+
+ allShareTypes, err := sharetypes.ExtractShareTypes(allPages)
+ if err != nil {
+ t.Fatalf("Unable to extract share types: %v", err)
+ }
+
+ for _, shareType := range allShareTypes {
+ PrintShareType(t, &shareType)
+ }
+}
diff --git a/openstack/sharedfilesystems/v2/sharetypes/requests.go b/openstack/sharedfilesystems/v2/sharetypes/requests.go
index 04153c7..1e63c5f 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/requests.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/requests.go
@@ -1,6 +1,9 @@
package sharetypes
-import "github.com/gophercloud/gophercloud"
+import (
+ "github.com/gophercloud/gophercloud"
+ "github.com/gophercloud/gophercloud/pagination"
+)
// CreateOptsBuilder allows extensions to add additional parameters to the
// Create request.
@@ -54,3 +57,38 @@
_, r.Err = client.Delete(deleteURL(client, id), nil)
return
}
+
+// ListOptsBuilder allows extensions to add additional parameters to the List
+// request.
+type ListOptsBuilder interface {
+ ToShareTypeListQuery() (string, error)
+}
+
+// ListOpts holds options for listing ShareTypes. It is passed to the
+// sharetypes.List function.
+type ListOpts struct {
+ // Select if public types, private types, or both should be listed
+ IsPublic string `q:"is_public"`
+}
+
+// ToShareTypeListQuery formats a ListOpts into a query string.
+func (opts ListOpts) ToShareTypeListQuery() (string, error) {
+ q, err := gophercloud.BuildQueryString(opts)
+ return q.String(), err
+}
+
+// List returns ShareTypes optionally limited by the conditions provided in ListOpts.
+func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
+ url := listURL(client)
+ if opts != nil {
+ query, err := opts.ToShareTypeListQuery()
+ if err != nil {
+ return pagination.Pager{Err: err}
+ }
+ url += query
+ }
+
+ return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
+ return ShareTypePage{pagination.SinglePageBase(r)}
+ })
+}
diff --git a/openstack/sharedfilesystems/v2/sharetypes/results.go b/openstack/sharedfilesystems/v2/sharetypes/results.go
index 7538581..a48543e 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/results.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/results.go
@@ -1,6 +1,9 @@
package sharetypes
-import "github.com/gophercloud/gophercloud"
+import (
+ "github.com/gophercloud/gophercloud"
+ "github.com/gophercloud/gophercloud/pagination"
+)
// ShareType contains all the information associated with an OpenStack
// ShareType.
@@ -39,3 +42,24 @@
type DeleteResult struct {
gophercloud.ErrResult
}
+
+// ShareTypePage is a pagination.pager that is returned from a call to the List function.
+type ShareTypePage struct {
+ pagination.SinglePageBase
+}
+
+// IsEmpty returns true if a ListResult contains no ShareTypes.
+func (r ShareTypePage) IsEmpty() (bool, error) {
+ shareTypes, err := ExtractShareTypes(r)
+ return len(shareTypes) == 0, err
+}
+
+// ExtractShareTypes extracts and returns ShareTypes. It is used while
+// iterating over a sharetypes.List call.
+func ExtractShareTypes(r pagination.Page) ([]ShareType, error) {
+ var s struct {
+ ShareTypes []ShareType `json:"share_types"`
+ }
+ err := (r.(ShareTypePage)).ExtractInto(&s)
+ return s.ShareTypes, err
+}
diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures.go b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures.go
index 0e8ba52..5cf7194 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures.go
@@ -67,3 +67,69 @@
w.WriteHeader(http.StatusAccepted)
})
}
+
+func MockListResponse(t *testing.T) {
+ th.Mux.HandleFunc("/types", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+
+ fmt.Fprintf(w, `
+ {
+ "volume_types": [
+ {
+ "os-share-type-access:is_public": true,
+ "required_extra_specs": {
+ "driver_handles_share_servers": "True"
+ },
+ "extra_specs": {
+ "snapshot_support": "True",
+ "driver_handles_share_servers": "True"
+ },
+ "name": "default",
+ "id": "be27425c-f807-4500-a056-d00721db45cf"
+ },
+ {
+ "os-share-type-access:is_public": true,
+ "required_extra_specs": {
+ "driver_handles_share_servers": "false"
+ },
+ "extra_specs": {
+ "snapshot_support": "True",
+ "driver_handles_share_servers": "false"
+ },
+ "name": "d",
+ "id": "f015bebe-c38b-4c49-8832-00143b10253b"
+ }
+ ],
+ "share_types": [
+ {
+ "os-share-type-access:is_public": true,
+ "required_extra_specs": {
+ "driver_handles_share_servers": "True"
+ },
+ "extra_specs": {
+ "snapshot_support": "True",
+ "driver_handles_share_servers": "True"
+ },
+ "name": "default",
+ "id": "be27425c-f807-4500-a056-d00721db45cf"
+ },
+ {
+ "os-share-type-access:is_public": true,
+ "required_extra_specs": {
+ "driver_handles_share_servers": "false"
+ },
+ "extra_specs": {
+ "snapshot_support": "True",
+ "driver_handles_share_servers": "false"
+ },
+ "name": "d",
+ "id": "f015bebe-c38b-4c49-8832-00143b10253b"
+ }
+ ]
+ }`)
+ })
+}
diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go b/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go
index 22ed2d1..ce20b0f 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go
@@ -69,3 +69,34 @@
res := sharetypes.Delete(client.ServiceClient(), "shareTypeID")
th.AssertNoErr(t, res.Err)
}
+
+// Verifies that share types can be listed correctly
+func TestList(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ MockListResponse(t)
+
+ allPages, err := sharetypes.List(client.ServiceClient(), &sharetypes.ListOpts{}).AllPages()
+ th.AssertNoErr(t, err)
+ actual, err := sharetypes.ExtractShareTypes(allPages)
+ th.AssertNoErr(t, err)
+ expected := []sharetypes.ShareType{
+ {
+ ID: "be27425c-f807-4500-a056-d00721db45cf",
+ Name: "default",
+ IsPublic: true,
+ ExtraSpecs: map[string]interface{}{"snapshot_support": "True", "driver_handles_share_servers": "True"},
+ RequiredExtraSpecs: map[string]interface{}{"driver_handles_share_servers": "True"},
+ },
+ {
+ ID: "f015bebe-c38b-4c49-8832-00143b10253b",
+ Name: "d",
+ IsPublic: true,
+ ExtraSpecs: map[string]interface{}{"driver_handles_share_servers": "false", "snapshot_support": "True"},
+ RequiredExtraSpecs: map[string]interface{}{"driver_handles_share_servers": "True"},
+ },
+ }
+
+ th.CheckDeepEquals(t, expected, actual)
+}
diff --git a/openstack/sharedfilesystems/v2/sharetypes/urls.go b/openstack/sharedfilesystems/v2/sharetypes/urls.go
index 3fb7f18..5004f97 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/urls.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/urls.go
@@ -9,3 +9,7 @@
func deleteURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL("types", id)
}
+
+func listURL(c *gophercloud.ServiceClient) string {
+ return createURL(c)
+}