github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/cce/v3/clusters/requests.go (about) 1 package clusters 2 3 import ( 4 "reflect" 5 6 "github.com/chnsz/golangsdk" 7 "github.com/chnsz/golangsdk/openstack/common/tags" 8 ) 9 10 var RequestOpts golangsdk.RequestOpts = golangsdk.RequestOpts{ 11 MoreHeaders: map[string]string{"Content-Type": "application/json"}, 12 } 13 14 // ListOpts allows the filtering of list data using given parameters. 15 type ListOpts struct { 16 Name string `json:"name"` 17 ID string `json:"uuid"` 18 Type string `json:"type"` 19 VpcID string `json:"vpc"` 20 Phase string `json:"phase"` 21 EnterpriseProjectID string `json:"enterpriseProjectId"` 22 } 23 24 // List returns collection of clusters. 25 func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Clusters, error) { 26 var r ListResult 27 _, r.Err = client.Get(rootURL(client), &r.Body, &golangsdk.RequestOpts{ 28 OkCodes: []int{200}, 29 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 30 }) 31 32 allClusters, err := r.ExtractClusters() 33 if err != nil { 34 return nil, err 35 } 36 37 return FilterClusters(allClusters, opts), nil 38 } 39 40 func FilterClusters(clusters []Clusters, opts ListOpts) []Clusters { 41 42 var refinedClusters []Clusters 43 var matched bool 44 m := map[string]FilterStruct{} 45 46 if opts.Name != "" { 47 m["Name"] = FilterStruct{Value: opts.Name, Driller: []string{"Metadata"}} 48 } 49 if opts.ID != "" { 50 m["Id"] = FilterStruct{Value: opts.ID, Driller: []string{"Metadata"}} 51 } 52 if opts.Type != "" { 53 m["Type"] = FilterStruct{Value: opts.Type, Driller: []string{"Spec"}} 54 } 55 if opts.VpcID != "" { 56 m["VpcId"] = FilterStruct{Value: opts.VpcID, Driller: []string{"Spec", "HostNetwork"}} 57 } 58 if opts.Phase != "" { 59 m["Phase"] = FilterStruct{Value: opts.Phase, Driller: []string{"Status"}} 60 } 61 if opts.EnterpriseProjectID != "" { 62 m["enterpriseProjectId"] = FilterStruct{Value: opts.EnterpriseProjectID, Driller: []string{"Spec", "ExtendParam"}} 63 } 64 65 if len(m) > 0 && len(clusters) > 0 { 66 for _, cluster := range clusters { 67 matched = true 68 69 for key, value := range m { 70 if sVal := GetStructNestedField(&cluster, key, value.Driller); !(sVal == value.Value) { 71 matched = false 72 } 73 } 74 if matched { 75 refinedClusters = append(refinedClusters, cluster) 76 } 77 } 78 79 } else { 80 refinedClusters = clusters 81 } 82 83 return refinedClusters 84 } 85 86 type FilterStruct struct { 87 Value string 88 Driller []string 89 } 90 91 func GetStructNestedField(v *Clusters, field string, structDriller []string) string { 92 r := reflect.ValueOf(v) 93 for _, drillField := range structDriller { 94 f := reflect.Indirect(r).FieldByName(drillField).Interface() 95 r = reflect.ValueOf(f) 96 } 97 98 if r.Kind() == reflect.Map { 99 keys := r.MapKeys() 100 for _, k := range keys { 101 if k.String() == field { 102 f1 := r.MapIndex(k) 103 return f1.Interface().(string) 104 } 105 } 106 return "" 107 } else { 108 f1 := reflect.Indirect(r).FieldByName(field) 109 return f1.String() 110 } 111 } 112 113 // CreateOptsBuilder allows extensions to add additional parameters to the 114 // Create request. 115 type CreateOptsBuilder interface { 116 ToClusterCreateMap() (map[string]interface{}, error) 117 } 118 119 // CreateOpts contains all the values needed to create a new cluster 120 type CreateOpts struct { 121 // API type, fixed value Cluster 122 Kind string `json:"kind" required:"true"` 123 // API version, fixed value v3 124 ApiVersion string `json:"apiversion" required:"true"` 125 // Metadata required to create a cluster 126 Metadata CreateMetaData `json:"metadata" required:"true"` 127 // specifications to create a cluster 128 Spec Spec `json:"spec" required:"true"` 129 } 130 131 // Metadata required to create a cluster 132 type CreateMetaData struct { 133 // Cluster unique name 134 Name string `json:"name" required:"true"` 135 // Cluster tag, key/value pair format 136 Labels map[string]string `json:"labels,omitempty"` 137 // Cluster annotation, key/value pair format 138 Annotations map[string]string `json:"annotations,omitempty"` 139 // Cluster alias 140 Alias string `json:"alias,omitempty"` 141 } 142 143 // ToClusterCreateMap builds a create request body from CreateOpts. 144 func (opts CreateOpts) ToClusterCreateMap() (map[string]interface{}, error) { 145 return golangsdk.BuildRequestBody(opts, "") 146 } 147 148 // Create accepts a CreateOpts struct and uses the values to create a new 149 // logical cluster. 150 func Create(c *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 151 b, err := opts.ToClusterCreateMap() 152 if err != nil { 153 r.Err = err 154 return 155 } 156 reqOpt := &golangsdk.RequestOpts{OkCodes: []int{201}} 157 _, r.Err = c.Post(rootURL(c), b, &r.Body, reqOpt) 158 return 159 } 160 161 // Get retrieves a particular cluster based on its unique ID. 162 func Get(c *golangsdk.ServiceClient, id string) (r GetResult) { 163 _, r.Err = c.Get(resourceURL(c, id), &r.Body, &golangsdk.RequestOpts{ 164 OkCodes: []int{200}, 165 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 166 }) 167 return 168 } 169 170 // GetCert retrieves a particular cluster certificate based on its unique ID. 171 func GetCert(c *golangsdk.ServiceClient, id string, opts GetCertOpts) (r GetCertResult) { 172 body, err := golangsdk.BuildRequestBody(opts, "") 173 if err != nil { 174 r.Err = err 175 return 176 } 177 _, r.Err = c.Post(certificateURL(c, id), body, &r.Body, nil) 178 return 179 } 180 181 type GetCertOpts struct { 182 Duration int `json:"duration" required:"true"` 183 } 184 185 // UpdateOpts contains all the values needed to update a new cluster 186 type UpdateOpts struct { 187 Spec UpdateSpec `json:"spec" required:"true"` 188 Metadata *UpdateMetadata `json:"metadata,omitempty"` 189 } 190 191 type UpdateMetadata struct { 192 // Cluster alias 193 Alias string `json:"alias"` 194 } 195 196 type UpdateSpec struct { 197 // Cluster description 198 Description string `json:"description,omitempty"` 199 // Custom san list for certificates 200 CustomSan []string `json:"customSan,omitempty"` 201 //Container network parameters 202 ContainerNetwork *UpdateContainerNetworkSpec `json:"containerNetwork,omitempty"` 203 // ENI network parameters 204 EniNetwork *EniNetworkSpec `json:"eniNetwork,omitempty"` 205 // Node network parameters 206 HostNetwork *UpdateHostNetworkSpec `json:"hostNetwork,omitempty"` 207 } 208 209 type UpdateContainerNetworkSpec struct { 210 // List of container CIDR blocks. In clusters of v1.21 and later, the cidrs field is used. 211 // When the cluster network type is vpc-router, you can add multiple container CIDR blocks. 212 // In versions earlier than v1.21, if the cidrs field is used, the first CIDR element in the array is used as the container CIDR block. 213 Cidrs []CidrSpec `json:"cidrs,omitempty"` 214 } 215 216 type UpdateHostNetworkSpec struct { 217 //The ID of the Security Group used to create the node 218 SecurityGroup string `json:"SecurityGroup,omitempty"` 219 } 220 221 // UpdateOptsBuilder allows extensions to add additional parameters to the 222 // Update request. 223 type UpdateOptsBuilder interface { 224 ToClusterUpdateMap() (map[string]interface{}, error) 225 } 226 227 // ToClusterUpdateMap builds an update body based on UpdateOpts. 228 func (opts UpdateOpts) ToClusterUpdateMap() (map[string]interface{}, error) { 229 return golangsdk.BuildRequestBody(opts, "") 230 } 231 232 // Update allows clusters to update description. 233 func Update(c *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { 234 b, err := opts.ToClusterUpdateMap() 235 if err != nil { 236 r.Err = err 237 return 238 } 239 _, r.Err = c.Put(resourceURL(c, id), b, &r.Body, &golangsdk.RequestOpts{ 240 OkCodes: []int{200}, 241 }) 242 return 243 } 244 245 type DeleteOpts struct { 246 ErrorStatus string `q:"errorStatus"` 247 DeleteEfs string `q:"delete_efs"` 248 DeleteENI string `q:"delete_eni"` 249 DeleteEvs string `q:"delete_evs"` 250 DeleteNet string `q:"delete_net"` 251 DeleteObs string `q:"delete_obs"` 252 DeleteSfs string `q:"delete_sfs"` 253 DeleteSfs30 string `q:"delete_sfs30"` 254 } 255 256 type DeleteOptsBuilder interface { 257 ToDeleteQuery() (string, error) 258 } 259 260 func (opts DeleteOpts) ToDeleteQuery() (string, error) { 261 q, err := golangsdk.BuildQueryString(opts) 262 return q.String(), err 263 } 264 265 // DeleteWithOpts will permanently delete a particular cluster based on its unique ID, 266 // and can delete associated resources based on DeleteOpts. 267 func DeleteWithOpts(c *golangsdk.ServiceClient, id string, opts DeleteOptsBuilder) (r DeleteResult) { 268 url := resourceURL(c, id) 269 if opts != nil { 270 var query string 271 query, r.Err = opts.ToDeleteQuery() 272 if r.Err != nil { 273 return 274 } 275 url += query 276 } 277 _, r.Err = c.Delete(url, &golangsdk.RequestOpts{ 278 OkCodes: []int{200}, 279 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 280 }) 281 return 282 } 283 284 // Delete will permanently delete a particular cluster based on its unique ID. 285 func Delete(c *golangsdk.ServiceClient, id string) (r DeleteResult) { 286 _, r.Err = c.Delete(resourceURL(c, id), &golangsdk.RequestOpts{ 287 OkCodes: []int{200}, 288 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 289 }) 290 return 291 } 292 293 type UpdateIpOpts struct { 294 Action string `json:"action" required:"true"` 295 Spec IpSpec `json:"spec,omitempty"` 296 ElasticIp string `json:"elasticIp"` 297 } 298 299 type IpSpec struct { 300 ID string `json:"id" required:"true"` 301 } 302 303 type UpdateIpOptsBuilder interface { 304 ToMasterIpUpdateMap() (map[string]interface{}, error) 305 } 306 307 func (opts UpdateIpOpts) ToMasterIpUpdateMap() (map[string]interface{}, error) { 308 return golangsdk.BuildRequestBody(opts, "spec") 309 } 310 311 // Update the access information of a specified cluster. 312 func UpdateMasterIp(c *golangsdk.ServiceClient, id string, opts UpdateIpOptsBuilder) (r UpdateIpResult) { 313 b, err := opts.ToMasterIpUpdateMap() 314 if err != nil { 315 r.Err = err 316 return 317 } 318 _, r.Err = c.Put(masterIpURL(c, id), b, nil, &golangsdk.RequestOpts{ 319 OkCodes: []int{200}, 320 }) 321 return 322 } 323 324 func Operation(c *golangsdk.ServiceClient, id, action string) (r OperationResult) { 325 _, r.Err = c.Post(operationURL(c, id, action), nil, nil, &golangsdk.RequestOpts{ 326 OkCodes: []int{200}, 327 MoreHeaders: RequestOpts.MoreHeaders, JSONBody: nil, 328 }) 329 return 330 } 331 332 type ResizeOpts struct { 333 FavorResize string `json:"flavorResize" required:"true"` 334 ExtendParam *ResizeExtendParam `json:"extendParam,omitempty"` 335 } 336 337 type ResizeExtendParam struct { 338 DecMasterFlavor string `json:"decMasterFlavor,omitempty"` 339 IsAutoPay string `json:"isAutoPay,omitempty"` 340 } 341 342 type ResizeResp struct { 343 JobID string `json:"jobID"` 344 OrderID string `json:"orderID"` 345 } 346 347 func Resize(c *golangsdk.ServiceClient, id string, opts ResizeOpts) (ResizeResp, error) { 348 var r ResizeResp 349 b, err := golangsdk.BuildRequestBody(opts, "") 350 if err != nil { 351 return r, err 352 } 353 354 _, err = c.Post(operationURL(c, id, "resize"), b, &r, &golangsdk.RequestOpts{ 355 OkCodes: []int{201}, 356 MoreHeaders: RequestOpts.MoreHeaders, 357 }) 358 return r, err 359 } 360 361 type UpdateTagsOpts struct { 362 Tags []tags.ResourceTag `json:"tags" required:"true"` 363 } 364 365 // AddTags will add tags to the cluster. 366 func AddTags(c *golangsdk.ServiceClient, id string, tagList []tags.ResourceTag) (r UpdateIpResult) { 367 opts := UpdateTagsOpts{ 368 Tags: tagList, 369 } 370 b, err := golangsdk.BuildRequestBody(opts, "") 371 if err != nil { 372 r.Err = err 373 return 374 } 375 _, r.Err = c.Post(tagsURL(c, id, "create"), b, nil, &golangsdk.RequestOpts{ 376 OkCodes: []int{204}, 377 }) 378 return 379 } 380 381 // RemoveTags will remove tags from the cluster. 382 func RemoveTags(c *golangsdk.ServiceClient, id string, tagList []tags.ResourceTag) (r UpdateIpResult) { 383 tagsWithKeys := make([]tags.ResourceTag, len(tagList)) 384 for i, v := range tagList { 385 tagsWithKeys[i] = tags.ResourceTag{ 386 Key: v.Key, 387 } 388 } 389 opts := UpdateTagsOpts{ 390 Tags: tagsWithKeys, 391 } 392 b, err := golangsdk.BuildRequestBody(opts, "") 393 if err != nil { 394 r.Err = err 395 return 396 } 397 _, r.Err = c.Post(tagsURL(c, id, "delete"), b, nil, &golangsdk.RequestOpts{ 398 OkCodes: []int{204}, 399 }) 400 return 401 }