blob: 7c063b23a18b770f5d035137294f932c4976e391 [file] [log] [blame]
Jon Perrittee6074f2014-04-30 18:42:32 -05001package volumes
2
3import (
Jon Perritt27249f42016-02-18 10:35:59 -06004 "github.com/gophercloud/gophercloud"
5 "github.com/gophercloud/gophercloud/pagination"
Jon Perrittee6074f2014-04-30 18:42:32 -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 ToVolumeCreateMap() (map[string]interface{}, error)
12}
13
Jon Perritt42b3a2a2014-10-02 23:06:07 -050014// CreateOpts contains options for creating a Volume. This object is passed to
15// the volumes.Create function. For more information about these parameters,
16// see the Volume object.
Jon Perritt97347a02014-09-21 13:34:48 -050017type CreateOpts struct {
Jon Perrittdb0ae142016-03-13 00:33:41 -060018 Size int `json:"size" required:"true"`
19 Availability string `json:"availability,omitempty"`
20 Description string `json:"description,omitempty"`
21 Metadata map[string]string `json:"metadata,omitempty"`
22 Name string `json:"name,omitempty"`
23 SnapshotID string `json:"snapshot_id,omitempty"`
24 SourceVolID string `json:"source_volid,omitempty"`
25 ImageID string `json:"imageRef,omitempty"`
26 VolumeType string `json:"volume_type,omitempty"`
Jon Perritt1c2356b2014-10-13 19:56:43 -050027}
28
29// ToVolumeCreateMap assembles a request body based on the contents of a
30// CreateOpts.
31func (opts CreateOpts) ToVolumeCreateMap() (map[string]interface{}, error) {
Jon Perrittdb0ae142016-03-13 00:33:41 -060032 return gophercloud.BuildRequestBody(opts, "volume")
Jon Perrittee6074f2014-04-30 18:42:32 -050033}
Jon Perritte77b9b22014-05-01 13:11:12 -050034
Jon Perritt42b3a2a2014-10-02 23:06:07 -050035// Create will create a new Volume based on the values in CreateOpts. To extract
Jon Perritt1c2356b2014-10-13 19:56:43 -050036// the Volume object from the response, call the Extract method on the
37// CreateResult.
38func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -060039 var r CreateResult
40 b, err := opts.ToVolumeCreateMap()
Jon Perritt1c2356b2014-10-13 19:56:43 -050041 if err != nil {
Jon Perrittdb0ae142016-03-13 00:33:41 -060042 r.Err = err
43 return r
Jon Perritt1c2356b2014-10-13 19:56:43 -050044 }
Jon Perrittdb0ae142016-03-13 00:33:41 -060045 _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford6181fdb2015-03-24 14:55:50 +010046 OkCodes: []int{200, 201},
Jon Perritt94963ad2014-05-05 12:14:39 -050047 })
Jon Perrittdb0ae142016-03-13 00:33:41 -060048 return r
Jon Perrittd1d6a742014-09-17 01:10:59 -050049}
50
Jon Perritt42b3a2a2014-10-02 23:06:07 -050051// Delete will delete the existing Volume with the provided ID.
Jamie Hannafordce9f9082014-10-27 11:27:12 +010052func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -060053 var r DeleteResult
54 _, r.Err = client.Delete(deleteURL(client, id), nil)
55 return r
Jon Perritt6d5561b2014-10-01 21:42:15 -050056}
Jon Perrittd1d6a742014-09-17 01:10:59 -050057
Jon Perritt1c2356b2014-10-13 19:56:43 -050058// Get retrieves the Volume with the provided ID. To extract the Volume object
59// from the response, call the Extract method on the GetResult.
Jon Perritt03cb46d2014-09-22 20:46:20 -050060func Get(client *gophercloud.ServiceClient, id string) GetResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -060061 var r GetResult
62 _, r.Err = client.Get(getURL(client, id), &r.Body, nil)
63 return r
Jon Perritt70dd47d2014-05-01 13:51:53 -050064}
65
Jon Perritt1c2356b2014-10-13 19:56:43 -050066// ListOptsBuilder allows extensions to add additional parameters to the List
67// request.
68type ListOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -050069 ToVolumeListQuery() (string, error)
Jon Perritt1c2356b2014-10-13 19:56:43 -050070}
71
Jon Perritt42b3a2a2014-10-02 23:06:07 -050072// ListOpts holds options for listing Volumes. It is passed to the volumes.List
73// function.
74type ListOpts struct {
Jon Perritt1c2356b2014-10-13 19:56:43 -050075 // admin-only option. Set it to true to see all tenant volumes.
76 AllTenants bool `q:"all_tenants"`
77 // List only volumes that contain Metadata.
78 Metadata map[string]string `q:"metadata"`
79 // List only volumes that have Name as the display name.
80 Name string `q:"name"`
81 // List only volumes that have a status of Status.
82 Status string `q:"status"`
83}
84
Jon Perritt26780d52014-10-14 11:35:58 -050085// ToVolumeListQuery formats a ListOpts into a query string.
86func (opts ListOpts) ToVolumeListQuery() (string, error) {
Jon Perritt1c2356b2014-10-13 19:56:43 -050087 q, err := gophercloud.BuildQueryString(opts)
Jon Perrittdb0ae142016-03-13 00:33:41 -060088 return q.String(), err
Jon Perritt97347a02014-09-21 13:34:48 -050089}
90
Jon Perritt42b3a2a2014-10-02 23:06:07 -050091// List returns Volumes optionally limited by the conditions provided in ListOpts.
Jon Perritt1c2356b2014-10-13 19:56:43 -050092func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
Jon Perritt0871a812014-10-03 11:02:35 -050093 url := listURL(client)
94 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -050095 query, err := opts.ToVolumeListQuery()
Jon Perritt0871a812014-10-03 11:02:35 -050096 if err != nil {
97 return pagination.Pager{Err: err}
98 }
Jon Perritt1c2356b2014-10-13 19:56:43 -050099 url += query
Jon Perritt0871a812014-10-03 11:02:35 -0500100 }
Jon Perrittdb0ae142016-03-13 00:33:41 -0600101 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
Jon Perritt12395212016-02-24 10:41:17 -0600102 return VolumePage{pagination.SinglePageBase(r)}
Jon Perrittdb0ae142016-03-13 00:33:41 -0600103 })
Jon Perritt1c2356b2014-10-13 19:56:43 -0500104}
105
106// UpdateOptsBuilder allows extensions to add additional parameters to the
107// Update request.
108type UpdateOptsBuilder interface {
109 ToVolumeUpdateMap() (map[string]interface{}, error)
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500110}
111
112// UpdateOpts contain options for updating an existing Volume. This object is passed
113// to the volumes.Update function. For more information about the parameters, see
114// the Volume object.
115type UpdateOpts struct {
Jon Perritt1c2356b2014-10-13 19:56:43 -0500116 // OPTIONAL
Jon Perrittdb0ae142016-03-13 00:33:41 -0600117 Name string `json:"name,omitempty"`
Jon Perritt1c2356b2014-10-13 19:56:43 -0500118 // OPTIONAL
Jon Perrittdb0ae142016-03-13 00:33:41 -0600119 Description string `json:"description,omitempty"`
Jon Perritt1c2356b2014-10-13 19:56:43 -0500120 // OPTIONAL
Jon Perrittdb0ae142016-03-13 00:33:41 -0600121 Metadata map[string]string `json:"metadata,omitempty"`
Jon Perritt1c2356b2014-10-13 19:56:43 -0500122}
123
124// ToVolumeUpdateMap assembles a request body based on the contents of an
125// UpdateOpts.
126func (opts UpdateOpts) ToVolumeUpdateMap() (map[string]interface{}, error) {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600127 return gophercloud.BuildRequestBody(opts, "volume")
Jon Perritt42b3a2a2014-10-02 23:06:07 -0500128}
129
130// Update will update the Volume with provided information. To extract the updated
131// Volume from the response, call the Extract method on the UpdateResult.
Jon Perritt04851d32014-10-14 02:07:13 -0500132func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600133 var r UpdateResult
134 b, err := opts.ToVolumeUpdateMap()
Jon Perritt1c2356b2014-10-13 19:56:43 -0500135 if err != nil {
Jon Perrittdb0ae142016-03-13 00:33:41 -0600136 r.Err = err
137 return r
Jon Perritt1c2356b2014-10-13 19:56:43 -0500138 }
Jon Perrittdb0ae142016-03-13 00:33:41 -0600139 _, r.Err = client.Put(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford6181fdb2015-03-24 14:55:50 +0100140 OkCodes: []int{200},
Jon Perritt97347a02014-09-21 13:34:48 -0500141 })
Jon Perrittdb0ae142016-03-13 00:33:41 -0600142 return r
Jon Perritte77b9b22014-05-01 13:11:12 -0500143}
Jon Perritt24c20832015-06-30 09:57:00 -0600144
145// IDFromName is a convienience function that returns a server's ID given its name.
146func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
Jon Perritted258942016-02-28 23:38:21 -0600147 count := 0
148 id := ""
Jon Perritted258942016-02-28 23:38:21 -0600149 pages, err := List(client, nil).AllPages()
150 if err != nil {
151 return "", err
152 }
Jon Perritt24c20832015-06-30 09:57:00 -0600153
Jon Perritted258942016-02-28 23:38:21 -0600154 all, err := ExtractVolumes(pages)
155 if err != nil {
156 return "", err
157 }
158
159 for _, s := range all {
160 if s.Name == name {
161 count++
162 id = s.ID
163 }
164 }
165
166 switch count {
Jon Perritt24c20832015-06-30 09:57:00 -0600167 case 0:
Jon Perrittdb0ae142016-03-13 00:33:41 -0600168 return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "volume"}
Jon Perritt24c20832015-06-30 09:57:00 -0600169 case 1:
Jon Perritted258942016-02-28 23:38:21 -0600170 return id, nil
Jon Perritt24c20832015-06-30 09:57:00 -0600171 default:
Jon Perrittdb0ae142016-03-13 00:33:41 -0600172 return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "volume"}
Jon Perritt24c20832015-06-30 09:57:00 -0600173 }
174}