blob: 504ce6e55efe6fe78569c3661b2fbf44c5f5ab25 [file] [log] [blame]
Jon Perrittdfff9972014-09-22 01:14:54 -05001package snapshots
2
3import (
Jon Perritt27249f42016-02-18 10:35:59 -06004 "github.com/gophercloud/gophercloud"
5 "github.com/gophercloud/gophercloud/pagination"
Jon Perrittdfff9972014-09-22 01:14:54 -05006)
7
Jon Perritt1c2356b2014-10-13 19:56:43 -05008// CreateOptsBuilder allows extensions to add additional parameters to the
9// Create request.
10type CreateOptsBuilder interface {
11 ToSnapshotCreateMap() (map[string]interface{}, error)
12}
13
Jon Perritt42b3a2a2014-10-02 23:06:07 -050014// CreateOpts contains options for creating a Snapshot. This object is passed to
15// the snapshots.Create function. For more information about these parameters,
16// see the Snapshot object.
Jon Perrittdfff9972014-09-22 01:14:54 -050017type CreateOpts struct {
Jon Perritt1c2356b2014-10-13 19:56:43 -050018 // OPTIONAL
19 Description string
20 // OPTIONAL
21 Force bool
22 // OPTIONAL
23 Metadata map[string]interface{}
24 // OPTIONAL
25 Name string
26 // REQUIRED
27 VolumeID string
Jon Perrittdfff9972014-09-22 01:14:54 -050028}
29
Jon Perritt1c2356b2014-10-13 19:56:43 -050030// ToSnapshotCreateMap assembles a request body based on the contents of a
31// CreateOpts.
32func (opts CreateOpts) ToSnapshotCreateMap() (map[string]interface{}, error) {
33 s := make(map[string]interface{})
34
35 if opts.VolumeID == "" {
Jon Perritted258942016-02-28 23:38:21 -060036 err := &gophercloud.ErrMissingInput{}
37 err.Argument = "CreateOpts.VolumeID"
38 err.Function = "snapshots.ToSnapshotCreateMap"
39 return nil, err
Jon Perritt1c2356b2014-10-13 19:56:43 -050040 }
41 s["volume_id"] = opts.VolumeID
42
43 if opts.Description != "" {
44 s["display_description"] = opts.Description
45 }
46 if opts.Force == true {
47 s["force"] = opts.Force
48 }
49 if opts.Metadata != nil {
50 s["metadata"] = opts.Metadata
51 }
52 if opts.Name != "" {
53 s["display_name"] = opts.Name
54 }
55
56 return map[string]interface{}{"snapshot": s}, nil
57}
58
59// Create will create a new Snapshot based on the values in CreateOpts. To
60// extract the Snapshot object from the response, call the Extract method on the
Jon Perritt42b3a2a2014-10-02 23:06:07 -050061// CreateResult.
Jon Perritt1c2356b2014-10-13 19:56:43 -050062func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
Jon Perritt6d5561b2014-10-01 21:42:15 -050063 var res CreateResult
Jon Perritt1c2356b2014-10-13 19:56:43 -050064
65 reqBody, err := opts.ToSnapshotCreateMap()
66 if err != nil {
67 res.Err = err
68 return res
69 }
70
Jamie Hannaford6181fdb2015-03-24 14:55:50 +010071 _, res.Err = client.Post(createURL(client), reqBody, &res.Body, &gophercloud.RequestOpts{
72 OkCodes: []int{200, 201},
Jon Perrittdfff9972014-09-22 01:14:54 -050073 })
Jon Perritt6d5561b2014-10-01 21:42:15 -050074 return res
Jon Perrittdfff9972014-09-22 01:14:54 -050075}
Jon Perritt56d43b22014-09-22 20:47:11 -050076
Jon Perritt42b3a2a2014-10-02 23:06:07 -050077// Delete will delete the existing Snapshot with the provided ID.
Jamie Hannaford38509592014-10-27 11:25:15 +010078func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
79 var res DeleteResult
Jamie Hannaford6181fdb2015-03-24 14:55:50 +010080 _, res.Err = client.Delete(deleteURL(client, id), nil)
Jamie Hannaford38509592014-10-27 11:25:15 +010081 return res
Jon Perrittd4788f92014-09-24 12:05:27 -050082}
83
Jon Perritt1c2356b2014-10-13 19:56:43 -050084// Get retrieves the Snapshot with the provided ID. To extract the Snapshot
85// object from the response, call the Extract method on the GetResult.
Jon Perrittd7468632014-09-22 21:58:59 -050086func Get(client *gophercloud.ServiceClient, id string) GetResult {
Jon Perritt6d5561b2014-10-01 21:42:15 -050087 var res GetResult
Jamie Hannaford6181fdb2015-03-24 14:55:50 +010088 _, res.Err = client.Get(getURL(client, id), &res.Body, nil)
Jon Perritt6d5561b2014-10-01 21:42:15 -050089 return res
90}
91
Jon Perritt1c2356b2014-10-13 19:56:43 -050092// ListOptsBuilder allows extensions to add additional parameters to the List
93// request.
94type ListOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -050095 ToSnapshotListQuery() (string, error)
Jon Perritt1c2356b2014-10-13 19:56:43 -050096}
97
Jon Perritt42b3a2a2014-10-02 23:06:07 -050098// ListOpts hold options for listing Snapshots. It is passed to the
99// snapshots.List function.
Jon Perritt6d5561b2014-10-01 21:42:15 -0500100type ListOpts struct {
101 Name string `q:"display_name"`
102 Status string `q:"status"`
103 VolumeID string `q:"volume_id"`
104}
105
Jon Perritt26780d52014-10-14 11:35:58 -0500106// ToSnapshotListQuery formats a ListOpts into a query string.
107func (opts ListOpts) ToSnapshotListQuery() (string, error) {
Jon Perritt1c2356b2014-10-13 19:56:43 -0500108 q, err := gophercloud.BuildQueryString(opts)
109 if err != nil {
110 return "", err
111 }
112 return q.String(), nil
113}
114
115// List returns Snapshots optionally limited by the conditions provided in
116// ListOpts.
117func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
Jon Perritt6d5561b2014-10-01 21:42:15 -0500118 url := listURL(client)
119 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -0500120 query, err := opts.ToSnapshotListQuery()
Jon Perritt6d5561b2014-10-01 21:42:15 -0500121 if err != nil {
122 return pagination.Pager{Err: err}
123 }
Jon Perritt1c2356b2014-10-13 19:56:43 -0500124 url += query
Jon Perritt6d5561b2014-10-01 21:42:15 -0500125 }
126
Ash Wilsonb8b16f82014-10-20 10:19:49 -0400127 createPage := func(r pagination.PageResult) pagination.Page {
Jon Perritt12395212016-02-24 10:41:17 -0600128 return SnapshotPage{pagination.SinglePageBase(r)}
Jon Perritt6d5561b2014-10-01 21:42:15 -0500129 }
130 return pagination.NewPager(client, url, createPage)
131}
132
Jon Perritt1c2356b2014-10-13 19:56:43 -0500133// UpdateMetadataOptsBuilder allows extensions to add additional parameters to
134// the Update request.
135type UpdateMetadataOptsBuilder interface {
136 ToSnapshotUpdateMetadataMap() (map[string]interface{}, error)
137}
138
Jamie Hannafordd8275bb2014-10-06 16:12:23 +0200139// UpdateMetadataOpts contain options for updating an existing Snapshot. This
140// object is passed to the snapshots.Update function. For more information
141// about the parameters, see the Snapshot object.
Jon Perritte357e3d2014-10-03 01:53:57 -0500142type UpdateMetadataOpts struct {
143 Metadata map[string]interface{}
Jon Perritt6d5561b2014-10-01 21:42:15 -0500144}
145
Jon Perritt1c2356b2014-10-13 19:56:43 -0500146// ToSnapshotUpdateMetadataMap assembles a request body based on the contents of
147// an UpdateMetadataOpts.
148func (opts UpdateMetadataOpts) ToSnapshotUpdateMetadataMap() (map[string]interface{}, error) {
149 v := make(map[string]interface{})
150
151 if opts.Metadata != nil {
152 v["metadata"] = opts.Metadata
153 }
154
155 return v, nil
156}
157
Jamie Hannafordd8275bb2014-10-06 16:12:23 +0200158// UpdateMetadata will update the Snapshot with provided information. To
159// extract the updated Snapshot from the response, call the ExtractMetadata
160// method on the UpdateMetadataResult.
Jon Perritt1c2356b2014-10-13 19:56:43 -0500161func UpdateMetadata(client *gophercloud.ServiceClient, id string, opts UpdateMetadataOptsBuilder) UpdateMetadataResult {
Jon Perritte357e3d2014-10-03 01:53:57 -0500162 var res UpdateMetadataResult
Jon Perritt6d5561b2014-10-01 21:42:15 -0500163
Jon Perritt1c2356b2014-10-13 19:56:43 -0500164 reqBody, err := opts.ToSnapshotUpdateMetadataMap()
165 if err != nil {
166 res.Err = err
167 return res
168 }
169
Jamie Hannaford6181fdb2015-03-24 14:55:50 +0100170 _, res.Err = client.Put(updateMetadataURL(client, id), reqBody, &res.Body, &gophercloud.RequestOpts{
171 OkCodes: []int{200},
Jon Perritt6d5561b2014-10-01 21:42:15 -0500172 })
173 return res
Jon Perritt56d43b22014-09-22 20:47:11 -0500174}
Jon Perritt24c20832015-06-30 09:57:00 -0600175
176// IDFromName is a convienience function that returns a snapshot's ID given its name.
177func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
Jon Perritted258942016-02-28 23:38:21 -0600178 count := 0
179 id := ""
Jon Perritt24c20832015-06-30 09:57:00 -0600180 if name == "" {
Jon Perritted258942016-02-28 23:38:21 -0600181 err := &gophercloud.ErrMissingInput{}
182 err.Function = "snapshots.IDFromName"
183 err.Argument = "name"
184 return "", err
Jon Perritt24c20832015-06-30 09:57:00 -0600185 }
Jon Perritt24c20832015-06-30 09:57:00 -0600186
Jon Perritted258942016-02-28 23:38:21 -0600187 pages, err := List(client, nil).AllPages()
188 if err != nil {
189 return "", err
190 }
Jon Perritt24c20832015-06-30 09:57:00 -0600191
Jon Perritted258942016-02-28 23:38:21 -0600192 all, err := ExtractSnapshots(pages)
193 if err != nil {
194 return "", err
195 }
196
197 for _, s := range all {
198 if s.Name == name {
199 count++
200 id = s.ID
201 }
202 }
203
204 switch count {
Jon Perritt24c20832015-06-30 09:57:00 -0600205 case 0:
Jon Perritted258942016-02-28 23:38:21 -0600206 err := &gophercloud.ErrResourceNotFound{}
207 err.Name = name
208 err.ResourceType = "snapshot"
209 err.Function = "snapshots.IDFromName"
210 return "", err
Jon Perritt24c20832015-06-30 09:57:00 -0600211 case 1:
Jon Perritted258942016-02-28 23:38:21 -0600212 return id, nil
Jon Perritt24c20832015-06-30 09:57:00 -0600213 default:
Jon Perritted258942016-02-28 23:38:21 -0600214 err := &gophercloud.ErrMultipleResourcesFound{}
215 err.Count = count
216 err.Name = name
217 err.ResourceType = "snapshot"
218 err.Function = "snapshots.IDFromName"
219 return "", err
Jon Perritt24c20832015-06-30 09:57:00 -0600220 }
221}