blob: 1e60f8a4e04c1abe4910163641a98c9170ce34f8 [file] [log] [blame]
Jon Perritt35e27e42014-12-05 11:10:46 -07001package stacks
2
3import (
4 "time"
5
6 "github.com/mitchellh/mapstructure"
7 "github.com/rackspace/gophercloud"
8 "github.com/rackspace/gophercloud/pagination"
9)
10
Jon Perritt7726e492015-02-04 17:54:28 -070011// CreatedStack represents the object extracted from a Create operation.
Jon Perritt01972e22015-01-28 10:30:45 -070012type CreatedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -070013 ID string `mapstructure:"id"`
14 Links []gophercloud.Link `mapstructure:"links"`
15}
16
Jon Perritt7726e492015-02-04 17:54:28 -070017// CreateResult represents the result of a Create operation.
Jon Perritt35e27e42014-12-05 11:10:46 -070018type CreateResult struct {
19 gophercloud.Result
20}
21
Jon Perritt7726e492015-02-04 17:54:28 -070022// Extract returns a pointer to a CreatedStack object and is called after a
23// Create operation.
Jon Perritt22325f42015-01-29 14:48:18 -070024func (r CreateResult) Extract() (*CreatedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -070025 if r.Err != nil {
26 return nil, r.Err
27 }
28
29 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -070030 Stack *CreatedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -070031 }
32
33 if err := mapstructure.Decode(r.Body, &res); err != nil {
34 return nil, err
35 }
36
37 return res.Stack, nil
38}
39
Jon Perritt7726e492015-02-04 17:54:28 -070040// AdoptResult represents the result of an Adopt operation. AdoptResult has the
41// same form as CreateResult.
Jon Perritt35e27e42014-12-05 11:10:46 -070042type AdoptResult struct {
Jon Perritt9741dd92015-02-04 12:05:47 -070043 CreateResult
Jon Perritt35e27e42014-12-05 11:10:46 -070044}
45
46// StackPage is a pagination.Pager that is returned from a call to the List function.
47type StackPage struct {
48 pagination.SinglePageBase
49}
50
51// IsEmpty returns true if a ListResult contains no Stacks.
52func (r StackPage) IsEmpty() (bool, error) {
53 stacks, err := ExtractStacks(r)
54 if err != nil {
55 return true, err
56 }
57 return len(stacks) == 0, nil
58}
59
Jon Perritt7726e492015-02-04 17:54:28 -070060// ListedStack represents an element in the slice extracted from a List operation.
Jon Perritt01972e22015-01-28 10:30:45 -070061type ListedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -070062 CreationTime time.Time `mapstructure:"-"`
63 Description string `mapstructure:"description"`
64 ID string `mapstructure:"id"`
65 Links []gophercloud.Link `mapstructure:"links"`
66 Name string `mapstructure:"stack_name"`
67 Status string `mapstructure:"stack_status"`
Jon Perritt01972e22015-01-28 10:30:45 -070068 StatusReason string `mapstructure:"stack_status_reason"`
Jon Perritt35e27e42014-12-05 11:10:46 -070069 UpdatedTime time.Time `mapstructure:"-"`
70}
71
Jon Perritt7726e492015-02-04 17:54:28 -070072// ExtractStacks extracts and returns a slice of ListedStack. It is used while iterating
Jon Perritt35e27e42014-12-05 11:10:46 -070073// over a stacks.List call.
Jon Perritt22325f42015-01-29 14:48:18 -070074func ExtractStacks(page pagination.Page) ([]ListedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -070075 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -070076 Stacks []ListedStack `mapstructure:"stacks"`
Jon Perritt35e27e42014-12-05 11:10:46 -070077 }
78
79 err := mapstructure.Decode(page.(StackPage).Body, &res)
Jon Perritt01972e22015-01-28 10:30:45 -070080 if err != nil {
81 return nil, err
82 }
83
84 rawStacks := (((page.(StackPage).Body).(map[string]interface{}))["stacks"]).([]interface{})
85 for i := range rawStacks {
Jon Perritt9cd3d382015-02-04 15:49:41 -070086 thisStack := (rawStacks[i]).(map[string]interface{})
Jon Perritt01972e22015-01-28 10:30:45 -070087
Jon Perritt9cd3d382015-02-04 15:49:41 -070088 if t, ok := thisStack["creation_time"].(string); ok && t != "" {
89 creationTime, err := time.Parse(time.RFC3339, t)
90 if err != nil {
91 return res.Stacks, err
92 }
93 res.Stacks[i].CreationTime = creationTime
Jon Perritt01972e22015-01-28 10:30:45 -070094 }
Jon Perritt9cd3d382015-02-04 15:49:41 -070095
96 if t, ok := thisStack["updated_time"].(string); ok && t != "" {
97 updatedTime, err := time.Parse(time.RFC3339, t)
98 if err != nil {
99 return res.Stacks, err
100 }
101 res.Stacks[i].UpdatedTime = updatedTime
102 }
Jon Perritt01972e22015-01-28 10:30:45 -0700103 }
104
105 return res.Stacks, nil
Jon Perritt35e27e42014-12-05 11:10:46 -0700106}
107
Jon Perritt7726e492015-02-04 17:54:28 -0700108// RetrievedStack represents the object extracted from a Get operation.
Jon Perritt01972e22015-01-28 10:30:45 -0700109type RetrievedStack struct {
Jon Perritt7726e492015-02-04 17:54:28 -0700110 Capabilities []interface{} `mapstructure:"capabilities"`
111 CreationTime time.Time `mapstructure:"-"`
112 Description string `mapstructure:"description"`
113 DisableRollback bool `mapstructure:"disable_rollback"`
114 ID string `mapstructure:"id"`
115 Links []gophercloud.Link `mapstructure:"links"`
116 NotificationTopics []interface{} `mapstructure:"notification_topics"`
117 Outputs []map[string]interface{} `mapstructure:"outputs"`
118 Parameters map[string]string `mapstructure:"parameters"`
119 Name string `mapstructure:"stack_name"`
120 Status string `mapstructure:"stack_status"`
121 StatusReason string `mapstructure:"stack_status_reason"`
122 TemplateDescription string `mapstructure:"template_description"`
123 Timeout int `mapstructure:"timeout_mins"`
124 UpdatedTime time.Time `mapstructure:"-"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700125}
126
Jon Perritt7726e492015-02-04 17:54:28 -0700127// GetResult represents the result of a Get operation.
Jon Perritt35e27e42014-12-05 11:10:46 -0700128type GetResult struct {
129 gophercloud.Result
130}
131
Jon Perritt7726e492015-02-04 17:54:28 -0700132// Extract returns a pointer to a RetrievedStack object and is called after a
133// Get operation.
Jon Perritt22325f42015-01-29 14:48:18 -0700134func (r GetResult) Extract() (*RetrievedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -0700135 if r.Err != nil {
136 return nil, r.Err
137 }
138
139 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -0700140 Stack *RetrievedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700141 }
142
143 config := &mapstructure.DecoderConfig{
144 Result: &res,
145 WeaklyTypedInput: true,
146 }
147 decoder, err := mapstructure.NewDecoder(config)
148 if err != nil {
149 return nil, err
150 }
151
152 if err := decoder.Decode(r.Body); err != nil {
153 return nil, err
154 }
155
156 b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
157
158 if date, ok := b["creation_time"]; ok && date != nil {
159 t, err := time.Parse(time.RFC3339, date.(string))
160 if err != nil {
161 return nil, err
162 }
163 res.Stack.CreationTime = t
164 }
165
166 if date, ok := b["updated_time"]; ok && date != nil {
167 t, err := time.Parse(time.RFC3339, date.(string))
168 if err != nil {
169 return nil, err
170 }
171 res.Stack.UpdatedTime = t
172 }
173
174 return res.Stack, err
175}
176
Jon Perritt7726e492015-02-04 17:54:28 -0700177// UpdateResult represents the result of a Update operation.
Jon Perritt35e27e42014-12-05 11:10:46 -0700178type UpdateResult struct {
179 gophercloud.ErrResult
180}
181
Jon Perritt7726e492015-02-04 17:54:28 -0700182// DeleteResult represents the result of a Delete operation.
Jon Perritt35e27e42014-12-05 11:10:46 -0700183type DeleteResult struct {
184 gophercloud.ErrResult
185}
186
Jon Perritt37f97742015-02-04 18:55:05 -0700187// PreviewedStack represents the result of a Preview operation.
Jon Perritt01972e22015-01-28 10:30:45 -0700188type PreviewedStack struct {
Jon Perritt37f97742015-02-04 18:55:05 -0700189 Capabilities []interface{} `mapstructure:"capabilities"`
190 CreationTime time.Time `mapstructure:"-"`
191 Description string `mapstructure:"description"`
192 DisableRollback bool `mapstructure:"disable_rollback"`
193 ID string `mapstructure:"id"`
194 Links []gophercloud.Link `mapstructure:"links"`
195 Name string `mapstructure:"stack_name"`
196 NotificationTopics []interface{} `mapstructure:"notification_topics"`
197 Parameters map[string]string `mapstructure:"parameters"`
198 Resources []map[string]interface{} `mapstructure:"resources"`
199 Status string `mapstructure:"stack_status"`
200 StatusReason string `mapstructure:"stack_status_reason"`
201 TemplateDescription string `mapstructure:"template_description"`
202 Timeout int `mapstructure:"timeout_mins"`
203 UpdatedTime time.Time `mapstructure:"-"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700204}
205
Jon Perritt37f97742015-02-04 18:55:05 -0700206// PreviewResult represents the result of a Preview operation.
Jon Perritt35e27e42014-12-05 11:10:46 -0700207type PreviewResult struct {
208 gophercloud.Result
209}
210
Jon Perritt37f97742015-02-04 18:55:05 -0700211// Extract returns a pointer to a PreviewedStack object and is called after a
212// Preview operation.
Jon Perritt22325f42015-01-29 14:48:18 -0700213func (r PreviewResult) Extract() (*PreviewedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -0700214 if r.Err != nil {
215 return nil, r.Err
216 }
217
218 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -0700219 Stack *PreviewedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700220 }
221
222 config := &mapstructure.DecoderConfig{
223 Result: &res,
224 WeaklyTypedInput: true,
225 }
226 decoder, err := mapstructure.NewDecoder(config)
227 if err != nil {
228 return nil, err
229 }
230
231 if err := decoder.Decode(r.Body); err != nil {
232 return nil, err
233 }
234
235 b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
236
237 if date, ok := b["creation_time"]; ok && date != nil {
238 t, err := time.Parse(time.RFC3339, date.(string))
239 if err != nil {
240 return nil, err
241 }
242 res.Stack.CreationTime = t
243 }
244
245 if date, ok := b["updated_time"]; ok && date != nil {
246 t, err := time.Parse(time.RFC3339, date.(string))
247 if err != nil {
248 return nil, err
249 }
250 res.Stack.UpdatedTime = t
251 }
252
253 return res.Stack, err
254}
255
Jon Perritt9209df42015-02-05 12:55:33 -0700256// AbandonedStack represents the result of an Abandon operation.
Jon Perritt01972e22015-01-28 10:30:45 -0700257type AbandonedStack struct {
Jon Perritt9209df42015-02-05 12:55:33 -0700258 Status string `mapstructure:"status"`
259 Name string `mapstructure:"name"`
Jon Perritt6ec27cf2015-02-09 12:51:41 -0700260 Template map[string]interface{} `mapstructure:"template"`
Jon Perritt9209df42015-02-05 12:55:33 -0700261 Action string `mapstructure:"action"`
262 ID string `mapstructure:"id"`
263 Resources map[string]interface{} `mapstructure:"resources"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700264}
265
Jon Perritt9209df42015-02-05 12:55:33 -0700266// AbandonResult represents the result of an Abandon operation.
Jon Perritt35e27e42014-12-05 11:10:46 -0700267type AbandonResult struct {
268 gophercloud.Result
269}
Jon Perritt9209df42015-02-05 12:55:33 -0700270
271// Extract returns a pointer to an AbandonedStack object and is called after an
272// Abandon operation.
273func (r AbandonResult) Extract() (*AbandonedStack, error) {
274 if r.Err != nil {
275 return nil, r.Err
276 }
277
278 var res AbandonedStack
279
280 if err := mapstructure.Decode(r.Body, &res); err != nil {
281 return nil, err
282 }
283
284 return &res, nil
285}