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