blob: fa2202ce2b8f1f75ae2010734ec4c1f3e8e6abbe [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.
98func Delete(client *gophercloud.ServiceClient, id string) error {
99 _, err := perigee.Request("DELETE", deleteURL(client, id), perigee.Options{
Ash Wilson77857dc2014-10-22 09:09:02 -0400100 MoreHeaders: client.AuthenticatedHeaders(),
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500101 OkCodes: []int{202, 204},
102 })
103 return err
Jon Perritt6d5561b2014-10-01 21:42:15 -0500104}
Jon Perrittd1d6a742014-09-17 01:10:59 -0500105
Jon Perritt1c2356b2014-10-13 19:56:43 -0500106// Get retrieves the Volume with the provided ID. To extract the Volume object
107// from the response, call the Extract method on the GetResult.
Jon Perritt03cb46d2014-09-22 20:46:20 -0500108func Get(client *gophercloud.ServiceClient, id string) GetResult {
Jon Perritt6d5561b2014-10-01 21:42:15 -0500109 var res GetResult
110 _, res.Err = perigee.Request("GET", getURL(client, id), perigee.Options{
Ash Wilsond3dc2542014-10-20 10:10:48 -0400111 Results: &res.Body,
Ash Wilson77857dc2014-10-22 09:09:02 -0400112 MoreHeaders: client.AuthenticatedHeaders(),
Jon Perritt6d5561b2014-10-01 21:42:15 -0500113 OkCodes: []int{200},
Jon Perritt70dd47d2014-05-01 13:51:53 -0500114 })
Jon Perritt6d5561b2014-10-01 21:42:15 -0500115 return res
Jon Perritt70dd47d2014-05-01 13:51:53 -0500116}
117
Jon Perritt1c2356b2014-10-13 19:56:43 -0500118// ListOptsBuilder allows extensions to add additional parameters to the List
119// request.
120type ListOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -0500121 ToVolumeListQuery() (string, error)
Jon Perritt1c2356b2014-10-13 19:56:43 -0500122}
123
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500124// ListOpts holds options for listing Volumes. It is passed to the volumes.List
125// function.
126type ListOpts struct {
Jon Perritt1c2356b2014-10-13 19:56:43 -0500127 // admin-only option. Set it to true to see all tenant volumes.
128 AllTenants bool `q:"all_tenants"`
129 // List only volumes that contain Metadata.
130 Metadata map[string]string `q:"metadata"`
131 // List only volumes that have Name as the display name.
132 Name string `q:"name"`
133 // List only volumes that have a status of Status.
134 Status string `q:"status"`
135}
136
Jon Perritt26780d52014-10-14 11:35:58 -0500137// ToVolumeListQuery formats a ListOpts into a query string.
138func (opts ListOpts) ToVolumeListQuery() (string, error) {
Jon Perritt1c2356b2014-10-13 19:56:43 -0500139 q, err := gophercloud.BuildQueryString(opts)
140 if err != nil {
141 return "", err
142 }
143 return q.String(), nil
Jon Perritt97347a02014-09-21 13:34:48 -0500144}
145
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500146// List returns Volumes optionally limited by the conditions provided in ListOpts.
Jon Perritt1c2356b2014-10-13 19:56:43 -0500147func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
Jon Perritt0871a812014-10-03 11:02:35 -0500148 url := listURL(client)
149 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -0500150 query, err := opts.ToVolumeListQuery()
Jon Perritt0871a812014-10-03 11:02:35 -0500151 if err != nil {
152 return pagination.Pager{Err: err}
153 }
Jon Perritt1c2356b2014-10-13 19:56:43 -0500154 url += query
Jon Perritt0871a812014-10-03 11:02:35 -0500155 }
Ash Wilsonb8b16f82014-10-20 10:19:49 -0400156 createPage := func(r pagination.PageResult) pagination.Page {
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500157 return ListResult{pagination.SinglePageBase(r)}
158 }
Jon Perritt1c2356b2014-10-13 19:56:43 -0500159 return pagination.NewPager(client, url, createPage)
160}
161
162// UpdateOptsBuilder allows extensions to add additional parameters to the
163// Update request.
164type UpdateOptsBuilder interface {
165 ToVolumeUpdateMap() (map[string]interface{}, error)
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500166}
167
168// UpdateOpts contain options for updating an existing Volume. This object is passed
169// to the volumes.Update function. For more information about the parameters, see
170// the Volume object.
171type UpdateOpts struct {
Jon Perritt1c2356b2014-10-13 19:56:43 -0500172 // OPTIONAL
173 Name string
174 // OPTIONAL
175 Description string
176 // OPTIONAL
177 Metadata map[string]string
178}
179
180// ToVolumeUpdateMap assembles a request body based on the contents of an
181// UpdateOpts.
182func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) {
183 v := make(map[string]interface{})
184
185 if opts.Description != "" {
186 v["display_description"] = opts.Description
187 }
188 if opts.Metadata != nil {
189 v["metadata"] = opts.Metadata
190 }
191 if opts.Name != "" {
192 v["display_name"] = opts.Name
193 }
194
195 return map[string]interface{}{"volume": v}, nil
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500196}
197
198// Update will update the Volume with provided information. To extract the updated
199// Volume from the response, call the Extract method on the UpdateResult.
Jon Perritt04851d32014-10-14 02:07:13 -0500200func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
Jon Perritt6d5561b2014-10-01 21:42:15 -0500201 var res UpdateResult
Jon Perritt97347a02014-09-21 13:34:48 -0500202
Jon Perritt1c2356b2014-10-13 19:56:43 -0500203 reqBody, err := opts.ToVolumeUpdateMap()
204 if err != nil {
205 res.Err = err
206 return res
207 }
208
Jon Perritt6d5561b2014-10-01 21:42:15 -0500209 _, res.Err = perigee.Request("PUT", updateURL(client, id), perigee.Options{
Ash Wilson77857dc2014-10-22 09:09:02 -0400210 MoreHeaders: client.AuthenticatedHeaders(),
Jon Perritt97347a02014-09-21 13:34:48 -0500211 OkCodes: []int{200},
Jon Perritt04851d32014-10-14 02:07:13 -0500212 ReqBody: &reqBody,
Ash Wilsond3dc2542014-10-20 10:10:48 -0400213 Results: &res.Body,
Jon Perritt97347a02014-09-21 13:34:48 -0500214 })
Jon Perritt6d5561b2014-10-01 21:42:15 -0500215 return res
Jon Perritte77b9b22014-05-01 13:11:12 -0500216}