github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/openstack/rts/v1/stacks/requests.go (about) 1 package stacks 2 3 import ( 4 "reflect" 5 "strings" 6 7 "github.com/opentelekomcloud/gophertelekomcloud" 8 "github.com/opentelekomcloud/gophertelekomcloud/pagination" 9 ) 10 11 // CreateOptsBuilder is the interface options structs have to satisfy in order 12 // to be used in the main Create operation in this package. Since many 13 // extensions decorate or modify the common logic, it is useful for them to 14 // satisfy a basic interface in order for them to be used. 15 type CreateOptsBuilder interface { 16 ToStackCreateMap() (map[string]interface{}, error) 17 } 18 19 // CreateOpts is the common options struct used in this package's Create 20 // operation. 21 type CreateOpts struct { 22 // The name of the stack. It must start with an alphabetic character. 23 Name string `json:"stack_name" required:"true"` 24 // A structure that contains either the template file or url. Call the 25 // associated methods to extract the information relevant to send in a create request. 26 TemplateOpts *Template `json:"-" required:"true"` 27 // Enables or disables deletion of all stack resources when a stack 28 // creation fails. Default is true, meaning all resources are not deleted when 29 // stack creation fails. 30 DisableRollback *bool `json:"disable_rollback,omitempty"` 31 // A structure that contains details for the environment of the stack. 32 EnvironmentOpts *Environment `json:"-"` 33 // User-defined parameters to pass to the template. 34 Parameters map[string]string `json:"parameters,omitempty"` 35 // The timeout for stack creation in minutes. 36 Timeout int `json:"timeout_mins,omitempty"` 37 // A list of tags to assosciate with the Stack 38 Tags []string `json:"-"` 39 } 40 41 // ToStackCreateMap casts a CreateOpts struct to a map. 42 func (opts CreateOpts) ToStackCreateMap() (map[string]interface{}, error) { 43 b, err := golangsdk.BuildRequestBody(opts, "") 44 if err != nil { 45 return nil, err 46 } 47 48 if err := opts.TemplateOpts.Parse(); err != nil { 49 return nil, err 50 } 51 52 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil { 53 return nil, err 54 } 55 opts.TemplateOpts.fixFileRefs() 56 b["template"] = string(opts.TemplateOpts.Bin) 57 58 files := make(map[string]string) 59 for k, v := range opts.TemplateOpts.Files { 60 files[k] = v 61 } 62 63 if opts.EnvironmentOpts != nil { 64 if err := opts.EnvironmentOpts.Parse(); err != nil { 65 return nil, err 66 } 67 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { 68 return nil, err 69 } 70 opts.EnvironmentOpts.fixFileRefs() 71 for k, v := range opts.EnvironmentOpts.Files { 72 files[k] = v 73 } 74 b["environment"] = string(opts.EnvironmentOpts.Bin) 75 } 76 77 if len(files) > 0 { 78 b["files"] = files 79 } 80 81 if opts.Tags != nil { 82 b["tags"] = strings.Join(opts.Tags, ",") 83 } 84 85 return b, nil 86 } 87 88 // Create accepts a CreateOpts struct and creates a new stack using the values 89 // provided. 90 func Create(c *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 91 b, err := opts.ToStackCreateMap() 92 if err != nil { 93 r.Err = err 94 return 95 } 96 _, r.Err = c.Post(createURL(c), b, &r.Body, nil) 97 return 98 } 99 100 // SortDir is a type for specifying in which direction to sort a list of stacks. 101 type SortDir string 102 103 // SortKey is a type for specifying by which key to sort a list of stacks. 104 type SortKey string 105 106 var ( 107 // SortAsc is used to sort a list of stacks in ascending order. 108 SortAsc SortDir = "asc" 109 // SortDesc is used to sort a list of stacks in descending order. 110 SortDesc SortDir = "desc" 111 // SortName is used to sort a list of stacks by name. 112 SortName SortKey = "name" 113 // SortStatus is used to sort a list of stacks by status. 114 SortStatus SortKey = "status" 115 // SortCreatedAt is used to sort a list of stacks by date created. 116 SortCreatedAt SortKey = "created_at" 117 // SortUpdatedAt is used to sort a list of stacks by date updated. 118 SortUpdatedAt SortKey = "updated_at" 119 ) 120 121 // ListOptsBuilder allows extensions to add additional parameters to the 122 // List request. 123 type ListOptsBuilder interface { 124 ToStackListQuery() (string, error) 125 } 126 127 // ListOpts allows the filtering and sorting of paginated collections through 128 // the API. Filtering is achieved by passing in struct field values that map to 129 // the rts attributes you want to see returned. SortKey allows you to sort 130 // by a particular network attribute. SortDir sets the direction, and is either 131 // `asc' or `desc'. Marker and Limit are used for pagination. 132 type ListOpts struct { 133 ID string `q:"id"` 134 Status string `q:"status"` 135 Name string `q:"name"` 136 Marker string `q:"marker"` 137 Limit int `q:"limit"` 138 SortKey SortKey `q:"sort_keys"` 139 SortDir SortDir `q:"sort_dir"` 140 } 141 142 // ToStackListQuery formats a ListOpts into a query string. 143 func (opts ListOpts) ToStackListQuery() (string, error) { 144 q, err := golangsdk.BuildQueryString(opts) 145 if err != nil { 146 return "", err 147 } 148 return q.String(), nil 149 } 150 151 func List(c *golangsdk.ServiceClient, opts ListOpts) ([]ListedStack, error) { 152 u := listURL(c) 153 pages, err := pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { 154 return StackPage{pagination.LinkedPageBase{PageResult: r}} 155 }).AllPages() 156 157 if err != nil { 158 return nil, err 159 } 160 161 allStacks, err := ExtractStacks(pages) 162 if err != nil { 163 return nil, err 164 } 165 166 return FilterStacks(allStacks, opts) 167 } 168 169 func FilterStacks(stacks []ListedStack, opts ListOpts) ([]ListedStack, error) { 170 171 var refinedStacks []ListedStack 172 var matched bool 173 m := map[string]interface{}{} 174 175 if opts.ID != "" { 176 m["ID"] = opts.ID 177 } 178 if opts.Name != "" { 179 m["Name"] = opts.Name 180 } 181 if opts.Status != "" { 182 m["Status"] = opts.Status 183 } 184 185 if len(m) > 0 && len(stacks) > 0 { 186 for _, stack := range stacks { 187 matched = true 188 189 for key, value := range m { 190 if sVal := getStructField(&stack, key); !(sVal == value) { 191 matched = false 192 } 193 } 194 195 if matched { 196 refinedStacks = append(refinedStacks, stack) 197 } 198 } 199 200 } else { 201 refinedStacks = stacks 202 } 203 204 return refinedStacks, nil 205 } 206 207 func getStructField(v *ListedStack, field string) string { 208 r := reflect.ValueOf(v) 209 f := reflect.Indirect(r).FieldByName(field) 210 return f.String() 211 } 212 213 func Get(c *golangsdk.ServiceClient, stackName string) (r GetResult) { 214 _, r.Err = c.Get(getURL(c, stackName), &r.Body, nil) 215 return 216 } 217 218 // UpdateOptsBuilder is the interface options structs have to satisfy in order 219 // to be used in the Update operation in this package. 220 type UpdateOptsBuilder interface { 221 ToStackUpdateMap() (map[string]interface{}, error) 222 } 223 224 // UpdateOpts contains the common options struct used in this package's Update 225 // operation. 226 type UpdateOpts struct { 227 // A structure that contains either the template file or url. Call the 228 // associated methods to extract the information relevant to send in a create request. 229 TemplateOpts *Template `json:"-" required:"true"` 230 // A structure that contains details for the environment of the stack. 231 EnvironmentOpts *Environment `json:"-"` 232 // User-defined parameters to pass to the template. 233 Parameters map[string]string `json:"parameters,omitempty"` 234 // The timeout for stack creation in minutes. 235 Timeout int `json:"timeout_mins,omitempty"` 236 // Enables or disables deletion of all stack resources when a stack 237 // creation fails. Default is true, meaning all resources are not deleted when 238 // stack creation fails. 239 DisableRollback *bool `json:"disable_rollback,omitempty"` 240 // A list of tags to assosciate with the Stack 241 Tags []string `json:"-"` 242 } 243 244 // ToStackUpdateMap casts a CreateOpts struct to a map. 245 func (opts UpdateOpts) ToStackUpdateMap() (map[string]interface{}, error) { 246 b, err := golangsdk.BuildRequestBody(opts, "") 247 if err != nil { 248 return nil, err 249 } 250 251 if err := opts.TemplateOpts.Parse(); err != nil { 252 return nil, err 253 } 254 255 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil { 256 return nil, err 257 } 258 opts.TemplateOpts.fixFileRefs() 259 b["template"] = string(opts.TemplateOpts.Bin) 260 261 files := make(map[string]string) 262 for k, v := range opts.TemplateOpts.Files { 263 files[k] = v 264 } 265 266 if opts.EnvironmentOpts != nil { 267 if err := opts.EnvironmentOpts.Parse(); err != nil { 268 return nil, err 269 } 270 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { 271 return nil, err 272 } 273 opts.EnvironmentOpts.fixFileRefs() 274 for k, v := range opts.EnvironmentOpts.Files { 275 files[k] = v 276 } 277 b["environment"] = string(opts.EnvironmentOpts.Bin) 278 } 279 280 if len(files) > 0 { 281 b["files"] = files 282 } 283 284 if opts.Tags != nil { 285 b["tags"] = strings.Join(opts.Tags, ",") 286 } 287 288 return b, nil 289 } 290 291 // Update accepts an UpdateOpts struct and updates an existing stack using the values 292 // provided. 293 func Update(c *golangsdk.ServiceClient, stackName, stackID string, opts UpdateOptsBuilder) (r UpdateResult) { 294 b, err := opts.ToStackUpdateMap() 295 if err != nil { 296 r.Err = err 297 return 298 } 299 _, r.Err = c.Put(updateURL(c, stackName, stackID), b, nil, nil) 300 return 301 } 302 303 // Delete deletes a stack based on the stack name and stack ID. 304 func Delete(c *golangsdk.ServiceClient, stackName, stackID string) (r DeleteResult) { 305 _, r.Err = c.Delete(deleteURL(c, stackName, stackID), nil) 306 return 307 }