github.com/leeclow-ops/gophercloud@v1.2.1/openstack/orchestration/v1/stacks/requests.go (about) 1 package stacks 2 3 import ( 4 "strings" 5 6 "github.com/leeclow-ops/gophercloud" 7 "github.com/leeclow-ops/gophercloud/pagination" 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 { 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 24 // associated methods to extract the information relevant to send in a create request. 25 TemplateOpts *Template `json:"-" required:"true"` 26 // Enables or disables deletion of all stack resources when a stack 27 // creation fails. Default is true, meaning all resources are not deleted when 28 // stack creation fails. 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]interface{} `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:"-"` 38 } 39 40 // ToStackCreateMap casts a CreateOpts struct to a map. 41 func (opts CreateOpts) ToStackCreateMap() (map[string]interface{}, error) { 42 b, err := gophercloud.BuildRequestBody(opts, "") 43 if err != nil { 44 return nil, err 45 } 46 47 if err := opts.TemplateOpts.Parse(); err != nil { 48 return nil, err 49 } 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 60 } 61 62 if opts.EnvironmentOpts != nil { 63 if err := opts.EnvironmentOpts.Parse(); err != nil { 64 return nil, err 65 } 66 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { 67 return nil, err 68 } 69 opts.EnvironmentOpts.fixFileRefs() 70 for k, v := range opts.EnvironmentOpts.Files { 71 files[k] = v 72 } 73 b["environment"] = string(opts.EnvironmentOpts.Bin) 74 } 75 76 if len(files) > 0 { 77 b["files"] = files 78 } 79 80 if opts.Tags != nil { 81 b["tags"] = strings.Join(opts.Tags, ",") 82 } 83 84 return b, nil 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) (r CreateResult) { 90 b, err := opts.ToStackCreateMap() 91 if err != nil { 92 r.Err = err 93 return 94 } 95 resp, err := c.Post(createURL(c), b, &r.Body, nil) 96 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 97 return 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 { 111 // Existing resources data represented as a string to add to the 112 // new stack. Data returned by Abandon could be provided as AdoptsStackData. 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"` 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"` 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 122 // associated methods to extract the information relevant to send in a create request. 123 //TemplateOpts *Template `json:"-" required:"true"` 124 // Enables or disables deletion of all stack resources when a stack 125 // creation fails. Default is true, meaning all resources are not deleted when 126 // stack creation fails. 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]interface{} `json:"parameters,omitempty"` 132 } 133 134 // ToStackAdoptMap casts a CreateOpts struct to a map. 135 func (opts AdoptOpts) ToStackAdoptMap() (map[string]interface{}, error) { 136 b, err := gophercloud.BuildRequestBody(opts, "") 137 if err != nil { 138 return nil, err 139 } 140 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 151 files := make(map[string]string) 152 for k, v := range opts.TemplateOpts.Files { 153 files[k] = v 154 } 155 156 if opts.EnvironmentOpts != nil { 157 if err := opts.EnvironmentOpts.Parse(); err != nil { 158 return nil, err 159 } 160 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { 161 return nil, err 162 } 163 opts.EnvironmentOpts.fixFileRefs() 164 for k, v := range opts.EnvironmentOpts.Files { 165 files[k] = v 166 } 167 b["environment"] = string(opts.EnvironmentOpts.Bin) 168 } 169 170 if len(files) > 0 { 171 b["files"] = files 172 } 173 174 return b, nil 175 } 176 177 // Adopt accepts an AdoptOpts struct and creates a new stack using the resources 178 // from another stack. 179 func Adopt(c *gophercloud.ServiceClient, opts AdoptOptsBuilder) (r AdoptResult) { 180 b, err := opts.ToStackAdoptMap() 181 if err != nil { 182 r.Err = err 183 return 184 } 185 resp, err := c.Post(adoptURL(c), b, &r.Body, nil) 186 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 187 return 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. 220 type ListOpts struct { 221 // TenantID is the UUID of the tenant. A tenant is also known as 222 // a project. 223 TenantID string `q:"tenant_id"` 224 225 // ID filters the stack list by a stack ID 226 ID string `q:"id"` 227 228 // Status filters the stack list by a status. 229 Status string `q:"status"` 230 231 // Name filters the stack list by a name. 232 Name string `q:"name"` 233 234 // Marker is the ID of last-seen item. 235 Marker string `q:"marker"` 236 237 // Limit is an integer value for the limit of values to return. 238 Limit int `q:"limit"` 239 240 // SortKey allows you to sort by stack_name, stack_status, creation_time, or 241 // update_time key. 242 SortKey SortKey `q:"sort_keys"` 243 244 // SortDir sets the direction, and is either `asc` or `desc`. 245 SortDir SortDir `q:"sort_dir"` 246 247 // AllTenants is a bool to show all tenants. 248 AllTenants bool `q:"global_tenant"` 249 250 // ShowDeleted set to `true` to include deleted stacks in the list. 251 ShowDeleted bool `q:"show_deleted"` 252 253 // ShowNested set to `true` to include nested stacks in the list. 254 ShowNested bool `q:"show_nested"` 255 256 // ShowHidden set to `true` to include hiddened stacks in the list. 257 ShowHidden bool `q:"show_hidden"` 258 259 // Tags lists stacks that contain one or more simple string tags. 260 Tags string `q:"tags"` 261 262 // TagsAny lists stacks that contain one or more simple string tags. 263 TagsAny string `q:"tags_any"` 264 265 // NotTags lists stacks that do not contain one or more simple string tags. 266 NotTags string `q:"not_tags"` 267 268 // NotTagsAny lists stacks that do not contain one or more simple string tags. 269 NotTagsAny string `q:"not_tags_any"` 270 } 271 272 // ToStackListQuery formats a ListOpts into a query string. 273 func (opts ListOpts) ToStackListQuery() (string, error) { 274 q, err := gophercloud.BuildQueryString(opts) 275 if err != nil { 276 return "", err 277 } 278 return q.String(), nil 279 } 280 281 // List returns a Pager which allows you to iterate over a collection of 282 // stacks. It accepts a ListOpts struct, which allows you to filter and sort 283 // the returned collection for greater efficiency. 284 func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { 285 url := listURL(c) 286 if opts != nil { 287 query, err := opts.ToStackListQuery() 288 if err != nil { 289 return pagination.Pager{Err: err} 290 } 291 url += query 292 } 293 createPage := func(r pagination.PageResult) pagination.Page { 294 return StackPage{pagination.SinglePageBase(r)} 295 } 296 return pagination.NewPager(c, url, createPage) 297 } 298 299 // Get retreives a stack based on the stack name and stack ID. 300 func Get(c *gophercloud.ServiceClient, stackName, stackID string) (r GetResult) { 301 resp, err := c.Get(getURL(c, stackName, stackID), &r.Body, nil) 302 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 303 return 304 } 305 306 // Find retrieves a stack based on the stack name or stack ID. 307 func Find(c *gophercloud.ServiceClient, stackIdentity string) (r GetResult) { 308 resp, err := c.Get(findURL(c, stackIdentity), &r.Body, nil) 309 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 310 return 311 } 312 313 // UpdateOptsBuilder is the interface options structs have to satisfy in order 314 // to be used in the Update operation in this package. 315 type UpdateOptsBuilder interface { 316 ToStackUpdateMap() (map[string]interface{}, error) 317 } 318 319 // UpdatePatchOptsBuilder is the interface options structs have to satisfy in order 320 // to be used in the UpdatePatch operation in this package 321 type UpdatePatchOptsBuilder interface { 322 ToStackUpdatePatchMap() (map[string]interface{}, error) 323 } 324 325 // UpdateOpts contains the common options struct used in this package's Update 326 // and UpdatePatch operations. 327 type UpdateOpts struct { 328 // A structure that contains either the template file or url. Call the 329 // associated methods to extract the information relevant to send in a create request. 330 TemplateOpts *Template `json:"-"` 331 // A structure that contains details for the environment of the stack. 332 EnvironmentOpts *Environment `json:"-"` 333 // User-defined parameters to pass to the template. 334 Parameters map[string]interface{} `json:"parameters,omitempty"` 335 // The timeout for stack creation in minutes. 336 Timeout int `json:"timeout_mins,omitempty"` 337 // A list of tags to associate with the Stack 338 Tags []string `json:"-"` 339 } 340 341 // ToStackUpdateMap validates that a template was supplied and calls 342 // the toStackUpdateMap private function. 343 func (opts UpdateOpts) ToStackUpdateMap() (map[string]interface{}, error) { 344 if opts.TemplateOpts == nil { 345 return nil, ErrTemplateRequired{} 346 } 347 return toStackUpdateMap(opts) 348 } 349 350 // ToStackUpdatePatchMap calls the private function toStackUpdateMap 351 // directly. 352 func (opts UpdateOpts) ToStackUpdatePatchMap() (map[string]interface{}, error) { 353 return toStackUpdateMap(opts) 354 } 355 356 // ToStackUpdateMap casts a CreateOpts struct to a map. 357 func toStackUpdateMap(opts UpdateOpts) (map[string]interface{}, error) { 358 b, err := gophercloud.BuildRequestBody(opts, "") 359 if err != nil { 360 return nil, err 361 } 362 363 files := make(map[string]string) 364 365 if opts.TemplateOpts != nil { 366 if err := opts.TemplateOpts.Parse(); err != nil { 367 return nil, err 368 } 369 370 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil { 371 return nil, err 372 } 373 opts.TemplateOpts.fixFileRefs() 374 b["template"] = string(opts.TemplateOpts.Bin) 375 376 for k, v := range opts.TemplateOpts.Files { 377 files[k] = v 378 } 379 } 380 381 if opts.EnvironmentOpts != nil { 382 if err := opts.EnvironmentOpts.Parse(); err != nil { 383 return nil, err 384 } 385 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { 386 return nil, err 387 } 388 opts.EnvironmentOpts.fixFileRefs() 389 for k, v := range opts.EnvironmentOpts.Files { 390 files[k] = v 391 } 392 b["environment"] = string(opts.EnvironmentOpts.Bin) 393 } 394 395 if len(files) > 0 { 396 b["files"] = files 397 } 398 399 if opts.Tags != nil { 400 b["tags"] = strings.Join(opts.Tags, ",") 401 } 402 403 return b, nil 404 } 405 406 // Update accepts an UpdateOpts struct and updates an existing stack using the 407 // 408 // http PUT verb with the values provided. opts.TemplateOpts is required. 409 func Update(c *gophercloud.ServiceClient, stackName, stackID string, opts UpdateOptsBuilder) (r UpdateResult) { 410 b, err := opts.ToStackUpdateMap() 411 if err != nil { 412 r.Err = err 413 return 414 } 415 resp, err := c.Put(updateURL(c, stackName, stackID), b, nil, nil) 416 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 417 return 418 } 419 420 // Update accepts an UpdateOpts struct and updates an existing stack using the 421 // 422 // http PATCH verb with the values provided. opts.TemplateOpts is not required. 423 func UpdatePatch(c *gophercloud.ServiceClient, stackName, stackID string, opts UpdatePatchOptsBuilder) (r UpdateResult) { 424 b, err := opts.ToStackUpdatePatchMap() 425 if err != nil { 426 r.Err = err 427 return 428 } 429 resp, err := c.Patch(updateURL(c, stackName, stackID), b, nil, nil) 430 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 431 return 432 } 433 434 // Delete deletes a stack based on the stack name and stack ID. 435 func Delete(c *gophercloud.ServiceClient, stackName, stackID string) (r DeleteResult) { 436 resp, err := c.Delete(deleteURL(c, stackName, stackID), nil) 437 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 438 return 439 } 440 441 // PreviewOptsBuilder is the interface options structs have to satisfy in order 442 // to be used in the Preview operation in this package. 443 type PreviewOptsBuilder interface { 444 ToStackPreviewMap() (map[string]interface{}, error) 445 } 446 447 // PreviewOpts contains the common options struct used in this package's Preview 448 // operation. 449 type PreviewOpts struct { 450 // The name of the stack. It must start with an alphabetic character. 451 Name string `json:"stack_name" required:"true"` 452 // The timeout for stack creation in minutes. 453 Timeout int `json:"timeout_mins" required:"true"` 454 // A structure that contains either the template file or url. Call the 455 // associated methods to extract the information relevant to send in a create request. 456 TemplateOpts *Template `json:"-" required:"true"` 457 // Enables or disables deletion of all stack resources when a stack 458 // creation fails. Default is true, meaning all resources are not deleted when 459 // stack creation fails. 460 DisableRollback *bool `json:"disable_rollback,omitempty"` 461 // A structure that contains details for the environment of the stack. 462 EnvironmentOpts *Environment `json:"-"` 463 // User-defined parameters to pass to the template. 464 Parameters map[string]interface{} `json:"parameters,omitempty"` 465 } 466 467 // ToStackPreviewMap casts a PreviewOpts struct to a map. 468 func (opts PreviewOpts) ToStackPreviewMap() (map[string]interface{}, error) { 469 b, err := gophercloud.BuildRequestBody(opts, "") 470 if err != nil { 471 return nil, err 472 } 473 474 if err := opts.TemplateOpts.Parse(); err != nil { 475 return nil, err 476 } 477 478 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil { 479 return nil, err 480 } 481 opts.TemplateOpts.fixFileRefs() 482 b["template"] = string(opts.TemplateOpts.Bin) 483 484 files := make(map[string]string) 485 for k, v := range opts.TemplateOpts.Files { 486 files[k] = v 487 } 488 489 if opts.EnvironmentOpts != nil { 490 if err := opts.EnvironmentOpts.Parse(); err != nil { 491 return nil, err 492 } 493 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { 494 return nil, err 495 } 496 opts.EnvironmentOpts.fixFileRefs() 497 for k, v := range opts.EnvironmentOpts.Files { 498 files[k] = v 499 } 500 b["environment"] = string(opts.EnvironmentOpts.Bin) 501 } 502 503 if len(files) > 0 { 504 b["files"] = files 505 } 506 507 return b, nil 508 } 509 510 // Preview accepts a PreviewOptsBuilder interface and creates a preview of a stack using the values 511 // provided. 512 func Preview(c *gophercloud.ServiceClient, opts PreviewOptsBuilder) (r PreviewResult) { 513 b, err := opts.ToStackPreviewMap() 514 if err != nil { 515 r.Err = err 516 return 517 } 518 resp, err := c.Post(previewURL(c), b, &r.Body, &gophercloud.RequestOpts{ 519 OkCodes: []int{200}, 520 }) 521 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 522 return 523 } 524 525 // Abandon deletes the stack with the provided stackName and stackID, but leaves its 526 // resources intact, and returns data describing the stack and its resources. 527 func Abandon(c *gophercloud.ServiceClient, stackName, stackID string) (r AbandonResult) { 528 resp, err := c.Delete(abandonURL(c, stackName, stackID), &gophercloud.RequestOpts{ 529 JSONResponse: &r.Body, 530 OkCodes: []int{200}, 531 }) 532 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 533 return 534 }