Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block storage: adding support of update snapshot api call #2081

Merged
merged 5 commits into from
Dec 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions acceptance/openstack/blockstorage/v3/snapshots_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"github.com/gophercloud/gophercloud/acceptance/clients"
"github.com/gophercloud/gophercloud/acceptance/tools"
"github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots"
"github.com/gophercloud/gophercloud/pagination"
th "github.com/gophercloud/gophercloud/testhelper"
Expand All @@ -26,6 +27,21 @@ func TestSnapshots(t *testing.T) {
th.AssertNoErr(t, err)
defer DeleteSnapshot(t, client, snapshot1)

// Update snapshot
updatedSnapshotName := tools.RandomString("ACPTTEST", 16)
updatedSnapshotDescription := tools.RandomString("ACPTTEST", 16)
updateOpts := snapshots.UpdateOpts{
Name: &updatedSnapshotName,
Description: &updatedSnapshotDescription,
}
t.Logf("Attempting to update snapshot: %s", updatedSnapshotName)
updatedSnapshot, err := snapshots.Update(client, snapshot1.ID, updateOpts).Extract()
th.AssertNoErr(t, err)

tools.PrintResource(t, updatedSnapshot)
th.AssertEquals(t, updatedSnapshot.Name, updatedSnapshotName)
th.AssertEquals(t, updatedSnapshot.Description, updatedSnapshotDescription)

volume2, err := CreateVolume(t, client)
th.AssertNoErr(t, err)
defer DeleteVolume(t, client, volume2)
Expand Down
65 changes: 61 additions & 4 deletions openstack/blockstorage/v3/snapshots/doc.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,62 @@
// Package snapshots provides information and interaction with snapshots in the
// OpenStack Block Storage service. A snapshot is a point in time copy of the
// data contained in an external storage volume, and can be controlled
// programmatically.
/*
Package snapshots provides information and interaction with snapshots in the
OpenStack Block Storage service. A snapshot is a point in time copy of the
data contained in an external storage volume, and can be controlled
programmatically.


Example to list Snapshots

allPages, err := snapshots.List(client, snapshots.ListOpts{}).AllPages()
if err != nil{
panic(err)
}
snapshots, err := snapshots.ExtractSnapshots(allPages)
if err != nil{
panic(err)
}
for _,s := range snapshots{
fmt.Println(s)
}

Example to get a Snapshot

snapshotID := "4a584cae-e4ce-429b-9154-d4c9eb8fda4c"
snapshot, err := snapshots.Get(client, snapshotID).Extract()
if err != nil{
panic(err)
}
fmt.Println(snapshot)

Example to create a Snapshot

snapshot, err := snapshots.Create(client, snapshots.CreateOpts{
Name:"snapshot_001",
VolumeID:"5aa119a8-d25b-45a7-8d1b-88e127885635",
}).Extract()
if err != nil{
panic(err)
}
fmt.Println(snapshot)

Example to delete a Snapshot

snapshotID := "4a584cae-e4ce-429b-9154-d4c9eb8fda4c"
err := snapshots.Delete(client, snapshotID).ExtractErr()
if err != nil{
panic(err)
}

Example to update a Snapshot

snapshotID := "4a584cae-e4ce-429b-9154-d4c9eb8fda4c"
snapshot, err = snapshots.Update(client, snapshotID, snapshots.UpdateOpts{
Name: "snapshot_002",
Description:"description_002",
}).Extract()
if err != nil{
panic(err)
}
fmt.Println(snapshot)
*/
package snapshots
37 changes: 37 additions & 0 deletions openstack/blockstorage/v3/snapshots/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ type ListOptsBuilder interface {
ToSnapshotListQuery() (string, error)
}

// ListOpts holds options for listing Snapshots. It is passed to the snapshots.List
// function.
type ListOpts struct {
// AllTenants will retrieve snapshots of all tenants/projects.
AllTenants bool `q:"all_tenants"`
Expand Down Expand Up @@ -118,6 +120,41 @@ func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pa
})
}

// UpdateOptsBuilder allows extensions to add additional parameters to the
// Update request.
type UpdateOptsBuilder interface {
ToSnapshotUpdateMap() (map[string]interface{}, error)
}

// UpdateOpts contain options for updating an existing Snapshot. This object is passed
// to the snapshots.Update function. For more information about the parameters, see
// the Snapshot object.
type UpdateOpts struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
}

// ToSnapshotUpdateMap assembles a request body based on the contents of an
// UpdateOpts.
func (opts UpdateOpts) ToSnapshotUpdateMap() (map[string]interface{}, error) {
return gophercloud.BuildRequestBody(opts, "snapshot")
}

