Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 1 | package stacks |
| 2 | |
| 3 | import ( |
Pratik Mallya | 827c03e | 2015-09-17 00:10:47 -0500 | [diff] [blame] | 4 | "strings" |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 5 | |
Jon Perritt | 27249f4 | 2016-02-18 10:35:59 -0600 | [diff] [blame] | 6 | "github.com/gophercloud/gophercloud" |
| 7 | "github.com/gophercloud/gophercloud/pagination" |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 8 | ) |
| 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. |
| 14 | type 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. |
| 20 | type CreateOpts struct { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 21 | // 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 Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 24 | // associated methods to extract the information relevant to send in a create request. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 25 | TemplateOpts *Template `json:"-" required:"true"` |
| 26 | // Enables or disables deletion of all stack resources when a stack |
Jon Perritt | 952f3e1 | 2015-02-03 12:13:24 -0700 | [diff] [blame] | 27 | // creation fails. Default is true, meaning all resources are not deleted when |
| 28 | // stack creation fails. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 29 | 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 Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | // ToStackCreateMap casts a CreateOpts struct to a map. |
| 41 | func (opts CreateOpts) ToStackCreateMap() (map[string]interface{}, error) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 42 | b, err := gophercloud.BuildRequestBody(opts, "") |
| 43 | if err != nil { |
Jon Perritt | 58611da | 2016-03-09 00:49:57 -0600 | [diff] [blame] | 44 | return nil, err |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 45 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 46 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 47 | if err := opts.TemplateOpts.Parse(); err != nil { |
| 48 | return nil, err |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 49 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 50 | |
| 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 Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | if opts.EnvironmentOpts != nil { |
| 63 | if err := opts.EnvironmentOpts.Parse(); err != nil { |
| 64 | return nil, err |
| 65 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 66 | if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 67 | return nil, err |
| 68 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 69 | opts.EnvironmentOpts.fixFileRefs() |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 70 | for k, v := range opts.EnvironmentOpts.Files { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 71 | files[k] = v |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 72 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 73 | b["environment"] = string(opts.EnvironmentOpts.Bin) |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 74 | } |
| 75 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 76 | if len(files) > 0 { |
| 77 | b["files"] = files |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 78 | } |
| 79 | |
Pratik Mallya | 827c03e | 2015-09-17 00:10:47 -0500 | [diff] [blame] | 80 | if opts.Tags != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 81 | b["tags"] = strings.Join(opts.Tags, ",") |
Pratik Mallya | 827c03e | 2015-09-17 00:10:47 -0500 | [diff] [blame] | 82 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 83 | |
| 84 | return b, nil |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | // Create accepts a CreateOpts struct and creates a new stack using the values |
| 88 | // provided. |
| 89 | func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 90 | var r CreateResult |
| 91 | b, err := opts.ToStackCreateMap() |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 92 | if err != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 93 | r.Err = err |
| 94 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 95 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 96 | _, r.Err = c.Post(createURL(c), b, &r.Body, nil) |
| 97 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | // AdoptOptsBuilder is the interface options structs have to satisfy in order |
| 101 | // to be used in the Adopt function in this package. Since many |
| 102 | // extensions decorate or modify the common logic, it is useful for them to |
| 103 | // satisfy a basic interface in order for them to be used. |
| 104 | type AdoptOptsBuilder interface { |
| 105 | ToStackAdoptMap() (map[string]interface{}, error) |
| 106 | } |
| 107 | |
| 108 | // AdoptOpts is the common options struct used in this package's Adopt |
| 109 | // operation. |
| 110 | type AdoptOpts struct { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 111 | // Existing resources data represented as a string to add to the |
Jon Perritt | 9741dd9 | 2015-02-04 12:05:47 -0700 | [diff] [blame] | 112 | // new stack. Data returned by Abandon could be provided as AdoptsStackData. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 113 | AdoptStackData string `json:"adopt_stack_data" required:"true"` |
| 114 | // The name of the stack. It must start with an alphabetic character. |
| 115 | Name string `json:"stack_name" required:"true"` |
Jon Perritt | 397ade6 | 2016-03-15 06:55:02 -0500 | [diff] [blame^] | 116 | // A structure that contains either the template file or url. Call the |
| 117 | // associated methods to extract the information relevant to send in a create request. |
| 118 | TemplateOpts *Template `json:"-" required:"true"` |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 119 | // The timeout for stack creation in minutes. |
| 120 | Timeout int `json:"timeout_mins,omitempty"` |
| 121 | // A structure that contains either the template file or url. Call the |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 122 | // associated methods to extract the information relevant to send in a create request. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 123 | //TemplateOpts *Template `json:"-" required:"true"` |
| 124 | // Enables or disables deletion of all stack resources when a stack |
Jon Perritt | 9741dd9 | 2015-02-04 12:05:47 -0700 | [diff] [blame] | 125 | // creation fails. Default is true, meaning all resources are not deleted when |
| 126 | // stack creation fails. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 127 | DisableRollback *bool `json:"disable_rollback,omitempty"` |
| 128 | // A structure that contains details for the environment of the stack. |
| 129 | EnvironmentOpts *Environment `json:"-"` |
| 130 | // User-defined parameters to pass to the template. |
| 131 | Parameters map[string]string `json:"parameters,omitempty"` |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | // ToStackAdoptMap casts a CreateOpts struct to a map. |
| 135 | func (opts AdoptOpts) ToStackAdoptMap() (map[string]interface{}, error) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 136 | b, err := gophercloud.BuildRequestBody(opts, "") |
| 137 | if err != nil { |
Jon Perritt | 58611da | 2016-03-09 00:49:57 -0600 | [diff] [blame] | 138 | return nil, err |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 139 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 140 | |
Jon Perritt | 397ade6 | 2016-03-15 06:55:02 -0500 | [diff] [blame^] | 141 | if err := opts.TemplateOpts.Parse(); err != nil { |
| 142 | return nil, err |
| 143 | } |
| 144 | |
| 145 | if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil { |
| 146 | return nil, err |
| 147 | } |
| 148 | opts.TemplateOpts.fixFileRefs() |
| 149 | b["template"] = string(opts.TemplateOpts.Bin) |
| 150 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 151 | files := make(map[string]string) |
Jon Perritt | 397ade6 | 2016-03-15 06:55:02 -0500 | [diff] [blame^] | 152 | for k, v := range opts.TemplateOpts.Files { |
| 153 | files[k] = v |
| 154 | } |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 155 | |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 156 | if opts.EnvironmentOpts != nil { |
| 157 | if err := opts.EnvironmentOpts.Parse(); err != nil { |
| 158 | return nil, err |
| 159 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 160 | if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 161 | return nil, err |
| 162 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 163 | opts.EnvironmentOpts.fixFileRefs() |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 164 | for k, v := range opts.EnvironmentOpts.Files { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 165 | files[k] = v |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 166 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 167 | b["environment"] = string(opts.EnvironmentOpts.Bin) |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 168 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 169 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 170 | if len(files) > 0 { |
| 171 | b["files"] = files |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 172 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 173 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 174 | return b, nil |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 175 | } |
| 176 | |
| 177 | // Adopt accepts an AdoptOpts struct and creates a new stack using the resources |
| 178 | // from another stack. |
Jon Perritt | 9741dd9 | 2015-02-04 12:05:47 -0700 | [diff] [blame] | 179 | func Adopt(c *gophercloud.ServiceClient, opts AdoptOptsBuilder) AdoptResult { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 180 | var r AdoptResult |
| 181 | b, err := opts.ToStackAdoptMap() |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 182 | if err != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 183 | r.Err = err |
| 184 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 185 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 186 | _, r.Err = c.Post(adoptURL(c), b, &r.Body, nil) |
| 187 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 188 | } |
| 189 | |
| 190 | // SortDir is a type for specifying in which direction to sort a list of stacks. |
| 191 | type SortDir string |
| 192 | |
| 193 | // SortKey is a type for specifying by which key to sort a list of stacks. |
| 194 | type SortKey string |
| 195 | |
| 196 | var ( |
| 197 | // SortAsc is used to sort a list of stacks in ascending order. |
| 198 | SortAsc SortDir = "asc" |
| 199 | // SortDesc is used to sort a list of stacks in descending order. |
| 200 | SortDesc SortDir = "desc" |
| 201 | // SortName is used to sort a list of stacks by name. |
| 202 | SortName SortKey = "name" |
| 203 | // SortStatus is used to sort a list of stacks by status. |
| 204 | SortStatus SortKey = "status" |
| 205 | // SortCreatedAt is used to sort a list of stacks by date created. |
| 206 | SortCreatedAt SortKey = "created_at" |
| 207 | // SortUpdatedAt is used to sort a list of stacks by date updated. |
| 208 | SortUpdatedAt SortKey = "updated_at" |
| 209 | ) |
| 210 | |
| 211 | // ListOptsBuilder allows extensions to add additional parameters to the |
| 212 | // List request. |
| 213 | type ListOptsBuilder interface { |
| 214 | ToStackListQuery() (string, error) |
| 215 | } |
| 216 | |
| 217 | // ListOpts allows the filtering and sorting of paginated collections through |
| 218 | // the API. Filtering is achieved by passing in struct field values that map to |
| 219 | // the network attributes you want to see returned. SortKey allows you to sort |
| 220 | // by a particular network attribute. SortDir sets the direction, and is either |
| 221 | // `asc' or `desc'. Marker and Limit are used for pagination. |
| 222 | type ListOpts struct { |
| 223 | Status string `q:"status"` |
| 224 | Name string `q:"name"` |
| 225 | Marker string `q:"marker"` |
| 226 | Limit int `q:"limit"` |
| 227 | SortKey SortKey `q:"sort_keys"` |
| 228 | SortDir SortDir `q:"sort_dir"` |
| 229 | } |
| 230 | |
| 231 | // ToStackListQuery formats a ListOpts into a query string. |
| 232 | func (opts ListOpts) ToStackListQuery() (string, error) { |
| 233 | q, err := gophercloud.BuildQueryString(opts) |
| 234 | if err != nil { |
| 235 | return "", err |
| 236 | } |
| 237 | return q.String(), nil |
| 238 | } |
| 239 | |
| 240 | // List returns a Pager which allows you to iterate over a collection of |
| 241 | // stacks. It accepts a ListOpts struct, which allows you to filter and sort |
| 242 | // the returned collection for greater efficiency. |
| 243 | func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { |
| 244 | url := listURL(c) |
| 245 | if opts != nil { |
| 246 | query, err := opts.ToStackListQuery() |
| 247 | if err != nil { |
| 248 | return pagination.Pager{Err: err} |
| 249 | } |
| 250 | url += query |
| 251 | } |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 252 | createPage := func(r pagination.PageResult) pagination.Page { |
| 253 | return StackPage{pagination.SinglePageBase(r)} |
| 254 | } |
| 255 | return pagination.NewPager(c, url, createPage) |
| 256 | } |
| 257 | |
| 258 | // Get retreives a stack based on the stack name and stack ID. |
| 259 | func Get(c *gophercloud.ServiceClient, stackName, stackID string) GetResult { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 260 | var r GetResult |
| 261 | _, r.Err = c.Get(getURL(c, stackName, stackID), &r.Body, nil) |
| 262 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 263 | } |
| 264 | |
| 265 | // UpdateOptsBuilder is the interface options structs have to satisfy in order |
| 266 | // to be used in the Update operation in this package. |
| 267 | type UpdateOptsBuilder interface { |
| 268 | ToStackUpdateMap() (map[string]interface{}, error) |
| 269 | } |
| 270 | |
| 271 | // UpdateOpts contains the common options struct used in this package's Update |
| 272 | // operation. |
| 273 | type UpdateOpts struct { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 274 | // A structure that contains either the template file or url. Call the |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 275 | // associated methods to extract the information relevant to send in a create request. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 276 | TemplateOpts *Template `json:"-" required:"true"` |
| 277 | // A structure that contains details for the environment of the stack. |
| 278 | EnvironmentOpts *Environment `json:"-"` |
| 279 | // User-defined parameters to pass to the template. |
| 280 | Parameters map[string]string `json:"parameters,omitempty"` |
| 281 | // The timeout for stack creation in minutes. |
| 282 | Timeout int `json:"timeout_mins,omitempty"` |
| 283 | // A list of tags to assosciate with the Stack |
| 284 | Tags []string `json:"-"` |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 285 | } |
| 286 | |
| 287 | // ToStackUpdateMap casts a CreateOpts struct to a map. |
| 288 | func (opts UpdateOpts) ToStackUpdateMap() (map[string]interface{}, error) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 289 | b, err := gophercloud.BuildRequestBody(opts, "") |
| 290 | if err != nil { |
| 291 | return nil, err |
| 292 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 293 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 294 | if err := opts.TemplateOpts.Parse(); err != nil { |
| 295 | return nil, err |
| 296 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 297 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 298 | if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil { |
| 299 | return nil, err |
| 300 | } |
| 301 | opts.TemplateOpts.fixFileRefs() |
| 302 | b["template"] = string(opts.TemplateOpts.Bin) |
| 303 | |
| 304 | files := make(map[string]string) |
| 305 | for k, v := range opts.TemplateOpts.Files { |
| 306 | files[k] = v |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 307 | } |
| 308 | |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 309 | if opts.EnvironmentOpts != nil { |
| 310 | if err := opts.EnvironmentOpts.Parse(); err != nil { |
| 311 | return nil, err |
| 312 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 313 | if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 314 | return nil, err |
| 315 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 316 | opts.EnvironmentOpts.fixFileRefs() |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 317 | for k, v := range opts.EnvironmentOpts.Files { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 318 | files[k] = v |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 319 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 320 | b["environment"] = string(opts.EnvironmentOpts.Bin) |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 321 | } |
| 322 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 323 | if len(files) > 0 { |
| 324 | b["files"] = files |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 325 | } |
| 326 | |
Pratik Mallya | 827c03e | 2015-09-17 00:10:47 -0500 | [diff] [blame] | 327 | if opts.Tags != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 328 | b["tags"] = strings.Join(opts.Tags, ",") |
Pratik Mallya | 827c03e | 2015-09-17 00:10:47 -0500 | [diff] [blame] | 329 | } |
| 330 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 331 | return b, nil |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 332 | } |
| 333 | |
| 334 | // Update accepts an UpdateOpts struct and updates an existing stack using the values |
| 335 | // provided. |
| 336 | func Update(c *gophercloud.ServiceClient, stackName, stackID string, opts UpdateOptsBuilder) UpdateResult { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 337 | var r UpdateResult |
| 338 | b, err := opts.ToStackUpdateMap() |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 339 | if err != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 340 | r.Err = err |
| 341 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 342 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 343 | _, r.Err = c.Put(updateURL(c, stackName, stackID), b, nil, nil) |
| 344 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 345 | } |
| 346 | |
| 347 | // Delete deletes a stack based on the stack name and stack ID. |
| 348 | func Delete(c *gophercloud.ServiceClient, stackName, stackID string) DeleteResult { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 349 | var r DeleteResult |
| 350 | _, r.Err = c.Delete(deleteURL(c, stackName, stackID), nil) |
| 351 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 352 | } |
| 353 | |
| 354 | // PreviewOptsBuilder is the interface options structs have to satisfy in order |
| 355 | // to be used in the Preview operation in this package. |
| 356 | type PreviewOptsBuilder interface { |
| 357 | ToStackPreviewMap() (map[string]interface{}, error) |
| 358 | } |
| 359 | |
| 360 | // PreviewOpts contains the common options struct used in this package's Preview |
| 361 | // operation. |
| 362 | type PreviewOpts struct { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 363 | // The name of the stack. It must start with an alphabetic character. |
| 364 | Name string `json:"stack_name" required:"true"` |
| 365 | // The timeout for stack creation in minutes. |
| 366 | Timeout int `json:"timeout_mins" required:"true"` |
| 367 | // A structure that contains either the template file or url. Call the |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 368 | // associated methods to extract the information relevant to send in a create request. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 369 | TemplateOpts *Template `json:"-" required:"true"` |
| 370 | // Enables or disables deletion of all stack resources when a stack |
Jon Perritt | 37f9774 | 2015-02-04 18:55:05 -0700 | [diff] [blame] | 371 | // creation fails. Default is true, meaning all resources are not deleted when |
| 372 | // stack creation fails. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 373 | DisableRollback *bool `json:"disable_rollback,omitempty"` |
| 374 | // A structure that contains details for the environment of the stack. |
| 375 | EnvironmentOpts *Environment `json:"-"` |
| 376 | // User-defined parameters to pass to the template. |
| 377 | Parameters map[string]string `json:"parameters,omitempty"` |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 378 | } |
| 379 | |
| 380 | // ToStackPreviewMap casts a PreviewOpts struct to a map. |
| 381 | func (opts PreviewOpts) ToStackPreviewMap() (map[string]interface{}, error) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 382 | b, err := gophercloud.BuildRequestBody(opts, "") |
| 383 | if err != nil { |
Jon Perritt | 58611da | 2016-03-09 00:49:57 -0600 | [diff] [blame] | 384 | return nil, err |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 385 | } |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 386 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 387 | if err := opts.TemplateOpts.Parse(); err != nil { |
| 388 | return nil, err |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 389 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 390 | |
| 391 | if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil { |
| 392 | return nil, err |
| 393 | } |
| 394 | opts.TemplateOpts.fixFileRefs() |
| 395 | b["template"] = string(opts.TemplateOpts.Bin) |
| 396 | |
| 397 | files := make(map[string]string) |
| 398 | for k, v := range opts.TemplateOpts.Files { |
| 399 | files[k] = v |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 400 | } |
| 401 | |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 402 | if opts.EnvironmentOpts != nil { |
| 403 | if err := opts.EnvironmentOpts.Parse(); err != nil { |
| 404 | return nil, err |
| 405 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 406 | if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 407 | return nil, err |
| 408 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 409 | opts.EnvironmentOpts.fixFileRefs() |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 410 | for k, v := range opts.EnvironmentOpts.Files { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 411 | files[k] = v |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 412 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 413 | b["environment"] = string(opts.EnvironmentOpts.Bin) |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 414 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 415 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 416 | if len(files) > 0 { |
| 417 | b["files"] = files |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 418 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 419 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 420 | return b, nil |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 421 | } |
| 422 | |
| 423 | // Preview accepts a PreviewOptsBuilder interface and creates a preview of a stack using the values |
| 424 | // provided. |
| 425 | func Preview(c *gophercloud.ServiceClient, opts PreviewOptsBuilder) PreviewResult { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 426 | var r PreviewResult |
| 427 | b, err := opts.ToStackPreviewMap() |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 428 | if err != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 429 | r.Err = err |
| 430 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 431 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 432 | _, r.Err = c.Post(previewURL(c), b, &r.Body, &gophercloud.RequestOpts{ |
Jamie Hannaford | 1d27afa | 2015-03-24 16:20:45 +0100 | [diff] [blame] | 433 | OkCodes: []int{200}, |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 434 | }) |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 435 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 436 | } |
| 437 | |
| 438 | // Abandon deletes the stack with the provided stackName and stackID, but leaves its |
| 439 | // resources intact, and returns data describing the stack and its resources. |
| 440 | func Abandon(c *gophercloud.ServiceClient, stackName, stackID string) AbandonResult { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 441 | var r AbandonResult |
| 442 | _, r.Err = c.Delete(abandonURL(c, stackName, stackID), &gophercloud.RequestOpts{ |
| 443 | JSONResponse: &r.Body, |
Ash Wilson | decfed7 | 2015-02-13 09:14:55 -0500 | [diff] [blame] | 444 | OkCodes: []int{200}, |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 445 | }) |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 446 | return r |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 447 | } |