blob: f4332de6578e983f43623ab0750884df11687c4f [file] [log] [blame]
Jon Perrittee6074f2014-04-30 18:42:32 -05001package volumes
2
3import (
Jon Perritt1c2356b2014-10-13 19:56:43 -05004 "fmt"
5
Jon Perrittd1d6a742014-09-17 01:10:59 -05006 "github.com/rackspace/gophercloud"
7 "github.com/rackspace/gophercloud/pagination"
Jon Perritt42b3a2a2014-10-02 23:06:07 -05008
9 "github.com/racker/perigee"
Jon Perrittee6074f2014-04-30 18:42:32 -050010)
11
Jon Perritt1c2356b2014-10-13 19:56:43 -050012// CreateOptsBuilder allows extensions to add additional parameters to the
13// Create request.
14type CreateOptsBuilder interface {
15 ToVolumeCreateMap() (map[string]interface{}, error)
16}
17
Jon Perritt42b3a2a2014-10-02 23:06:07 -050018// CreateOpts contains options for creating a Volume. This object is passed to
19// the volumes.Create function. For more information about these parameters,
20// see the Volume object.
Jon Perritt97347a02014-09-21 13:34:48 -050021type CreateOpts struct {
Jon Perritt1c2356b2014-10-13 19:56:43 -050022 // OPTIONAL
23 Availability string
24 // OPTIONAL
25 Description string
26 // OPTIONAL
27 Metadata map[string]string
28 // OPTIONAL
29 Name string
30 // REQUIRED
31 Size int
32 // OPTIONAL
33 SnapshotID, SourceVolID, ImageID string
34 // OPTIONAL
35 VolumeType string
36}
37
38// ToVolumeCreateMap assembles a request body based on the contents of a
39// CreateOpts.
40func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) {
41 v := make(map[string]interface{})
42
43 if opts.Size == 0 {
44 return nil, fmt.Errorf("Required CreateOpts field 'Size' not set.")
45 }
46 v["size"] = opts.Size
47
48 if opts.Availability != "" {
49 v["availability_zone"] = opts.Availability
50 }
51 if opts.Description != "" {
52 v["display_description"] = opts.Description
53 }
54 if opts.ImageID != "" {
55 v["imageRef"] = opts.ImageID
56 }
57 if opts.Metadata != nil {
58 v["metadata"] = opts.Metadata
59 }
60 if opts.Name != "" {
61 v["display_name"] = opts.Name
62 }
63 if opts.SourceVolID != "" {
64 v["source_volid"] = opts.SourceVolID
65 }
66 if opts.SnapshotID != "" {
67 v["snapshot_id"] = opts.SnapshotID
68 }
69 if opts.VolumeType != "" {
70 v["volume_type"] = opts.VolumeType
71 }
72
73 return map[string]interface{}{"volume": v}, nil
Jon Perrittee6074f2014-04-30 18:42:32 -050074}
Jon Perritte77b9b22014-05-01 13:11:12 -050075
Jon Perritt42b3a2a2014-10-02 23:06:07 -050076// Create will create a new Volume based on the values in CreateOpts. To extract
Jon Perritt1c2356b2014-10-13 19:56:43 -050077// the Volume object from the response, call the Extract method on the
78// CreateResult.
79func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
Jon Perritt6d5561b2014-10-01 21:42:15 -050080 var res CreateResult
Jon Perritt1c2356b2014-10-13 19:56:43 -050081
82 reqBody, err := opts.ToVolumeCreateMap()
83 if err != nil {
84 res.Err = err
85 return res
86 }
87
Jon Perritt6d5561b2014-10-01 21:42:15 -050088 _, res.Err = perigee.Request("POST", createURL(client), perigee.Options{
Ash Wilson77857dc2014-10-22 09:09:02 -040089 MoreHeaders: client.AuthenticatedHeaders(),
Jon Perritt04851d32014-10-14 02:07:13 -050090 ReqBody: &reqBody,
Ash Wilsond3dc2542014-10-20 10:10:48 -040091 Results: &res.Body,
Jon Perritt6d5561b2014-10-01 21:42:15 -050092 OkCodes: []int{200, 201},
Jon Perritt94963ad2014-05-05 12:14:39 -050093 })
Jon Perritt6d5561b2014-10-01 21:42:15 -050094 return res
Jon Perrittd1d6a742014-09-17 01:10:59 -050095}
96
Jon Perritt42b3a2a2014-10-02 23:06:07 -050097// Delete will delete the existing Volume with the provided ID.
Jamie Hannafordce9f9082014-10-27 11:27:12 +010098func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
99 var res DeleteResult
100 _, res.Err = perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
Ash Wilson77857dc2014-10-22 09:09:02 -0400101 MoreHeaders: client.AuthenticatedHeaders(),
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500102 OkCodes: []int{202, 204},
103 })
Jamie Hannafordce9f9082014-10-27 11:27:12 +0100104 return res
Jon Perritt6d5561b2014-10-01 21:42:15 -0500105}
Jon Perrittd1d6a742014-09-17 01:10:59 -0500106
Jon Perritt1c2356b2014-10-13 19:56:43 -0500107// Get retrieves the Volume with the provided ID. To extract the Volume object
108// from the response, call the Extract method on the GetResult.
Jon Perritt03cb46d2014-09-22 20:46:20 -0500109func Get(client *gophercloud.ServiceClient, id string) GetResult {
Jon Perritt6d5561b2014-10-01 21:42:15 -0500110 var res GetResult
111 _, res.Err = perigee.Request("GET", getURL(client, id), perigee.Options{
Ash Wilsond3dc2542014-10-20 10:10:48 -0400112 Results: &res.Body,
Ash Wilson77857dc2014-10-22 09:09:02 -0400113 MoreHeaders: client.AuthenticatedHeaders(),
Jon Perritt6d5561b2014-10-01 21:42:15 -0500114 OkCodes: []int{200},
Jon Perritt70dd47d2014-05-01 13:51:53 -0500115 })
Jon Perritt6d5561b2014-10-01 21:42:15 -0500116 return res
Jon Perritt70dd47d2014-05-01 13:51:53 -0500117}
118
Jon Perritt1c2356b2014-10-13 19:56:43 -0500119// ListOptsBuilder allows extensions to add additional parameters to the List
120// request.
121type ListOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -0500122 ToVolumeListQuery() (string, error)
Jon Perritt1c2356b2014-10-13 19:56:43 -0500123}
124
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500125// ListOpts holds options for listing Volumes. It is passed to the volumes.List
126// function.
127type ListOpts struct {
Jon Perritt1c2356b2014-10-13 19:56:43 -0500128 // admin-only option. Set it to true to see all tenant volumes.
129 AllTenants bool `q:"all_tenants"`
130 // List only volumes that contain Metadata.
131 Metadata map[string]string `q:"metadata"`
132 // List only volumes that have Name as the display name.
133 Name string `q:"name"`
134 // List only volumes that have a status of Status.
135 Status string `q:"status"`
136}
137
Jon Perritt26780d52014-10-14 11:35:58 -0500138// ToVolumeListQuery formats a ListOpts into a query string.
139func (opts ListOpts) ToVolumeListQuery() (string, error) {
Jon Perritt1c2356b2014-10-13 19:56:43 -0500140 q, err := gophercloud.BuildQueryString(opts)
141 if err != nil {
142 return "", err
143 }
144 return q.String(), nil
Jon Perritt97347a02014-09-21 13:34:48 -0500145}
146
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500147// List returns Volumes optionally limited by the conditions provided in ListOpts.
Jon Perritt1c2356b2014-10-13 19:56:43 -0500148func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
Jon Perritt0871a812014-10-03 11:02:35 -0500149 url := listURL(client)
150 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -0500151 query, err := opts.ToVolumeListQuery()
Jon Perritt0871a812014-10-03 11:02:35 -0500152 if err != nil {
153 return pagination.Pager{Err: err}
154 }
Jon Perritt1c2356b2014-10-13 19:56:43 -0500155 url += query
Jon Perritt0871a812014-10-03 11:02:35 -0500156 }
Ash Wilsonb8b16f82014-10-20 10:19:49 -0400157 createPage := func(r pagination.PageResult) pagination.Page {
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500158 return ListResult{pagination.SinglePageBase(r)}
159 }
Jon Perritt1c2356b2014-10-13 19:56:43 -0500160 return pagination.NewPager(client, url, createPage)
161}
162
163// UpdateOptsBuilder allows extensions to add additional parameters to the
164// Update request.
165type UpdateOptsBuilder interface {
166 ToVolumeUpdateMap() (map[string]interface{}, error)
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500167}
168
169// UpdateOpts contain options for updating an existing Volume. This object is passed
170// to the volumes.Update function. For more information about the parameters, see
171// the Volume object.
172type UpdateOpts struct {
Jon Perritt1c2356b2014-10-13 19:56:43 -0500173 // OPTIONAL
174 Name string
175 // OPTIONAL
176 Description string
177 // OPTIONAL
178 Metadata map[string]string
179}
180
181// ToVolumeUpdateMap assembles a request body based on the contents of an
182// UpdateOpts.
183func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) {
184 v := make(map[string]interface{})
185
186 if opts.Description != "" {
187 v["display_description"] = opts.Description
188 }
189 if opts.Metadata != nil {
190 v["metadata"] = opts.Metadata
191 }
192 if opts.Name != "" {
193 v["display_name"] = opts.Name
194 }
195
196 return map[string]interface{}{"volume": v}, nil
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500197}
198
199// Update will update the Volume with provided information. To extract the updated
200// Volume from the response, call the Extract method on the UpdateResult.
Jon Perritt04851d32014-10-14 02:07:13 -0500201func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
Jon Perritt6d5561b2014-10-01 21:42:15 -0500202 var res UpdateResult
Jon Perritt97347a02014-09-21 13:34:48 -0500203
Jon Perritt1c2356b2014-10-13 19:56:43 -0500204 reqBody, err := opts.ToVolumeUpdateMap()
205 if err != nil {
206 res.Err = err
207 return res
208 }
209
Jon Perritt6d5561b2014-10-01 21:42:15 -0500210 _, res.Err = perigee.Request("PUT", updateURL(client, id), perigee.Options{
Ash Wilson77857dc2014-10-22 09:09:02 -0400211 MoreHeaders: client.AuthenticatedHeaders(),
Jon Perritt97347a02014-09-21 13:34:48 -0500212 OkCodes: []int{200},
Jon Perritt04851d32014-10-14 02:07:13 -0500213 ReqBody: &reqBody,
Ash Wilsond3dc2542014-10-20 10:10:48 -0400214 Results: &res.Body,
Jon Perritt97347a02014-09-21 13:34:48 -0500215 })
Jon Perritt6d5561b2014-10-01 21:42:15 -0500216 return res
Jon Perritte77b9b22014-05-01 13:11:12 -0500217}