Feature/filestorage sharenetworks update (#126)
* sfs: Add update for share networks
* sfs: Add acceptance tests for share network Update
* sfs: Add possiblity to update the network for share network
* sfs: Improve share network Update unit tests
* sfs: Improve share network Update acceptance tests
diff --git a/acceptance/openstack/sharedfilesystems/v2/sharenetworks_test.go b/acceptance/openstack/sharedfilesystems/v2/sharenetworks_test.go
index b9876d5..1a4ae9b 100644
--- a/acceptance/openstack/sharedfilesystems/v2/sharenetworks_test.go
+++ b/acceptance/openstack/sharedfilesystems/v2/sharenetworks_test.go
@@ -6,6 +6,7 @@
"github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/openstack/sharedfilesystems/v2/sharenetworks"
"github.com/gophercloud/gophercloud/pagination"
+ th "github.com/gophercloud/gophercloud/testhelper"
)
func TestShareNetworkCreateDestroy(t *testing.T) {
@@ -33,6 +34,54 @@
defer DeleteShareNetwork(t, client, shareNetwork)
}
+// Create a share network and update the name and description. Get the share
+// network and verify that the name and description have been updated
+func TestShareNetworkUpdate(t *testing.T) {
+ client, err := clients.NewSharedFileSystemV2Client()
+ if err != nil {
+ t.Fatalf("Unable to create shared file system client: %v", err)
+ }
+
+ shareNetwork, err := CreateShareNetwork(t, client)
+ if err != nil {
+ t.Fatalf("Unable to create share network: %v", err)
+ }
+
+ expectedShareNetwork, err := sharenetworks.Get(client, shareNetwork.ID).Extract()
+ if err != nil {
+ t.Errorf("Unable to retrieve shareNetwork: %v", err)
+ }
+
+ options := sharenetworks.UpdateOpts{
+ Name: "NewName",
+ Description: "New share network description",
+ NovaNetID: "New_nova_network_id",
+ }
+
+ expectedShareNetwork.Name = options.Name
+ expectedShareNetwork.Description = options.Description
+ expectedShareNetwork.NovaNetID = options.NovaNetID
+
+ _, err = sharenetworks.Update(client, shareNetwork.ID, options).Extract()
+ if err != nil {
+ t.Errorf("Unable to update shareNetwork: %v", err)
+ }
+
+ updatedShareNetwork, err := sharenetworks.Get(client, shareNetwork.ID).Extract()
+ if err != nil {
+ t.Errorf("Unable to retrieve shareNetwork: %v", err)
+ }
+
+ // Update time has to be set in order to get the assert equal to pass
+ expectedShareNetwork.UpdatedAt = updatedShareNetwork.UpdatedAt
+
+ th.CheckDeepEquals(t, expectedShareNetwork, updatedShareNetwork)
+
+ PrintShareNetwork(t, shareNetwork)
+
+ defer DeleteShareNetwork(t, client, shareNetwork)
+}
+
func TestShareNetworkListDetail(t *testing.T) {
client, err := clients.NewSharedFileSystemV2Client()
if err != nil {
diff --git a/openstack/sharedfilesystems/v2/sharenetworks/requests.go b/openstack/sharedfilesystems/v2/sharenetworks/requests.go
index 700e703..ebaad70 100644
--- a/openstack/sharedfilesystems/v2/sharenetworks/requests.go
+++ b/openstack/sharedfilesystems/v2/sharenetworks/requests.go
@@ -123,3 +123,45 @@
_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
return
}
+
+// UpdateOptsBuilder allows extensions to add additional parameters to the
+// Update request.
+type UpdateOptsBuilder interface {
+ ToShareNetworkUpdateMap() (map[string]interface{}, error)
+}
+
+// UpdateOpts contain options for updating an existing ShareNetwork. This object is passed
+// to the sharenetworks.Update function. For more information about the parameters, see
+// the ShareNetwork object.
+type UpdateOpts struct {
+ // The share network name
+ Name string `json:"name,omitempty"`
+ // The share network description
+ Description string `json:"description,omitempty"`
+ // The UUID of the Neutron network to set up for share servers
+ NeutronNetID string `json:"neutron_net_id,omitempty"`
+ // The UUID of the Neutron subnet to set up for share servers
+ NeutronSubnetID string `json:"neutron_subnet_id,omitempty"`
+ // The UUID of the nova network to set up for share servers
+ NovaNetID string `json:"nova_net_id,omitempty"`
+}
+
+// ToShareNetworkUpdateMap assembles a request body based on the contents of an
+// UpdateOpts.
+func (opts UpdateOpts) ToShareNetworkUpdateMap() (map[string]interface{}, error) {
+ return gophercloud.BuildRequestBody(opts, "share_network")
+}
+
+// Update will update the ShareNetwork with provided information. To extract the updated
+// ShareNetwork from the response, call the Extract method on the UpdateResult.
+func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
+ b, err := opts.ToShareNetworkUpdateMap()
+ if err != nil {
+ r.Err = err
+ return
+ }
+ _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
+ OkCodes: []int{200},
+ })
+ return
+}
diff --git a/openstack/sharedfilesystems/v2/sharenetworks/results.go b/openstack/sharedfilesystems/v2/sharenetworks/results.go
index ce2b00b..1eb64bc 100644
--- a/openstack/sharedfilesystems/v2/sharenetworks/results.go
+++ b/openstack/sharedfilesystems/v2/sharenetworks/results.go
@@ -142,3 +142,8 @@
type GetResult struct {
commonResult
}
+
+// UpdateResult contains the response body and error from an Update request.
+type UpdateResult struct {
+ commonResult
+}
diff --git a/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures.go b/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures.go
index 1b3cb9b..8b753e9 100644
--- a/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures.go
+++ b/openstack/sharedfilesystems/v2/sharenetworks/testing/fixtures.go
@@ -251,3 +251,57 @@
}`)
})
}
+
+func MockUpdateNeutronResponse(t *testing.T) {
+ th.Mux.HandleFunc("/share-networks/713df749-aac0-4a54-af52-10f6c991e80c", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "PUT")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+ w.WriteHeader(http.StatusOK)
+ fmt.Fprintf(w, `
+ {
+ "share_network": {
+ "name": "net_my2",
+ "segmentation_id": null,
+ "created_at": "2015-09-04T14:54:25.000000",
+ "neutron_subnet_id": "new-neutron-subnet-id",
+ "updated_at": "2015-09-07T08:02:53.512184",
+ "id": "713df749-aac0-4a54-af52-10f6c991e80c",
+ "neutron_net_id": "new-neutron-id",
+ "ip_version": 4,
+ "nova_net_id": null,
+ "cidr": null,
+ "project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
+ "network_type": null,
+ "description": "new description"
+ }
+ }
+ `)
+ })
+}
+
+func MockUpdateNovaResponse(t *testing.T) {
+ th.Mux.HandleFunc("/share-networks/713df749-aac0-4a54-af52-10f6c991e80c", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "PUT")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+ w.WriteHeader(http.StatusOK)
+ fmt.Fprintf(w, `
+ {
+ "share_network": {
+ "name": "net_my2",
+ "segmentation_id": null,
+ "created_at": "2015-09-04T14:54:25.000000",
+ "neutron_subnet_id": null,
+ "updated_at": "2015-09-07T08:02:53.512184",
+ "id": "713df749-aac0-4a54-af52-10f6c991e80c",
+ "neutron_net_id": null,
+ "ip_version": 4,
+ "nova_net_id": "new-nova-id",
+ "cidr": null,
+ "project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
+ "network_type": null,
+ "description": "new description"
+ }
+ }
+ `)
+ })
+}
diff --git a/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go b/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go
index a66199f..0b28623 100644
--- a/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go
+++ b/openstack/sharedfilesystems/v2/sharenetworks/testing/requests_test.go
@@ -168,3 +168,72 @@
th.CheckDeepEquals(t, &expected, n)
}
+
+// Verifies that it is possible to update a share network using neutron network
+func TestUpdateNeutron(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ MockUpdateNeutronResponse(t)
+
+ expected := sharenetworks.ShareNetwork{
+ ID: "713df749-aac0-4a54-af52-10f6c991e80c",
+ Name: "net_my2",
+ CreatedAt: gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 4, 14, 54, 25, 0, time.UTC)),
+ Description: "new description",
+ NetworkType: "",
+ CIDR: "",
+ NovaNetID: "",
+ NeutronNetID: "new-neutron-id",
+ NeutronSubnetID: "new-neutron-subnet-id",
+ IPVersion: 4,
+ SegmentationID: 0,
+ UpdatedAt: gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 7, 8, 2, 53, 512184000, time.UTC)),
+ ProjectID: "16e1ab15c35a457e9c2b2aa189f544e1",
+ }
+
+ options := sharenetworks.UpdateOpts{
+ Name: "net_my2",
+ Description: "new description",
+ NeutronNetID: "new-neutron-id",
+ NeutronSubnetID: "new-neutron-subnet-id",
+ }
+
+ v, err := sharenetworks.Update(client.ServiceClient(), "713df749-aac0-4a54-af52-10f6c991e80c", options).Extract()
+ th.AssertNoErr(t, err)
+ th.CheckDeepEquals(t, &expected, v)
+}
+
+// Verifies that it is possible to update a share network using nova network
+func TestUpdateNova(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ MockUpdateNovaResponse(t)
+
+ expected := sharenetworks.ShareNetwork{
+ ID: "713df749-aac0-4a54-af52-10f6c991e80c",
+ Name: "net_my2",
+ CreatedAt: gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 4, 14, 54, 25, 0, time.UTC)),
+ Description: "new description",
+ NetworkType: "",
+ CIDR: "",
+ NovaNetID: "new-nova-id",
+ NeutronNetID: "",
+ NeutronSubnetID: "",
+ IPVersion: 4,
+ SegmentationID: 0,
+ UpdatedAt: gophercloud.JSONRFC3339MilliNoZ(time.Date(2015, 9, 7, 8, 2, 53, 512184000, time.UTC)),
+ ProjectID: "16e1ab15c35a457e9c2b2aa189f544e1",
+ }
+
+ options := sharenetworks.UpdateOpts{
+ Name: "net_my2",
+ Description: "new description",
+ NovaNetID: "new-nova-id",
+ }
+
+ v, err := sharenetworks.Update(client.ServiceClient(), "713df749-aac0-4a54-af52-10f6c991e80c", options).Extract()
+ th.AssertNoErr(t, err)
+ th.CheckDeepEquals(t, &expected, v)
+}
diff --git a/openstack/sharedfilesystems/v2/sharenetworks/urls.go b/openstack/sharedfilesystems/v2/sharenetworks/urls.go
index 9e2c8e9..6198c54 100644
--- a/openstack/sharedfilesystems/v2/sharenetworks/urls.go
+++ b/openstack/sharedfilesystems/v2/sharenetworks/urls.go
@@ -17,3 +17,7 @@
func getURL(c *gophercloud.ServiceClient, id string) string {
return deleteURL(c, id)
}
+
+func updateURL(c *gophercloud.ServiceClient, id string) string {
+ return deleteURL(c, id)
+}