struct opts -> interface opts (block storage)
diff --git a/openstack/blockstorage/v1/snapshots/requests.go b/openstack/blockstorage/v1/snapshots/requests.go
index f3180d7..f54432f 100644
--- a/openstack/blockstorage/v1/snapshots/requests.go
+++ b/openstack/blockstorage/v1/snapshots/requests.go
@@ -1,54 +1,78 @@
package snapshots
import (
+ "fmt"
+
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
"github.com/racker/perigee"
)
+// CreateOptsBuilder allows extensions to add additional parameters to the
+// Create request.
+type CreateOptsBuilder interface {
+ ToSnapshotCreateMap() (map[string]interface{}, error)
+}
+
// CreateOpts contains options for creating a Snapshot. This object is passed to
// the snapshots.Create function. For more information about these parameters,
// see the Snapshot object.
type CreateOpts struct {
- Description string // OPTIONAL
- Force bool // OPTIONAL
- Metadata map[string]interface{} // OPTIONAL
- Name string // OPTIONAL
- VolumeID string // REQUIRED
+ // OPTIONAL
+ Description string
+ // OPTIONAL
+ Force bool
+ // OPTIONAL
+ Metadata map[string]interface{}
+ // OPTIONAL
+ Name string
+ // REQUIRED
+ VolumeID string
}
-// Create will create a new Snapshot based on the values in CreateOpts. To extract
-// the Snapshot object from the response, call the Extract method on the
+// ToSnapshotCreateMap assembles a request body based on the contents of a
+// CreateOpts.
+func (opts CreateOpts) ToSnapshotCreateMap() (map[string]interface{}, error) {
+ s := make(map[string]interface{})
+
+ if opts.VolumeID == "" {
+ return nil, fmt.Errorf("Required CreateOpts field 'VolumeID' not set.")
+ }
+ s["volume_id"] = opts.VolumeID
+
+ if opts.Description != "" {
+ s["display_description"] = opts.Description
+ }
+ if opts.Force == true {
+ s["force"] = opts.Force
+ }
+ if opts.Metadata != nil {
+ s["metadata"] = opts.Metadata
+ }
+ if opts.Name != "" {
+ s["display_name"] = opts.Name
+ }
+
+ return map[string]interface{}{"snapshot": s}, nil
+}
+
+// Create will create a new Snapshot based on the values in CreateOpts. To
+// extract the Snapshot object from the response, call the Extract method on the
// CreateResult.
-func Create(client *gophercloud.ServiceClient, opts *CreateOpts) CreateResult {
- type snapshot struct {
- Description *string `json:"display_description,omitempty"`
- Force bool `json:"force,omitempty"`
- Metadata map[string]interface{} `json:"metadata,omitempty"`
- Name *string `json:"display_name,omitempty"`
- VolumeID *string `json:"volume_id,omitempty"`
- }
-
- type request struct {
- Snapshot snapshot `json:"snapshot"`
- }
-
- reqBody := request{
- Snapshot: snapshot{},
- }
-
- reqBody.Snapshot.Description = gophercloud.MaybeString(opts.Description)
- reqBody.Snapshot.Name = gophercloud.MaybeString(opts.Name)
- reqBody.Snapshot.VolumeID = gophercloud.MaybeString(opts.VolumeID)
-
- reqBody.Snapshot.Force = opts.Force
-
+func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
var res CreateResult
+
+ reqBody, err := opts.ToSnapshotCreateMap()
+ if err != nil {
+ res.Err = err
+ return res
+ }
+
_, res.Err = perigee.Request("POST", createURL(client), perigee.Options{
MoreHeaders: client.Provider.AuthenticatedHeaders(),
OkCodes: []int{200, 201},
- ReqBody: &reqBody,
+ ReqBody: reqBody,
Results: &res.Resp,
})
return res
@@ -63,8 +87,8 @@
return err
}
-// Get retrieves the Snapshot with the provided ID. To extract the Snapshot object
-// from the response, call the Extract method on the GetResult.
+// Get retrieves the Snapshot with the provided ID. To extract the Snapshot
+// object from the response, call the Extract method on the GetResult.
func Get(client *gophercloud.ServiceClient, id string) GetResult {
var res GetResult
_, res.Err = perigee.Request("GET", getURL(client, id), perigee.Options{
@@ -75,6 +99,12 @@
return res
}
+// ListOptsBuilder allows extensions to add additional parameters to the List
+// request.
+type ListOptsBuilder interface {
+ ToVolumeListParams() (string, error)
+}
+
// ListOpts hold options for listing Snapshots. It is passed to the
// snapshots.List function.
type ListOpts struct {
@@ -83,15 +113,25 @@
VolumeID string `q:"volume_id"`
}
-// List returns Snapshots optionally limited by the conditions provided in ListOpts.
-func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager {
+// ToVolumeListParams formats a ListOpts into a query string.
+func (opts ListOpts) ToVolumeListParams() (string, error) {
+ q, err := gophercloud.BuildQueryString(opts)
+ if err != nil {
+ return "", err
+ }
+ return q.String(), nil
+}
+
+// List returns Snapshots 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 := gophercloud.BuildQueryString(opts)
+ query, err := opts.ToVolumeListParams()
if err != nil {
return pagination.Pager{Err: err}
}
- url += query.String()
+ url += query
}
createPage := func(r pagination.LastHTTPResponse) pagination.Page {
@@ -100,6 +140,12 @@
return pagination.NewPager(client, url, createPage)
}
+// UpdateMetadataOptsBuilder allows extensions to add additional parameters to
+// the Update request.
+type UpdateMetadataOptsBuilder interface {
+ ToSnapshotUpdateMetadataMap() (map[string]interface{}, error)
+}
+
// UpdateMetadataOpts 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.
@@ -107,24 +153,34 @@
Metadata map[string]interface{}
}
+// ToSnapshotUpdateMetadataMap assembles a request body based on the contents of
+// an UpdateMetadataOpts.
+func (opts UpdateMetadataOpts) ToSnapshotUpdateMetadataMap() (map[string]interface{}, error) {
+ v := make(map[string]interface{})
+
+ if opts.Metadata != nil {
+ v["metadata"] = opts.Metadata
+ }
+
+ return v, nil
+}
+
// UpdateMetadata will update the Snapshot with provided information. To
// extract the updated Snapshot from the response, call the ExtractMetadata
// method on the UpdateMetadataResult.
-func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts *UpdateMetadataOpts) UpdateMetadataResult {
- type request struct {
- Metadata map[string]interface{} `json:"metadata,omitempty"`
- }
-
- reqBody := request{}
-
- reqBody.Metadata = opts.Metadata
-
+func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) UpdateMetadataResult {
var res UpdateMetadataResult
+ reqBody, err := opts.ToSnapshotUpdateMetadataMap()
+ if err != nil {
+ res.Err = err
+ return res
+ }
+
_, res.Err = perigee.Request("PUT", updateMetadataURL(client, id), perigee.Options{
MoreHeaders: client.Provider.AuthenticatedHeaders(),
OkCodes: []int{200},
- ReqBody: &reqBody,
+ ReqBody: reqBody,
Results: &res.Resp,
})
return res