blob: 10c003a4230e0cc1cef6125b100865e49ef46703 [file] [log] [blame]
Samuel A. Falvo IIc007c272014-02-10 20:49:26 -08001package servers
2
3import (
Samuel A. Falvo IIe246ac02014-02-13 23:20:09 -08004 "github.com/mitchellh/mapstructure"
Ash Wilsond27e0ff2014-09-25 11:50:31 -04005 "github.com/rackspace/gophercloud"
Ash Wilson01626a32014-09-17 10:38:07 -04006 "github.com/rackspace/gophercloud/pagination"
Samuel A. Falvo IIc007c272014-02-10 20:49:26 -08007)
8
Ash Wilson397c78b2014-09-25 15:19:14 -04009type serverResult struct {
Ash Wilsonf548aad2014-10-20 08:35:34 -040010 gophercloud.Result
Ash Wilson397c78b2014-09-25 15:19:14 -040011}
12
13// Extract interprets any serverResult as a Server, if possible.
14func (r serverResult) Extract() (*Server, error) {
15 if r.Err != nil {
16 return nil, r.Err
17 }
18
19 var response struct {
20 Server Server `mapstructure:"server"`
21 }
22
Ash Wilsond3dc2542014-10-20 10:10:48 -040023 err := mapstructure.Decode(r.Body, &response)
Ash Wilson397c78b2014-09-25 15:19:14 -040024 return &response.Server, err
25}
26
27// CreateResult temporarily contains the response from a Create call.
28type CreateResult struct {
29 serverResult
30}
31
32// GetResult temporarily contains the response from a Get call.
33type GetResult struct {
34 serverResult
35}
36
37// UpdateResult temporarily contains the response from an Update call.
38type UpdateResult struct {
39 serverResult
40}
41
Jon Perrittcc77da62014-11-16 13:14:21 -070042// DeleteResult temporarily contains the response from a Delete call.
Jamie Hannaford34732fe2014-10-27 11:29:36 +010043type DeleteResult struct {
Jon Perrittba2395e2014-10-27 15:23:21 -050044 gophercloud.ErrResult
Jamie Hannaford34732fe2014-10-27 11:29:36 +010045}
46
Ash Wilson397c78b2014-09-25 15:19:14 -040047// RebuildResult temporarily contains the response from a Rebuild call.
Jamie Hannaford01c1efe2014-10-16 15:08:59 +020048type RebuildResult struct {
Ash Wilson397c78b2014-09-25 15:19:14 -040049 serverResult
50}
Samuel A. Falvo IIc007c272014-02-10 20:49:26 -080051
Jamie Hannaford01c1efe2014-10-16 15:08:59 +020052// ActionResult represents the result of server action operations, like reboot
53type ActionResult struct {
Jon Perrittba2395e2014-10-27 15:23:21 -050054 gophercloud.ErrResult
Jamie Hannaford01c1efe2014-10-16 15:08:59 +020055}
56
Alex Gaynor587e3e32014-11-13 10:39:09 -080057// RescueResult represents the result of a server rescue operation
Alex Gaynorfbe61bb2014-11-12 13:35:03 -080058type RescueResult struct {
59 ActionResult
Alex Gaynor7f3b06e2014-11-13 09:54:03 -080060}
61
Jon Perrittcc77da62014-11-16 13:14:21 -070062// Extract interprets any RescueResult as an AdminPass, if possible.
Alex Gaynor7f3b06e2014-11-13 09:54:03 -080063func (r RescueResult) Extract() (string, error) {
64 if r.Err != nil {
Alex Gaynor94a28aa2014-11-13 10:09:56 -080065 return "", r.Err
Alex Gaynor7f3b06e2014-11-13 09:54:03 -080066 }
67
68 var response struct {
69 AdminPass string `mapstructure:"adminPass"`
70 }
71
72 err := mapstructure.Decode(r.Body, &response)
Alex Gaynor94a28aa2014-11-13 10:09:56 -080073 return response.AdminPass, err
Alex Gaynorfbe61bb2014-11-12 13:35:03 -080074}
75
Samuel A. Falvo IIc007c272014-02-10 20:49:26 -080076// Server exposes only the standard OpenStack fields corresponding to a given server on the user's account.
Samuel A. Falvo IIc007c272014-02-10 20:49:26 -080077type Server struct {
Ash Wilson01626a32014-09-17 10:38:07 -040078 // ID uniquely identifies this server amongst all other servers, including those not accessible to the current tenant.
79 ID string
80
81 // TenantID identifies the tenant owning this server resource.
82 TenantID string `mapstructure:"tenant_id"`
83
84 // UserID uniquely identifies the user account owning the tenant.
85 UserID string `mapstructure:"user_id"`
86
87 // Name contains the human-readable name for the server.
88 Name string
89
90 // Updated and Created contain ISO-8601 timestamps of when the state of the server last changed, and when it was created.
91 Updated string
92 Created string
93
94 HostID string
95
96 // Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE.
97 Status string
98
99 // Progress ranges from 0..100.
100 // A request made against the server completes only once Progress reaches 100.
101 Progress int
102
103 // AccessIPv4 and AccessIPv6 contain the IP addresses of the server, suitable for remote access for administration.
Jamie Hannaford908e1e92014-10-27 14:41:17 +0100104 AccessIPv4, AccessIPv6 string
Ash Wilson01626a32014-09-17 10:38:07 -0400105
106 // Image refers to a JSON object, which itself indicates the OS image used to deploy the server.
107 Image map[string]interface{}
108
109 // Flavor refers to a JSON object, which itself indicates the hardware configuration of the deployed server.
110 Flavor map[string]interface{}
111
112 // Addresses includes a list of all IP addresses assigned to the server, keyed by pool.
Ash Wilson01626a32014-09-17 10:38:07 -0400113 Addresses map[string]interface{}
114
115 // Metadata includes a list of all user-specified key-value pairs attached to the server.
116 Metadata map[string]interface{}
117
118 // Links includes HTTP references to the itself, useful for passing along to other APIs that might want a server reference.
119 Links []interface{}
120
Ash Wilsonad21c712014-09-25 10:15:22 -0400121 // KeyName indicates which public key was injected into the server on launch.
Ash Wilson69b144f2014-10-21 14:03:52 -0400122 KeyName string `json:"key_name" mapstructure:"key_name"`
Ash Wilsonad21c712014-09-25 10:15:22 -0400123
Ash Wilson01626a32014-09-17 10:38:07 -0400124 // AdminPass will generally be empty (""). However, it will contain the administrative password chosen when provisioning a new server without a set AdminPass setting in the first place.
125 // Note that this is the ONLY time this field will be valid.
Ash Wilson69b144f2014-10-21 14:03:52 -0400126 AdminPass string `json:"adminPass" mapstructure:"adminPass"`
Samuel A. Falvo IIc007c272014-02-10 20:49:26 -0800127}
128
Ash Wilson397c78b2014-09-25 15:19:14 -0400129// ServerPage abstracts the raw results of making a List() request against the API.
130// As OpenStack extensions may freely alter the response bodies of structures returned to the client, you may only safely access the
131// data provided through the ExtractServers call.
132type ServerPage struct {
133 pagination.LinkedPageBase
Ash Wilsonf57381e2014-09-25 13:21:34 -0400134}
135
Ash Wilson397c78b2014-09-25 15:19:14 -0400136// IsEmpty returns true if a page contains no Server results.
137func (page ServerPage) IsEmpty() (bool, error) {
138 servers, err := ExtractServers(page)
139 if err != nil {
140 return true, err
141 }
142 return len(servers) == 0, nil
143}
144
145// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
146func (page ServerPage) NextPageURL() (string, error) {
Ash Wilson397c78b2014-09-25 15:19:14 -0400147 type resp struct {
Jamie Hannaforda581acd2014-10-08 17:14:13 +0200148 Links []gophercloud.Link `mapstructure:"servers_links"`
Ash Wilsond27e0ff2014-09-25 11:50:31 -0400149 }
150
Ash Wilson397c78b2014-09-25 15:19:14 -0400151 var r resp
152 err := mapstructure.Decode(page.Body, &r)
153 if err != nil {
154 return "", err
Ash Wilsond27e0ff2014-09-25 11:50:31 -0400155 }
156
Jamie Hannaforda581acd2014-10-08 17:14:13 +0200157 return gophercloud.ExtractNextURL(r.Links)
Ash Wilsond27e0ff2014-09-25 11:50:31 -0400158}
159
Ash Wilson01626a32014-09-17 10:38:07 -0400160// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities.
161func ExtractServers(page pagination.Page) ([]Server, error) {
Ash Wilson397c78b2014-09-25 15:19:14 -0400162 casted := page.(ServerPage).Body
Ash Wilson12259392014-09-17 10:50:02 -0400163
164 var response struct {
165 Servers []Server `mapstructure:"servers"`
166 }
167 err := mapstructure.Decode(casted, &response)
168 return response.Servers, err
Samuel A. Falvo IIc007c272014-02-10 20:49:26 -0800169}
Jon Perrittcc77da62014-11-16 13:14:21 -0700170
171// MetadatasResult contains the result of a call for (potentially) multiple key-value pairs.
172type MetadatasResult struct {
173 gophercloud.Result
174}
175
176// GetMetadatasResult temporarily contains the response from a metadatas Get call.
177type GetMetadatasResult struct {
178 MetadatasResult
179}
180
181// CreateMetadatasResult temporarily contains the response from a metadatas Create call.
182type CreateMetadatasResult struct {
183 MetadatasResult
184}
185
186// UpdateMetadatasResult temporarily contains the response from a metadatas Update call.
187type UpdateMetadatasResult struct {
188 MetadatasResult
189}
190
191// MetadataResult contains the result of a call for individual a single key-value pair.
192type MetadataResult struct {
193 gophercloud.Result
194}
195
196// GetMetadataResult temporarily contains the response from a metadata Get call.
197type GetMetadataResult struct {
198 MetadataResult
199}
200
201// CreateMetadataResult temporarily contains the response from a metadata Create call.
202type CreateMetadataResult struct {
203 MetadataResult
204}
205
206// DeleteMetadataResult temporarily contains the response from a metadata Delete call.
207type DeleteMetadataResult struct {
208 gophercloud.ErrResult
209}
210
211// Extract interprets any MetadatasResult as a Metadatas, if possible.
212func (r MetadatasResult) Extract() (map[string]string, error) {
213 if r.Err != nil {
214 return nil, r.Err
215 }
216
217 var response struct {
218 Metadatas map[string]string `mapstructure:"metadata"`
219 }
220
221 err := mapstructure.Decode(r.Body, &response)
222 return response.Metadatas, err
223}
224
225// Extract interprets any MetadataResult as a Metadata, if possible.
226func (r MetadataResult) Extract() (map[string]string, error) {
227 if r.Err != nil {
228 return nil, r.Err
229 }
230
231 var response struct {
232 Metadata map[string]string `mapstructure:"meta"`
233 }
234
235 err := mapstructure.Decode(r.Body, &response)
236 return response.Metadata, err
237}