// Update will update the Snapshot with provided information. To extract the updated
// Snapshot from the response, call the Extract method on the UpdateResult.
func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
b, err := opts.ToSnapshotUpdateMap()
if err != nil {
r.Err = err
return
}
resp, err := client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}

// UpdateMetadataOptsBuilder allows extensions to add additional parameters to
// the Update request.
type UpdateMetadataOptsBuilder interface {
Expand Down
11 changes: 9 additions & 2 deletions openstack/blockstorage/v3/snapshots/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ type DeleteResult struct {
gophercloud.ErrResult
}

// UpdateResult contains the response body and error from an Update request.
type UpdateResult struct {
commonResult
}

// SnapshotPage is a pagination.Pager that is returned from a call to the List function.
type SnapshotPage struct {
pagination.LinkedPageBase
Expand Down Expand Up @@ -84,11 +89,13 @@ func (r SnapshotPage) IsEmpty() (bool, error) {
return len(volumes) == 0, err
}

func (page SnapshotPage) NextPageURL() (string, error) {
// NextPageURL uses the response's embedded link reference to navigate to the
// next page of results.
func (r SnapshotPage) NextPageURL() (string, error) {
var s struct {
Links []gophercloud.Link `json:"snapshots_links"`
}
err := page.ExtractInto(&s)
err := r.ExtractInto(&s)
if err != nil {
return "", err
}
Expand Down
2 changes: 1 addition & 1 deletion openstack/blockstorage/v3/snapshots/testing/doc.go
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// snapshots_v3
// Package testing for snapshots_v3
package testing
30 changes: 30 additions & 0 deletions openstack/blockstorage/v3/snapshots/testing/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
fake "github.com/gophercloud/gophercloud/testhelper/client"
)

// MockListResponse provides mock responce for list snapshot API call
func MockListResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "GET")
Expand Down Expand Up @@ -58,6 +59,7 @@ func MockListResponse(t *testing.T) {
})
}

// MockGetResponse provides mock responce for get snapshot API call
func MockGetResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "GET")
Expand All @@ -81,6 +83,7 @@ func MockGetResponse(t *testing.T) {
})
}

// MockCreateResponse provides mock responce for create snapshot API call
func MockCreateResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "POST")
Expand Down Expand Up @@ -116,6 +119,7 @@ func MockCreateResponse(t *testing.T) {
})
}

// MockUpdateMetadataResponse provides mock responce for update metadata snapshot API call
func MockUpdateMetadataResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots/123/metadata", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "PUT")
Expand All @@ -139,10 +143,36 @@ func MockUpdateMetadataResponse(t *testing.T) {
})
}

// MockDeleteResponse provides mock responce for delete snapshot API call
func MockDeleteResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "DELETE")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
w.WriteHeader(http.StatusNoContent)
})
}

// MockUpdateResponse provides mock responce for update snapshot API call
func MockUpdateResponse(t *testing.T) {
th.Mux.HandleFunc("/snapshots/d32019d3-bc6e-4319-9c1d-6722fc136a22", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "PUT")
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)

w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, `
{
"snapshot": {
"id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
"name": "snapshot-002",
"description": "Daily backup 002",
"volume_id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c",
"status": "available",
"size": 30,
"created_at": "2017-05-30T03:35:03.000000",
"updated_at": "2017-05-30T03:35:03.000000"
}
}
`)
})
}
15 changes: 15 additions & 0 deletions openstack/blockstorage/v3/snapshots/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,18 @@ func TestDelete(t *testing.T) {
res := snapshots.Delete(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22")
th.AssertNoErr(t, res.Err)
}

func TestUpdate(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

MockUpdateResponse(t)

var name = "snapshot-002"
var description = "Daily backup 002"
options := snapshots.UpdateOpts{Name: &name, Description: &description}
v, err := snapshots.Update(client.ServiceClient(), "d32019d3-bc6e-4319-9c1d-6722fc136a22", options).Extract()
th.AssertNoErr(t, err)
th.CheckEquals(t, "snapshot-002", v.Name)
th.CheckEquals(t, "Daily backup 002", v.Description)
}
4 changes: 4 additions & 0 deletions openstack/blockstorage/v3/snapshots/urls.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ func listURL(c *gophercloud.ServiceClient) string {
return createURL(c)
}

func updateURL(c *gophercloud.ServiceClient, id string) string {
return deleteURL(c, id)
}

func metadataURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL("snapshots", id, "metadata")
}
Expand Down