blob: d69031c8e6a20850d10232c0665df2224af88dac [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 Perritt01972e22015-01-28 10:30:45 -0700187type PreviewedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -0700188 Capabilities []interface{} `mapstructure:"capabilities"`
189 CreationTime time.Time `mapstructure:"-"`
190 Description string `mapstructure:"description"`
191 DisableRollback bool `mapstructure:"disable_rollback"`
192 ID string `mapstructure:"id"`
193 Links []gophercloud.Link `mapstructure:"links"`
194 Name string `mapstructure:"stack_name"`
195 NotificationTopics []interface{} `mapstructure:"notification_topics"`
196 Parameters map[string]string `mapstructure:"parameters"`
197 Resources []map[string]string `mapstructure:"resources"`
198 Status string `mapstructure:"stack_status"`
199 StausReason string `mapstructure:"stack_status_reason"`
200 TemplateDescription string `mapstructure:"template_description"`
201 Timeout int `mapstructure:"timeout_mins"`
202 UpdatedTime time.Time `mapstructure:"-"`
203}
204
205type PreviewResult struct {
206 gophercloud.Result
207}
208
Jon Perritt22325f42015-01-29 14:48:18 -0700209func (r PreviewResult) Extract() (*PreviewedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -0700210 if r.Err != nil {
211 return nil, r.Err
212 }
213
214 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -0700215 Stack *PreviewedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700216 }
217
218 config := &mapstructure.DecoderConfig{
219 Result: &res,
220 WeaklyTypedInput: true,
221 }
222 decoder, err := mapstructure.NewDecoder(config)
223 if err != nil {
224 return nil, err
225 }
226
227 if err := decoder.Decode(r.Body); err != nil {
228 return nil, err
229 }
230
231 b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
232
233 if date, ok := b["creation_time"]; ok && date != nil {
234 t, err := time.Parse(time.RFC3339, date.(string))
235 if err != nil {
236 return nil, err
237 }
238 res.Stack.CreationTime = t
239 }
240
241 if date, ok := b["updated_time"]; ok && date != nil {
242 t, err := time.Parse(time.RFC3339, date.(string))
243 if err != nil {
244 return nil, err
245 }
246 res.Stack.UpdatedTime = t
247 }
248
249 return res.Stack, err
250}
251
Jon Perritt01972e22015-01-28 10:30:45 -0700252type AbandonedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -0700253}
254
255type AbandonResult struct {
256 gophercloud.Result
257}