blob: 886642534904fa7f01f83cd9835fe7f7733bec0d [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 Perritt01972e22015-01-28 10:30:45 -070011type CreatedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -070012 ID string `mapstructure:"id"`
13 Links []gophercloud.Link `mapstructure:"links"`
14}
15
16type CreateResult struct {
17 gophercloud.Result
18}
19
Jon Perritt22325f42015-01-29 14:48:18 -070020func (r CreateResult) Extract() (*CreatedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -070021 if r.Err != nil {
22 return nil, r.Err
23 }
24
25 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -070026 Stack *CreatedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -070027 }
28
29 if err := mapstructure.Decode(r.Body, &res); err != nil {
30 return nil, err
31 }
32
33 return res.Stack, nil
34}
35
36type AdoptResult struct {
Jon Perritt9741dd92015-02-04 12:05:47 -070037 CreateResult
Jon Perritt35e27e42014-12-05 11:10:46 -070038}
39
40// StackPage is a pagination.Pager that is returned from a call to the List function.
41type StackPage struct {
42 pagination.SinglePageBase
43}
44
45// IsEmpty returns true if a ListResult contains no Stacks.
46func (r StackPage) IsEmpty() (bool, error) {
47 stacks, err := ExtractStacks(r)
48 if err != nil {
49 return true, err
50 }
51 return len(stacks) == 0, nil
52}
53
Jon Perritt01972e22015-01-28 10:30:45 -070054type ListedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -070055 CreationTime time.Time `mapstructure:"-"`
56 Description string `mapstructure:"description"`
57 ID string `mapstructure:"id"`
58 Links []gophercloud.Link `mapstructure:"links"`
59 Name string `mapstructure:"stack_name"`
60 Status string `mapstructure:"stack_status"`
Jon Perritt01972e22015-01-28 10:30:45 -070061 StatusReason string `mapstructure:"stack_status_reason"`
Jon Perritt35e27e42014-12-05 11:10:46 -070062 UpdatedTime time.Time `mapstructure:"-"`
63}
64
65// ExtractStacks extracts and returns a slice of Stacks. It is used while iterating
66// over a stacks.List call.
Jon Perritt22325f42015-01-29 14:48:18 -070067func ExtractStacks(page pagination.Page) ([]ListedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -070068 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -070069 Stacks []ListedStack `mapstructure:"stacks"`
Jon Perritt35e27e42014-12-05 11:10:46 -070070 }
71
72 err := mapstructure.Decode(page.(StackPage).Body, &res)
Jon Perritt01972e22015-01-28 10:30:45 -070073 if err != nil {
74 return nil, err
75 }
76
77 rawStacks := (((page.(StackPage).Body).(map[string]interface{}))["stacks"]).([]interface{})
78 for i := range rawStacks {
Jon Perritt9cd3d382015-02-04 15:49:41 -070079 thisStack := (rawStacks[i]).(map[string]interface{})
Jon Perritt01972e22015-01-28 10:30:45 -070080
Jon Perritt9cd3d382015-02-04 15:49:41 -070081 if t, ok := thisStack["creation_time"].(string); ok && t != "" {
82 creationTime, err := time.Parse(time.RFC3339, t)
83 if err != nil {
84 return res.Stacks, err
85 }
86 res.Stacks[i].CreationTime = creationTime
Jon Perritt01972e22015-01-28 10:30:45 -070087 }
Jon Perritt9cd3d382015-02-04 15:49:41 -070088
89 if t, ok := thisStack["updated_time"].(string); ok && t != "" {
90 updatedTime, err := time.Parse(time.RFC3339, t)
91 if err != nil {
92 return res.Stacks, err
93 }
94 res.Stacks[i].UpdatedTime = updatedTime
95 }
Jon Perritt01972e22015-01-28 10:30:45 -070096 }
97
98 return res.Stacks, nil
Jon Perritt35e27e42014-12-05 11:10:46 -070099}
100
Jon Perritt01972e22015-01-28 10:30:45 -0700101type RetrievedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -0700102 Capabilities []interface{} `mapstructure:"capabilities"`
103 CreationTime time.Time `mapstructure:"-"`
104 Description string `mapstructure:"description"`
105 DisableRollback bool `mapstructure:"disable_rollback"`
106 ID string `mapstructure:"id"`
107 Links []gophercloud.Link `mapstructure:"links"`
108 NotificationTopics []interface{} `mapstructure:"notification_topics"`
109 Outputs []map[string]string `mapstructure:"outputs"`
110 Parameters map[string]string `mapstructure:"parameters"`
111 Name string `mapstructure:"stack_name"`
112 Status string `mapstructure:"stack_status"`
113 StausReason string `mapstructure:"stack_status_reason"`
114 TemplateDescription string `mapstructure:"template_description"`
115 Timeout int `mapstructure:"timeout_mins"`
116 UpdatedTime time.Time `mapstructure:"-"`
117}
118
119type GetResult struct {
120 gophercloud.Result
121}
122
Jon Perritt22325f42015-01-29 14:48:18 -0700123func (r GetResult) Extract() (*RetrievedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -0700124 if r.Err != nil {
125 return nil, r.Err
126 }
127
128 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -0700129 Stack *RetrievedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700130 }
131
132 config := &mapstructure.DecoderConfig{
133 Result: &res,
134 WeaklyTypedInput: true,
135 }
136 decoder, err := mapstructure.NewDecoder(config)
137 if err != nil {
138 return nil, err
139 }
140
141 if err := decoder.Decode(r.Body); err != nil {
142 return nil, err
143 }
144
145 b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
146
147 if date, ok := b["creation_time"]; ok && date != nil {
148 t, err := time.Parse(time.RFC3339, date.(string))
149 if err != nil {
150 return nil, err
151 }
152 res.Stack.CreationTime = t
153 }
154
155 if date, ok := b["updated_time"]; ok && date != nil {
156 t, err := time.Parse(time.RFC3339, date.(string))
157 if err != nil {
158 return nil, err
159 }
160 res.Stack.UpdatedTime = t
161 }
162
163 return res.Stack, err
164}
165
166type UpdateResult struct {
167 gophercloud.ErrResult
168}
169
170type DeleteResult struct {
171 gophercloud.ErrResult
172}
173
Jon Perritt01972e22015-01-28 10:30:45 -0700174type PreviewedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -0700175 Capabilities []interface{} `mapstructure:"capabilities"`
176 CreationTime time.Time `mapstructure:"-"`
177 Description string `mapstructure:"description"`
178 DisableRollback bool `mapstructure:"disable_rollback"`
179 ID string `mapstructure:"id"`
180 Links []gophercloud.Link `mapstructure:"links"`
181 Name string `mapstructure:"stack_name"`
182 NotificationTopics []interface{} `mapstructure:"notification_topics"`
183 Parameters map[string]string `mapstructure:"parameters"`
184 Resources []map[string]string `mapstructure:"resources"`
185 Status string `mapstructure:"stack_status"`
186 StausReason string `mapstructure:"stack_status_reason"`
187 TemplateDescription string `mapstructure:"template_description"`
188 Timeout int `mapstructure:"timeout_mins"`
189 UpdatedTime time.Time `mapstructure:"-"`
190}
191
192type PreviewResult struct {
193 gophercloud.Result
194}
195
Jon Perritt22325f42015-01-29 14:48:18 -0700196func (r PreviewResult) Extract() (*PreviewedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -0700197 if r.Err != nil {
198 return nil, r.Err
199 }
200
201 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -0700202 Stack *PreviewedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700203 }
204
205 config := &mapstructure.DecoderConfig{
206 Result: &res,
207 WeaklyTypedInput: true,
208 }
209 decoder, err := mapstructure.NewDecoder(config)
210 if err != nil {
211 return nil, err
212 }
213
214 if err := decoder.Decode(r.Body); err != nil {
215 return nil, err
216 }
217
218 b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
219
220 if date, ok := b["creation_time"]; ok && date != nil {
221 t, err := time.Parse(time.RFC3339, date.(string))
222 if err != nil {
223 return nil, err
224 }
225 res.Stack.CreationTime = t
226 }
227
228 if date, ok := b["updated_time"]; ok && date != nil {
229 t, err := time.Parse(time.RFC3339, date.(string))
230 if err != nil {
231 return nil, err
232 }
233 res.Stack.UpdatedTime = t
234 }
235
236 return res.Stack, err
237}
238
Jon Perritt01972e22015-01-28 10:30:45 -0700239type AbandonedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -0700240}
241
242type AbandonResult struct {
243 gophercloud.Result
244}