github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/rts/v1/stacks/requests.go (about) 1 package stacks 2 3 import ( 4 "reflect" 5 "strings" 6 7 "github.com/huaweicloud/golangsdk" 8 "github.com/huaweicloud/golangsdk/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 allStacks, err := ExtractStacks(pages) 158 if err != nil { 159 return nil, err 160 } 161 162 return FilterStacks(allStacks, opts) 163 } 164 165 func FilterStacks(stacks []ListedStack, opts ListOpts) ([]ListedStack, error) { 166 167 var refinedStacks []ListedStack 168 var matched bool 169 m := map[string]interface{}{} 170 171 if opts.ID != "" { 172 m["ID"] = opts.ID 173 } 174 if opts.Name != "" { 175 m["Name"] = opts.Name 176 } 177 if opts.Status != "" { 178 m["Status"] = opts.Status 179 } 180 181 if len(m) > 0 && len(stacks) > 0 { 182 for _, stack := range stacks { 183 matched = true 184 185 for key, value := range m { 186 if sVal := getStructField(&stack, key); !(sVal == value) { 187 matched = false 188 } 189 } 190 191 if matched { 192 refinedStacks = append(refinedStacks, stack) 193 } 194 } 195 196 } else { 197 refinedStacks = stacks 198 } 199 200 return refinedStacks, nil 201 } 202 203 func getStructField(v *ListedStack, field string) string { 204 r := reflect.ValueOf(v) 205 f := reflect.Indirect(r).FieldByName(field) 206 return string(f.String()) 207 } 208 209 func Get(c *golangsdk.ServiceClient, stackName string) (r GetResult) { 210 _, r.Err = c.Get(getURL(c, stackName), &r.Body, nil) 211 return 212 } 213 214 // UpdateOptsBuilder is the interface options structs have to satisfy in order 215 // to be used in the Update operation in this package. 216 type UpdateOptsBuilder interface { 217 ToStackUpdateMap() (map[string]interface{}, error) 218 } 219 220 // UpdateOpts contains the common options struct used in this package's Update 221 // operation. 222 type UpdateOpts struct { 223 // A structure that contains either the template file or url. Call the 224 // associated methods to extract the information relevant to send in a create request. 225 TemplateOpts *Template `json:"-" required:"true"` 226 // A structure that contains details for the environment of the stack. 227 EnvironmentOpts *Environment `json:"-"` 228 // User-defined parameters to pass to the template. 229 Parameters map[string]string `json:"parameters,omitempty"` 230 // The timeout for stack creation in minutes. 231 Timeout int `json:"timeout_mins,omitempty"` 232 // Enables or disables deletion of all stack resources when a stack 233 // creation fails. Default is true, meaning all resources are not deleted when 234 // stack creation fails. 235 DisableRollback *bool `json:"disable_rollback,omitempty"` 236 // A list of tags to assosciate with the Stack 237 Tags []string `json:"-"` 238 } 239 240 // ToStackUpdateMap casts a CreateOpts struct to a map. 241 func (opts UpdateOpts) ToStackUpdateMap() (map[string]interface{}, error) { 242 b, err := golangsdk.BuildRequestBody(opts, "") 243 if err != nil { 244 return nil, err 245 } 246 247 if err := opts.TemplateOpts.Parse(); err != nil { 248 return nil, err 249 } 250 251 if err := opts.TemplateOpts.getFileContents(opts.TemplateOpts.Parsed, ignoreIfTemplate, true); err != nil { 252 return nil, err 253 } 254 opts.TemplateOpts.fixFileRefs() 255 b["template"] = string(opts.TemplateOpts.Bin) 256 257 files := make(map[string]string) 258 for k, v := range opts.TemplateOpts.Files { 259 files[k] = v 260 } 261 262 if opts.EnvironmentOpts != nil { 263 if err := opts.EnvironmentOpts.Parse(); err != nil { 264 return nil, err 265 } 266 if err := opts.EnvironmentOpts.getRRFileContents(ignoreIfEnvironment); err != nil { 267 return nil, err 268 } 269 opts.EnvironmentOpts.fixFileRefs() 270 for k, v := range opts.EnvironmentOpts.Files { 271 files[k] = v 272 } 273 b["environment"] = string(opts.EnvironmentOpts.Bin) 274 } 275 276 if len(files) > 0 { 277 b["files"] = files 278 } 279 280 if opts.Tags != nil { 281 b["tags"] = strings.Join(opts.Tags, ",") 282 } 283 284 return b, nil 285 } 286 287 // Update accepts an UpdateOpts struct and updates an existing stack using the values 288 // provided. 289 func Update(c *golangsdk.ServiceClient, stackName, stackID string, opts UpdateOptsBuilder) (r UpdateResult) { 290 b, err := opts.ToStackUpdateMap() 291 if err != nil { 292 r.Err = err 293 return 294 } 295 _, r.Err = c.Put(updateURL(c, stackName, stackID), b, nil, nil) 296 return 297 } 298 299 // Delete deletes a stack based on the stack name and stack ID. 300 func Delete(c *golangsdk.ServiceClient, stackName, stackID string) (r DeleteResult) { 301 _, r.Err = c.Delete(deleteURL(c, stackName, stackID), nil) 302 return 303 }