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) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 96 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 97 | } |
| 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. |
| 103 | type 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. |
| 109 | type AdoptOpts struct { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 110 | // Existing resources data represented as a string to add to the |
Jon Perritt | 9741dd9 | 2015-02-04 12:05:47 -0700 | [diff] [blame] | 111 | // new stack. Data returned by Abandon could be provided as AdoptsStackData. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 112 | 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 Perritt | 397ade6 | 2016-03-15 06:55:02 -0500 | [diff] [blame] | 115 | // 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 Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 118 | // 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 Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 121 | // 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] | 122 | //TemplateOpts *Template `json:"-" required:"true"` |
| 123 | // Enables or disables deletion of all stack resources when a stack |
Jon Perritt | 9741dd9 | 2015-02-04 12:05:47 -0700 | [diff] [blame] | 124 | // creation fails. Default is true, meaning all resources are not deleted when |
| 125 | // stack creation fails. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 126 | 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 Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 131 | } |
| 132 | |
| 133 | // ToStackAdoptMap casts a CreateOpts struct to a map. |
| 134 | func (opts AdoptOpts) ToStackAdoptMap() (map[string]interface{}, error) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 135 | b, err := gophercloud.BuildRequestBody(opts, "") |
| 136 | if err != nil { |
Jon Perritt | 58611da | 2016-03-09 00:49:57 -0600 | [diff] [blame] | 137 | return nil, err |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 138 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 139 | |
Jon Perritt | 397ade6 | 2016-03-15 06:55:02 -0500 | [diff] [blame] | 140 | 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 Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 150 | files := make(map[string]string) |
Jon Perritt | 397ade6 | 2016-03-15 06:55:02 -0500 | [diff] [blame] | 151 | for k, v := range opts.TemplateOpts.Files { |
| 152 | files[k] = v |
| 153 | } |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 154 | |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 155 | if opts.EnvironmentOpts != nil { |
| 156 | if err := opts.EnvironmentOpts.Parse(); err != nil { |
| 157 | return nil, err |
| 158 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 159 | if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 160 | return nil, err |
| 161 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 162 | opts.EnvironmentOpts.fixFileRefs() |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 163 | for k, v := range opts.EnvironmentOpts.Files { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 164 | files[k] = v |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 165 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 166 | b["environment"] = string(opts.EnvironmentOpts.Bin) |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 167 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 168 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 169 | if len(files) > 0 { |
| 170 | b["files"] = files |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 171 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 172 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 173 | return b, nil |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | // Adopt accepts an AdoptOpts struct and creates a new stack using the resources |
| 177 | // from another stack. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 178 | func Adopt(c *gophercloud.ServiceClient, opts AdoptOptsBuilder) (r AdoptResult) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 179 | b, err := opts.ToStackAdoptMap() |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 180 | if err != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 181 | r.Err = err |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 182 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 183 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 184 | _, r.Err = c.Post(adoptURL(c), b, &r.Body, nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 185 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 186 | } |
| 187 | |
| 188 | // SortDir is a type for specifying in which direction to sort a list of stacks. |
| 189 | type SortDir string |
| 190 | |
| 191 | // SortKey is a type for specifying by which key to sort a list of stacks. |
| 192 | type SortKey string |
| 193 | |
| 194 | var ( |
| 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. |
| 211 | type 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. |
| 220 | type 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. |
| 230 | func (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. |
| 241 | func 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 Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 250 | 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. |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 257 | func Get(c *gophercloud.ServiceClient, stackName, stackID string) (r GetResult) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 258 | _, r.Err = c.Get(getURL(c, stackName, stackID), &r.Body, nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 259 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 260 | } |
| 261 | |
| 262 | // UpdateOptsBuilder is the interface options structs have to satisfy in order |
| 263 | // to be used in the Update operation in this package. |
| 264 | type 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. |
| 270 | type UpdateOpts struct { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 271 | // A structure that contains either the template file or url. Call the |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 272 | // 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] | 273 | 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 Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 282 | } |
| 283 | |
| 284 | // ToStackUpdateMap casts a CreateOpts struct to a map. |
| 285 | func (opts UpdateOpts) ToStackUpdateMap() (map[string]interface{}, error) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 286 | b, err := gophercloud.BuildRequestBody(opts, "") |
| 287 | if err != nil { |
| 288 | return nil, err |
| 289 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 290 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 291 | if err := opts.TemplateOpts.Parse(); err != nil { |
| 292 | return nil, err |
| 293 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 294 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 295 | 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 Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 304 | } |
| 305 | |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 306 | if opts.EnvironmentOpts != nil { |
| 307 | if err := opts.EnvironmentOpts.Parse(); err != nil { |
| 308 | return nil, err |
| 309 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 310 | if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 311 | return nil, err |
| 312 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 313 | opts.EnvironmentOpts.fixFileRefs() |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 314 | for k, v := range opts.EnvironmentOpts.Files { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 315 | files[k] = v |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 316 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 317 | b["environment"] = string(opts.EnvironmentOpts.Bin) |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 318 | } |
| 319 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 320 | if len(files) > 0 { |
| 321 | b["files"] = files |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 322 | } |
| 323 | |
Pratik Mallya | 827c03e | 2015-09-17 00:10:47 -0500 | [diff] [blame] | 324 | if opts.Tags != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 325 | b["tags"] = strings.Join(opts.Tags, ",") |
Pratik Mallya | 827c03e | 2015-09-17 00:10:47 -0500 | [diff] [blame] | 326 | } |
| 327 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 328 | return b, nil |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 329 | } |
| 330 | |
| 331 | // Update accepts an UpdateOpts struct and updates an existing stack using the values |
| 332 | // provided. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 333 | func Update(c *gophercloud.ServiceClient, stackName, stackID string, opts UpdateOptsBuilder) (r UpdateResult) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 334 | b, err := opts.ToStackUpdateMap() |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 335 | if err != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 336 | r.Err = err |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 337 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 338 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 339 | _, r.Err = c.Put(updateURL(c, stackName, stackID), b, nil, nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 340 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 341 | } |
| 342 | |
| 343 | // Delete deletes a stack based on the stack name and stack ID. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 344 | func Delete(c *gophercloud.ServiceClient, stackName, stackID string) (r DeleteResult) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 345 | _, r.Err = c.Delete(deleteURL(c, stackName, stackID), nil) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 346 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 347 | } |
| 348 | |
| 349 | // PreviewOptsBuilder is the interface options structs have to satisfy in order |
| 350 | // to be used in the Preview operation in this package. |
| 351 | type 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. |
| 357 | type PreviewOpts struct { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 358 | // 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 Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 363 | // 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] | 364 | TemplateOpts *Template `json:"-" required:"true"` |
| 365 | // Enables or disables deletion of all stack resources when a stack |
Jon Perritt | 37f9774 | 2015-02-04 18:55:05 -0700 | [diff] [blame] | 366 | // creation fails. Default is true, meaning all resources are not deleted when |
| 367 | // stack creation fails. |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 368 | 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 Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 373 | } |
| 374 | |
| 375 | // ToStackPreviewMap casts a PreviewOpts struct to a map. |
| 376 | func (opts PreviewOpts) ToStackPreviewMap() (map[string]interface{}, error) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 377 | b, err := gophercloud.BuildRequestBody(opts, "") |
| 378 | if err != nil { |
Jon Perritt | 58611da | 2016-03-09 00:49:57 -0600 | [diff] [blame] | 379 | return nil, err |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 380 | } |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 381 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 382 | if err := opts.TemplateOpts.Parse(); err != nil { |
| 383 | return nil, err |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 384 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 385 | |
| 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 Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 395 | } |
| 396 | |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 397 | if opts.EnvironmentOpts != nil { |
| 398 | if err := opts.EnvironmentOpts.Parse(); err != nil { |
| 399 | return nil, err |
| 400 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 401 | if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 402 | return nil, err |
| 403 | } |
Pratik Mallya | a979f5b | 2015-09-22 03:10:55 -0500 | [diff] [blame] | 404 | opts.EnvironmentOpts.fixFileRefs() |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 405 | for k, v := range opts.EnvironmentOpts.Files { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 406 | files[k] = v |
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 | b["environment"] = string(opts.EnvironmentOpts.Bin) |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 409 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 410 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 411 | if len(files) > 0 { |
| 412 | b["files"] = files |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 413 | } |
Pratik Mallya | 5fddb2a | 2015-09-14 14:04:49 -0500 | [diff] [blame] | 414 | |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 415 | return b, nil |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 416 | } |
| 417 | |
| 418 | // Preview accepts a PreviewOptsBuilder interface and creates a preview of a stack using the values |
| 419 | // provided. |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 420 | func Preview(c *gophercloud.ServiceClient, opts PreviewOptsBuilder) (r PreviewResult) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 421 | b, err := opts.ToStackPreviewMap() |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 422 | if err != nil { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 423 | r.Err = err |
Jon Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 424 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 425 | } |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 426 | _, r.Err = c.Post(previewURL(c), b, &r.Body, &gophercloud.RequestOpts{ |
Jamie Hannaford | 1d27afa | 2015-03-24 16:20:45 +0100 | [diff] [blame] | 427 | OkCodes: []int{200}, |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 428 | }) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 429 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 430 | } |
| 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 Perritt | 3860b51 | 2016-03-29 12:01:48 -0500 | [diff] [blame] | 434 | func Abandon(c *gophercloud.ServiceClient, stackName, stackID string) (r AbandonResult) { |
Jon Perritt | fea9073 | 2016-03-15 02:57:05 -0500 | [diff] [blame] | 435 | _, r.Err = c.Delete(abandonURL(c, stackName, stackID), &gophercloud.RequestOpts{ |
| 436 | JSONResponse: &r.Body, |
Ash Wilson | decfed7 | 2015-02-13 09:14:55 -0500 | [diff] [blame] | 437 | OkCodes: []int{200}, |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 438 | }) |
jrperritt | 29ae6b3 | 2016-04-13 12:59:37 -0500 | [diff] [blame] | 439 | return |
Jon Perritt | 35e27e4 | 2014-12-05 11:10:46 -0700 | [diff] [blame] | 440 | } |