blob: 91f38ee7e60448a8c254d15df7d2ff90620edfad [file] [log] [blame]
Jon Perritt35e27e42014-12-05 11:10:46 -07001package stacks
2
3import (
Pratik Mallya827c03e2015-09-17 00:10:47 -05004 "strings"
Jon Perritt35e27e42014-12-05 11:10:46 -07005
Jon Perritt27249f42016-02-18 10:35:59 -06006 "github.com/gophercloud/gophercloud"
7 "github.com/gophercloud/gophercloud/pagination"
Jon Perritt35e27e42014-12-05 11:10:46 -07008)
9
10// CreateOptsBuilder is the interface options structs have to satisfy in order
11// to be used in the main Create operation in this package. Since many
12// extensions decorate or modify the common logic, it is useful for them to
13// satisfy a basic interface in order for them to be used.
14type CreateOptsBuilder interface {
15 ToStackCreateMap() (map[string]interface{}, error)
16}
17
18// CreateOpts is the common options struct used in this package's Create
19// operation.
20type CreateOpts struct {
Jon Perrittfea90732016-03-15 02:57:05 -050021 // The name of the stack. It must start with an alphabetic character.
22 Name string `json:"stack_name" required:"true"`
23 // A structure that contains either the template file or url. Call the
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050024 // associated methods to extract the information relevant to send in a create request.
Jon Perrittfea90732016-03-15 02:57:05 -050025 TemplateOpts *Template `json:"-" required:"true"`
26 // Enables or disables deletion of all stack resources when a stack
Jon Perritt952f3e12015-02-03 12:13:24 -070027 // creation fails. Default is true, meaning all resources are not deleted when
28 // stack creation fails.
Jon Perrittfea90732016-03-15 02:57:05 -050029 DisableRollback *bool `json:"disable_rollback,omitempty"`
30 // A structure that contains details for the environment of the stack.
31 EnvironmentOpts *Environment `json:"-"`
32 // User-defined parameters to pass to the template.
33 Parameters map[string]string `json:"parameters,omitempty"`
34 // The timeout for stack creation in minutes.
35 Timeout int `json:"timeout_mins,omitempty"`
36 // A list of tags to assosciate with the Stack
37 Tags []string `json:"-"`
Jon Perritt35e27e42014-12-05 11:10:46 -070038}
39
40// ToStackCreateMap casts a CreateOpts struct to a map.
41func (opts CreateOpts) ToStackCreateMap() (map[string]interface{}, error) {
Jon Perrittfea90732016-03-15 02:57:05 -050042 b, err := gophercloud.BuildRequestBody(opts, "")
43 if err != nil {
Jon Perritt58611da2016-03-09 00:49:57 -060044 return nil, err
Jon Perritt35e27e42014-12-05 11:10:46 -070045 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050046
Jon Perrittfea90732016-03-15 02:57:05 -050047 if err := opts.TemplateOpts.Parse(); err != nil {
48 return nil, err
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050049 }
Jon Perrittfea90732016-03-15 02:57:05 -050050
51 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
52 return nil, err
53 }
54 opts.TemplateOpts.fixFileRefs()
55 b["template"] = string(opts.TemplateOpts.Bin)
56
57 files := make(map[string]string)
58 for k, v := range opts.TemplateOpts.Files {
59 files[k] = v
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050060 }
61
62 if opts.EnvironmentOpts != nil {
63 if err := opts.EnvironmentOpts.Parse(); err != nil {
64 return nil, err
65 }
Pratik Mallyaa979f5b2015-09-22 03:10:55 -050066 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil {
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050067 return nil, err
68 }
Pratik Mallyaa979f5b2015-09-22 03:10:55 -050069 opts.EnvironmentOpts.fixFileRefs()
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050070 for k, v := range opts.EnvironmentOpts.Files {
Jon Perrittfea90732016-03-15 02:57:05 -050071 files[k] = v
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050072 }
Jon Perrittfea90732016-03-15 02:57:05 -050073 b["environment"] = string(opts.EnvironmentOpts.Bin)
Pratik Mallya5fddb2a2015-09-14 14:04:49 -050074 }
75
Jon Perrittfea90732016-03-15 02:57:05 -050076 if len(files) > 0 {
77 b["files"] = files
Jon Perritt35e27e42014-12-05 11:10:46 -070078 }
79
Pratik Mallya827c03e2015-09-17 00:10:47 -050080 if opts.Tags != nil {
Jon Perrittfea90732016-03-15 02:57:05 -050081 b["tags"] = strings.Join(opts.Tags, ",")
Pratik Mallya827c03e2015-09-17 00:10:47 -050082 }
Jon Perrittfea90732016-03-15 02:57:05 -050083
84 return b, nil
Jon Perritt35e27e42014-12-05 11:10:46 -070085}
86
87// Create accepts a CreateOpts struct and creates a new stack using the values
88// provided.
Jon Perritt3860b512016-03-29 12:01:48 -050089func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
Jon Perrittfea90732016-03-15 02:57:05 -050090 b, err := opts.ToStackCreateMap()
Jon Perritt35e27e42014-12-05 11:10:46 -070091 if err != nil {
Jon Perrittfea90732016-03-15 02:57:05 -050092 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -050093 return
Jon Perritt35e27e42014-12-05 11:10:46 -070094 }
Jon Perrittfea90732016-03-15 02:57:05 -050095 _, r.Err = c.Post(createURL(c), b, &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -050096 return
Jon Perritt35e27e42014-12-05 11:10:46 -070097}
98
99// AdoptOptsBuilder is the interface options structs have to satisfy in order
100// to be used in the Adopt function in this package. Since many
101// extensions decorate or modify the common logic, it is useful for them to
102// satisfy a basic interface in order for them to be used.
103type AdoptOptsBuilder interface {
104 ToStackAdoptMap() (map[string]interface{}, error)
105}
106
107// AdoptOpts is the common options struct used in this package's Adopt
108// operation.
109type AdoptOpts struct {
Jon Perrittfea90732016-03-15 02:57:05 -0500110 // Existing resources data represented as a string to add to the
Jon Perritt9741dd92015-02-04 12:05:47 -0700111 // new stack. Data returned by Abandon could be provided as AdoptsStackData.
Jon Perrittfea90732016-03-15 02:57:05 -0500112 AdoptStackData string `json:"adopt_stack_data" required:"true"`
113 // The name of the stack. It must start with an alphabetic character.
114 Name string `json:"stack_name" required:"true"`
Jon Perritt397ade62016-03-15 06:55:02 -0500115 // A structure that contains either the template file or url. Call the
116 // associated methods to extract the information relevant to send in a create request.
117 TemplateOpts *Template `json:"-" required:"true"`
Jon Perrittfea90732016-03-15 02:57:05 -0500118 // The timeout for stack creation in minutes.
119 Timeout int `json:"timeout_mins,omitempty"`
120 // A structure that contains either the template file or url. Call the
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500121 // associated methods to extract the information relevant to send in a create request.
Jon Perrittfea90732016-03-15 02:57:05 -0500122 //TemplateOpts *Template `json:"-" required:"true"`
123 // Enables or disables deletion of all stack resources when a stack
Jon Perritt9741dd92015-02-04 12:05:47 -0700124 // creation fails. Default is true, meaning all resources are not deleted when
125 // stack creation fails.
Jon Perrittfea90732016-03-15 02:57:05 -0500126 DisableRollback *bool `json:"disable_rollback,omitempty"`
127 // A structure that contains details for the environment of the stack.
128 EnvironmentOpts *Environment `json:"-"`
129 // User-defined parameters to pass to the template.
130 Parameters map[string]string `json:"parameters,omitempty"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700131}
132
133// ToStackAdoptMap casts a CreateOpts struct to a map.
134func (opts AdoptOpts) ToStackAdoptMap() (map[string]interface{}, error) {
Jon Perrittfea90732016-03-15 02:57:05 -0500135 b, err := gophercloud.BuildRequestBody(opts, "")
136 if err != nil {
Jon Perritt58611da2016-03-09 00:49:57 -0600137 return nil, err
Jon Perritt35e27e42014-12-05 11:10:46 -0700138 }
Jon Perrittfea90732016-03-15 02:57:05 -0500139
Jon Perritt397ade62016-03-15 06:55:02 -0500140 if err := opts.TemplateOpts.Parse(); err != nil {
141 return nil, err
142 }
143
144 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
145 return nil, err
146 }
147 opts.TemplateOpts.fixFileRefs()
148 b["template"] = string(opts.TemplateOpts.Bin)
149
Jon Perrittfea90732016-03-15 02:57:05 -0500150 files := make(map[string]string)
Jon Perritt397ade62016-03-15 06:55:02 -0500151 for k, v := range opts.TemplateOpts.Files {
152 files[k] = v
153 }
Jon Perritt35e27e42014-12-05 11:10:46 -0700154
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500155 if opts.EnvironmentOpts != nil {
156 if err := opts.EnvironmentOpts.Parse(); err != nil {
157 return nil, err
158 }
Pratik Mallyaa979f5b2015-09-22 03:10:55 -0500159 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil {
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500160 return nil, err
161 }
Pratik Mallyaa979f5b2015-09-22 03:10:55 -0500162 opts.EnvironmentOpts.fixFileRefs()
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500163 for k, v := range opts.EnvironmentOpts.Files {
Jon Perrittfea90732016-03-15 02:57:05 -0500164 files[k] = v
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500165 }
Jon Perrittfea90732016-03-15 02:57:05 -0500166 b["environment"] = string(opts.EnvironmentOpts.Bin)
Jon Perritt35e27e42014-12-05 11:10:46 -0700167 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500168
Jon Perrittfea90732016-03-15 02:57:05 -0500169 if len(files) > 0 {
170 b["files"] = files
Jon Perritt35e27e42014-12-05 11:10:46 -0700171 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500172
Jon Perrittfea90732016-03-15 02:57:05 -0500173 return b, nil
Jon Perritt35e27e42014-12-05 11:10:46 -0700174}
175
176// Adopt accepts an AdoptOpts struct and creates a new stack using the resources
177// from another stack.
Jon Perritt3860b512016-03-29 12:01:48 -0500178func Adopt(c *gophercloud.ServiceClient, opts AdoptOptsBuilder) (r AdoptResult) {
Jon Perrittfea90732016-03-15 02:57:05 -0500179 b, err := opts.ToStackAdoptMap()
Jon Perritt35e27e42014-12-05 11:10:46 -0700180 if err != nil {
Jon Perrittfea90732016-03-15 02:57:05 -0500181 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500182 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700183 }
Jon Perrittfea90732016-03-15 02:57:05 -0500184 _, r.Err = c.Post(adoptURL(c), b, &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500185 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700186}
187
188// SortDir is a type for specifying in which direction to sort a list of stacks.
189type SortDir string
190
191// SortKey is a type for specifying by which key to sort a list of stacks.
192type SortKey string
193
194var (
195 // SortAsc is used to sort a list of stacks in ascending order.
196 SortAsc SortDir = "asc"
197 // SortDesc is used to sort a list of stacks in descending order.
198 SortDesc SortDir = "desc"
199 // SortName is used to sort a list of stacks by name.
200 SortName SortKey = "name"
201 // SortStatus is used to sort a list of stacks by status.
202 SortStatus SortKey = "status"
203 // SortCreatedAt is used to sort a list of stacks by date created.
204 SortCreatedAt SortKey = "created_at"
205 // SortUpdatedAt is used to sort a list of stacks by date updated.
206 SortUpdatedAt SortKey = "updated_at"
207)
208
209// ListOptsBuilder allows extensions to add additional parameters to the
210// List request.
211type ListOptsBuilder interface {
212 ToStackListQuery() (string, error)
213}
214
215// ListOpts allows the filtering and sorting of paginated collections through
216// the API. Filtering is achieved by passing in struct field values that map to
217// the network attributes you want to see returned. SortKey allows you to sort
218// by a particular network attribute. SortDir sets the direction, and is either
219// `asc' or `desc'. Marker and Limit are used for pagination.
220type ListOpts struct {
221 Status string `q:"status"`
222 Name string `q:"name"`
223 Marker string `q:"marker"`
224 Limit int `q:"limit"`
225 SortKey SortKey `q:"sort_keys"`
226 SortDir SortDir `q:"sort_dir"`
227}
228
229// ToStackListQuery formats a ListOpts into a query string.
230func (opts ListOpts) ToStackListQuery() (string, error) {
231 q, err := gophercloud.BuildQueryString(opts)
232 if err != nil {
233 return "", err
234 }
235 return q.String(), nil
236}
237
238// List returns a Pager which allows you to iterate over a collection of
239// stacks. It accepts a ListOpts struct, which allows you to filter and sort
240// the returned collection for greater efficiency.
241func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
242 url := listURL(c)
243 if opts != nil {
244 query, err := opts.ToStackListQuery()
245 if err != nil {
246 return pagination.Pager{Err: err}
247 }
248 url += query
249 }
Jon Perritt35e27e42014-12-05 11:10:46 -0700250 createPage := func(r pagination.PageResult) pagination.Page {
251 return StackPage{pagination.SinglePageBase(r)}
252 }
253 return pagination.NewPager(c, url, createPage)
254}
255
256// Get retreives a stack based on the stack name and stack ID.
jrperritt29ae6b32016-04-13 12:59:37 -0500257func Get(c *gophercloud.ServiceClient, stackName, stackID string) (r GetResult) {
Jon Perrittfea90732016-03-15 02:57:05 -0500258 _, r.Err = c.Get(getURL(c, stackName, stackID), &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500259 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700260}
261
262// UpdateOptsBuilder is the interface options structs have to satisfy in order
263// to be used in the Update operation in this package.
264type UpdateOptsBuilder interface {
265 ToStackUpdateMap() (map[string]interface{}, error)
266}
267
268// UpdateOpts contains the common options struct used in this package's Update
269// operation.
270type UpdateOpts struct {
Jon Perrittfea90732016-03-15 02:57:05 -0500271 // A structure that contains either the template file or url. Call the
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500272 // associated methods to extract the information relevant to send in a create request.
Jon Perrittfea90732016-03-15 02:57:05 -0500273 TemplateOpts *Template `json:"-" required:"true"`
274 // A structure that contains details for the environment of the stack.
275 EnvironmentOpts *Environment `json:"-"`
276 // User-defined parameters to pass to the template.
277 Parameters map[string]string `json:"parameters,omitempty"`
278 // The timeout for stack creation in minutes.
279 Timeout int `json:"timeout_mins,omitempty"`
280 // A list of tags to assosciate with the Stack
281 Tags []string `json:"-"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700282}
283
284// ToStackUpdateMap casts a CreateOpts struct to a map.
285func (opts UpdateOpts) ToStackUpdateMap() (map[string]interface{}, error) {
Jon Perrittfea90732016-03-15 02:57:05 -0500286 b, err := gophercloud.BuildRequestBody(opts, "")
287 if err != nil {
288 return nil, err
289 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500290
Jon Perrittfea90732016-03-15 02:57:05 -0500291 if err := opts.TemplateOpts.Parse(); err != nil {
292 return nil, err
293 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500294
Jon Perrittfea90732016-03-15 02:57:05 -0500295 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
296 return nil, err
297 }
298 opts.TemplateOpts.fixFileRefs()
299 b["template"] = string(opts.TemplateOpts.Bin)
300
301 files := make(map[string]string)
302 for k, v := range opts.TemplateOpts.Files {
303 files[k] = v
Jon Perritt35e27e42014-12-05 11:10:46 -0700304 }
305
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500306 if opts.EnvironmentOpts != nil {
307 if err := opts.EnvironmentOpts.Parse(); err != nil {
308 return nil, err
309 }
Pratik Mallyaa979f5b2015-09-22 03:10:55 -0500310 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil {
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500311 return nil, err
312 }
Pratik Mallyaa979f5b2015-09-22 03:10:55 -0500313 opts.EnvironmentOpts.fixFileRefs()
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500314 for k, v := range opts.EnvironmentOpts.Files {
Jon Perrittfea90732016-03-15 02:57:05 -0500315 files[k] = v
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500316 }
Jon Perrittfea90732016-03-15 02:57:05 -0500317 b["environment"] = string(opts.EnvironmentOpts.Bin)
Jon Perritt35e27e42014-12-05 11:10:46 -0700318 }
319
Jon Perrittfea90732016-03-15 02:57:05 -0500320 if len(files) > 0 {
321 b["files"] = files
Jon Perritt35e27e42014-12-05 11:10:46 -0700322 }
323
Pratik Mallya827c03e2015-09-17 00:10:47 -0500324 if opts.Tags != nil {
Jon Perrittfea90732016-03-15 02:57:05 -0500325 b["tags"] = strings.Join(opts.Tags, ",")
Pratik Mallya827c03e2015-09-17 00:10:47 -0500326 }
327
Jon Perrittfea90732016-03-15 02:57:05 -0500328 return b, nil
Jon Perritt35e27e42014-12-05 11:10:46 -0700329}
330
331// Update accepts an UpdateOpts struct and updates an existing stack using the values
332// provided.
Jon Perritt3860b512016-03-29 12:01:48 -0500333func Update(c *gophercloud.ServiceClient, stackName, stackID string, opts UpdateOptsBuilder) (r UpdateResult) {
Jon Perrittfea90732016-03-15 02:57:05 -0500334 b, err := opts.ToStackUpdateMap()
Jon Perritt35e27e42014-12-05 11:10:46 -0700335 if err != nil {
Jon Perrittfea90732016-03-15 02:57:05 -0500336 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500337 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700338 }
Jon Perrittfea90732016-03-15 02:57:05 -0500339 _, r.Err = c.Put(updateURL(c, stackName, stackID), b, nil, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500340 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700341}
342
343// Delete deletes a stack based on the stack name and stack ID.
Jon Perritt3860b512016-03-29 12:01:48 -0500344func Delete(c *gophercloud.ServiceClient, stackName, stackID string) (r DeleteResult) {
Jon Perrittfea90732016-03-15 02:57:05 -0500345 _, r.Err = c.Delete(deleteURL(c, stackName, stackID), nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500346 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700347}
348
349// PreviewOptsBuilder is the interface options structs have to satisfy in order
350// to be used in the Preview operation in this package.
351type PreviewOptsBuilder interface {
352 ToStackPreviewMap() (map[string]interface{}, error)
353}
354
355// PreviewOpts contains the common options struct used in this package's Preview
356// operation.
357type PreviewOpts struct {
Jon Perrittfea90732016-03-15 02:57:05 -0500358 // The name of the stack. It must start with an alphabetic character.
359 Name string `json:"stack_name" required:"true"`
360 // The timeout for stack creation in minutes.
361 Timeout int `json:"timeout_mins" required:"true"`
362 // A structure that contains either the template file or url. Call the
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500363 // associated methods to extract the information relevant to send in a create request.
Jon Perrittfea90732016-03-15 02:57:05 -0500364 TemplateOpts *Template `json:"-" required:"true"`
365 // Enables or disables deletion of all stack resources when a stack
Jon Perritt37f97742015-02-04 18:55:05 -0700366 // creation fails. Default is true, meaning all resources are not deleted when
367 // stack creation fails.
Jon Perrittfea90732016-03-15 02:57:05 -0500368 DisableRollback *bool `json:"disable_rollback,omitempty"`
369 // A structure that contains details for the environment of the stack.
370 EnvironmentOpts *Environment `json:"-"`
371 // User-defined parameters to pass to the template.
372 Parameters map[string]string `json:"parameters,omitempty"`
Jon Perritt35e27e42014-12-05 11:10:46 -0700373}
374
375// ToStackPreviewMap casts a PreviewOpts struct to a map.
376func (opts PreviewOpts) ToStackPreviewMap() (map[string]interface{}, error) {
Jon Perrittfea90732016-03-15 02:57:05 -0500377 b, err := gophercloud.BuildRequestBody(opts, "")
378 if err != nil {
Jon Perritt58611da2016-03-09 00:49:57 -0600379 return nil, err
Jon Perritt35e27e42014-12-05 11:10:46 -0700380 }
Jon Perritt35e27e42014-12-05 11:10:46 -0700381
Jon Perrittfea90732016-03-15 02:57:05 -0500382 if err := opts.TemplateOpts.Parse(); err != nil {
383 return nil, err
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500384 }
Jon Perrittfea90732016-03-15 02:57:05 -0500385
386 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil {
387 return nil, err
388 }
389 opts.TemplateOpts.fixFileRefs()
390 b["template"] = string(opts.TemplateOpts.Bin)
391
392 files := make(map[string]string)
393 for k, v := range opts.TemplateOpts.Files {
394 files[k] = v
Jon Perritt35e27e42014-12-05 11:10:46 -0700395 }
396
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500397 if opts.EnvironmentOpts != nil {
398 if err := opts.EnvironmentOpts.Parse(); err != nil {
399 return nil, err
400 }
Pratik Mallyaa979f5b2015-09-22 03:10:55 -0500401 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil {
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500402 return nil, err
403 }
Pratik Mallyaa979f5b2015-09-22 03:10:55 -0500404 opts.EnvironmentOpts.fixFileRefs()
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500405 for k, v := range opts.EnvironmentOpts.Files {
Jon Perrittfea90732016-03-15 02:57:05 -0500406 files[k] = v
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500407 }
Jon Perrittfea90732016-03-15 02:57:05 -0500408 b["environment"] = string(opts.EnvironmentOpts.Bin)
Jon Perritt35e27e42014-12-05 11:10:46 -0700409 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500410
Jon Perrittfea90732016-03-15 02:57:05 -0500411 if len(files) > 0 {
412 b["files"] = files
Jon Perritt35e27e42014-12-05 11:10:46 -0700413 }
Pratik Mallya5fddb2a2015-09-14 14:04:49 -0500414
Jon Perrittfea90732016-03-15 02:57:05 -0500415 return b, nil
Jon Perritt35e27e42014-12-05 11:10:46 -0700416}
417
418// Preview accepts a PreviewOptsBuilder interface and creates a preview of a stack using the values
419// provided.
Jon Perritt3860b512016-03-29 12:01:48 -0500420func Preview(c *gophercloud.ServiceClient, opts PreviewOptsBuilder) (r PreviewResult) {
Jon Perrittfea90732016-03-15 02:57:05 -0500421 b, err := opts.ToStackPreviewMap()
Jon Perritt35e27e42014-12-05 11:10:46 -0700422 if err != nil {
Jon Perrittfea90732016-03-15 02:57:05 -0500423 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500424 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700425 }
Jon Perrittfea90732016-03-15 02:57:05 -0500426 _, r.Err = c.Post(previewURL(c), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford1d27afa2015-03-24 16:20:45 +0100427 OkCodes: []int{200},
Jon Perritt35e27e42014-12-05 11:10:46 -0700428 })
jrperritt29ae6b32016-04-13 12:59:37 -0500429 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700430}
431
432// Abandon deletes the stack with the provided stackName and stackID, but leaves its
433// resources intact, and returns data describing the stack and its resources.
Jon Perritt3860b512016-03-29 12:01:48 -0500434func Abandon(c *gophercloud.ServiceClient, stackName, stackID string) (r AbandonResult) {
Jon Perrittfea90732016-03-15 02:57:05 -0500435 _, r.Err = c.Delete(abandonURL(c, stackName, stackID), &gophercloud.RequestOpts{
436 JSONResponse: &r.Body,
Ash Wilsondecfed72015-02-13 09:14:55 -0500437 OkCodes: []int{200},
Jon Perritt35e27e42014-12-05 11:10:46 -0700438 })
jrperritt29ae6b32016-04-13 12:59:37 -0500439 return
Jon Perritt35e27e42014-12-05 11:10:46 -0700440}