blob: 62f4f6b9370f637d6ebbe3fa2a135802cab7d265 [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 {
79 creationTime, err := time.Parse(time.RFC3339, ((rawStacks[i]).(map[string]interface{}))["creation_time"].(string))
80 if err != nil {
81 return res.Stacks, err
82 }
83 res.Stacks[i].CreationTime = creationTime
84
85 updatedTime, err := time.Parse(time.RFC3339, ((rawStacks[i]).(map[string]interface{}))["updated_time"].(string))
86 if err != nil {
87 return res.Stacks, err
88 }
89 res.Stacks[i].UpdatedTime = updatedTime
90 }
91
92 return res.Stacks, nil
Jon Perritt35e27e42014-12-05 11:10:46 -070093}
94
Jon Perritt01972e22015-01-28 10:30:45 -070095type RetrievedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -070096 Capabilities []interface{} `mapstructure:"capabilities"`
97 CreationTime time.Time `mapstructure:"-"`
98 Description string `mapstructure:"description"`
99 DisableRollback bool `mapstructure:"disable_rollback"`
100 ID string `mapstructure:"id"`
101 Links []gophercloud.Link `mapstructure:"links"`
102 NotificationTopics []interface{} `mapstructure:"notification_topics"`
103 Outputs []map[string]string `mapstructure:"outputs"`
104 Parameters map[string]string `mapstructure:"parameters"`
105 Name string `mapstructure:"stack_name"`
106 Status string `mapstructure:"stack_status"`
107 StausReason string `mapstructure:"stack_status_reason"`
108 TemplateDescription string `mapstructure:"template_description"`
109 Timeout int `mapstructure:"timeout_mins"`
110 UpdatedTime time.Time `mapstructure:"-"`
111}
112
113type GetResult struct {
114 gophercloud.Result
115}
116
Jon Perritt22325f42015-01-29 14:48:18 -0700117func (r GetResult) Extract() (*RetrievedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -0700118 if r.Err != nil {
119 return nil, r.Err
120 }
121
122 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -0700123 Stack *RetrievedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700124 }
125
126 config := &mapstructure.DecoderConfig{
127 Result: &res,
128 WeaklyTypedInput: true,
129 }
130 decoder, err := mapstructure.NewDecoder(config)
131 if err != nil {
132 return nil, err
133 }
134
135 if err := decoder.Decode(r.Body); err != nil {
136 return nil, err
137 }
138
139 b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
140
141 if date, ok := b["creation_time"]; ok && date != nil {
142 t, err := time.Parse(time.RFC3339, date.(string))
143 if err != nil {
144 return nil, err
145 }
146 res.Stack.CreationTime = t
147 }
148
149 if date, ok := b["updated_time"]; ok && date != nil {
150 t, err := time.Parse(time.RFC3339, date.(string))
151 if err != nil {
152 return nil, err
153 }
154 res.Stack.UpdatedTime = t
155 }
156
157 return res.Stack, err
158}
159
160type UpdateResult struct {
161 gophercloud.ErrResult
162}
163
164type DeleteResult struct {
165 gophercloud.ErrResult
166}
167
Jon Perritt01972e22015-01-28 10:30:45 -0700168type PreviewedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -0700169 Capabilities []interface{} `mapstructure:"capabilities"`
170 CreationTime time.Time `mapstructure:"-"`
171 Description string `mapstructure:"description"`
172 DisableRollback bool `mapstructure:"disable_rollback"`
173 ID string `mapstructure:"id"`
174 Links []gophercloud.Link `mapstructure:"links"`
175 Name string `mapstructure:"stack_name"`
176 NotificationTopics []interface{} `mapstructure:"notification_topics"`
177 Parameters map[string]string `mapstructure:"parameters"`
178 Resources []map[string]string `mapstructure:"resources"`
179 Status string `mapstructure:"stack_status"`
180 StausReason string `mapstructure:"stack_status_reason"`
181 TemplateDescription string `mapstructure:"template_description"`
182 Timeout int `mapstructure:"timeout_mins"`
183 UpdatedTime time.Time `mapstructure:"-"`
184}
185
186type PreviewResult struct {
187 gophercloud.Result
188}
189
Jon Perritt22325f42015-01-29 14:48:18 -0700190func (r PreviewResult) Extract() (*PreviewedStack, error) {
Jon Perritt35e27e42014-12-05 11:10:46 -0700191 if r.Err != nil {
192 return nil, r.Err
193 }
194
195 var res struct {
Jon Perritt22325f42015-01-29 14:48:18 -0700196 Stack *PreviewedStack `mapstructure:"stack"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700197 }
198
199 config := &mapstructure.DecoderConfig{
200 Result: &res,
201 WeaklyTypedInput: true,
202 }
203 decoder, err := mapstructure.NewDecoder(config)
204 if err != nil {
205 return nil, err
206 }
207
208 if err := decoder.Decode(r.Body); err != nil {
209 return nil, err
210 }
211
212 b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
213
214 if date, ok := b["creation_time"]; ok && date != nil {
215 t, err := time.Parse(time.RFC3339, date.(string))
216 if err != nil {
217 return nil, err
218 }
219 res.Stack.CreationTime = t
220 }
221
222 if date, ok := b["updated_time"]; ok && date != nil {
223 t, err := time.Parse(time.RFC3339, date.(string))
224 if err != nil {
225 return nil, err
226 }
227 res.Stack.UpdatedTime = t
228 }
229
230 return res.Stack, err
231}
232
Jon Perritt01972e22015-01-28 10:30:45 -0700233type AbandonedStack struct {
Jon Perritt35e27e42014-12-05 11:10:46 -0700234}
235
236type AbandonResult struct {
237 gophercloud.Result
238}