Feature/filestorage sharetype setextraspecs (#147)
* sfs: Add support for share type Set Extra Specs
* sfs: Add acceptance tests for share type Set Extra Specs
* sfs: Fix tests
diff --git a/acceptance/openstack/sharedfilesystems/v2/sharetypes_test.go b/acceptance/openstack/sharedfilesystems/v2/sharetypes_test.go
index e29e484..d54b3f7 100644
--- a/acceptance/openstack/sharedfilesystems/v2/sharetypes_test.go
+++ b/acceptance/openstack/sharedfilesystems/v2/sharetypes_test.go
@@ -73,6 +73,15 @@
t.Fatalf("Unable to create share type: %v", err)
}
+ options := sharetypes.SetExtraSpecsOpts{
+ Specs: map[string]interface{}{"my_new_key": "my_value"},
+ }
+
+ _, err = sharetypes.SetExtraSpecs(client, shareType.ID, options).Extract()
+ if err != nil {
+ t.Fatalf("Unable to set extra specs for Share type: %s", shareType.Name)
+ }
+
extraSpecs, err := sharetypes.GetExtraSpecs(client, shareType.ID).Extract()
if err != nil {
t.Fatalf("Unable to retrieve share type: %s", shareType.Name)
@@ -82,6 +91,10 @@
t.Fatal("driver_handles_share_servers was expected to be true")
}
+ if extraSpecs["my_new_key"] != "my_value" {
+ t.Fatal("my_new_key was expected to be equal to my_value")
+ }
+
PrintShareType(t, shareType)
defer DeleteShareType(t, client, shareType)
diff --git a/openstack/sharedfilesystems/v2/sharetypes/requests.go b/openstack/sharedfilesystems/v2/sharetypes/requests.go
index 94f84b6..0b6744b 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/requests.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/requests.go
@@ -104,3 +104,36 @@
_, r.Err = client.Get(getExtraSpecsURL(client, id), &r.Body, nil)
return
}
+
+// SetExtraSpecsOptsBuilder allows extensions to add additional parameters to the
+// SetExtraSpecs request.
+type SetExtraSpecsOptsBuilder interface {
+ ToShareTypeSetExtraSpecsMap() (map[string]interface{}, error)
+}
+
+type SetExtraSpecsOpts struct {
+ // A list of all extra specifications to be added to a ShareType
+ Specs map[string]interface{} `json:"extra_specs"`
+}
+
+// ToShareTypeSetExtraSpecsMap assembles a request body based on the contents of a
+// SetExtraSpecsOpts.
+func (opts SetExtraSpecsOpts) ToShareTypeSetExtraSpecsMap() (map[string]interface{}, error) {
+ return gophercloud.BuildRequestBody(opts, "")
+}
+
+// SetExtraSpecs will set new specifications for a ShareType based on the values
+// in SetExtraSpecsOpts. To extract the extra specifications object from the response,
+// call the Extract method on the SetExtraSpecsResult.
+func SetExtraSpecs(client *gophercloud.ServiceClient, id string, opts SetExtraSpecsOptsBuilder) (r SetExtraSpecsResult) {
+ b, err := opts.ToShareTypeSetExtraSpecsMap()
+ if err != nil {
+ r.Err = err
+ return
+ }
+
+ _, r.Err = client.Post(setExtraSpecsURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
+ OkCodes: []int{200, 202},
+ })
+ return
+}
diff --git a/openstack/sharedfilesystems/v2/sharetypes/results.go b/openstack/sharedfilesystems/v2/sharetypes/results.go
index f4de532..9388b52 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/results.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/results.go
@@ -90,3 +90,8 @@
type GetExtraSpecsResult struct {
extraSpecsResult
}
+
+// SetExtraSpecsResult contains the response body and error from a Set Extra Specs request.
+type SetExtraSpecsResult struct {
+ extraSpecsResult
+}
diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures.go b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures.go
index 1666d11..6565ba5 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/testing/fixtures.go
@@ -177,7 +177,32 @@
"extra_specs": {
"snapshot_support": "True",
"driver_handles_share_servers": "True",
- "my_custom_extra_spec": "False"
+ "my_custom_extra_spec": "False"
+ }
+ }`)
+ })
+}
+
+func MockSetExtraSpecsResponse(t *testing.T) {
+ th.Mux.HandleFunc("/types/shareTypeID/extra_specs", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "POST")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+ th.TestHeader(t, r, "Content-Type", "application/json")
+ th.TestHeader(t, r, "Accept", "application/json")
+ th.TestJSONRequest(t, r, `
+ {
+ "extra_specs": {
+ "my_key": "my_value"
+ }
+ }`)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusAccepted)
+
+ fmt.Fprintf(w, `
+ {
+ "extra_specs": {
+ "my_key": "my_value"
}
}`)
})
diff --git a/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go b/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go
index ad1ad15..d6576c3 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/testing/requests_test.go
@@ -134,3 +134,20 @@
th.AssertEquals(t, st["driver_handles_share_servers"], "True")
th.AssertEquals(t, st["my_custom_extra_spec"], "False")
}
+
+// Verifies that an extra specs can be added to a share type
+func TestSetExtraSpecs(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ MockSetExtraSpecsResponse(t)
+
+ options := &sharetypes.SetExtraSpecsOpts{
+ Specs: map[string]interface{}{"my_key": "my_value"},
+ }
+
+ es, err := sharetypes.SetExtraSpecs(client.ServiceClient(), "shareTypeID", options).Extract()
+ th.AssertNoErr(t, err)
+
+ th.AssertEquals(t, es["my_key"], "my_value")
+}
diff --git a/openstack/sharedfilesystems/v2/sharetypes/urls.go b/openstack/sharedfilesystems/v2/sharetypes/urls.go
index ecd159e..848aac8 100644
--- a/openstack/sharedfilesystems/v2/sharetypes/urls.go
+++ b/openstack/sharedfilesystems/v2/sharetypes/urls.go
@@ -21,3 +21,7 @@
func getExtraSpecsURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL("types", id, "extra_specs")
}
+
+func setExtraSpecsURL(c *gophercloud.ServiceClient, id string) string {
+ return getExtraSpecsURL(c, id)
+}