github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/compute/v2/flavors/requests.go (about) 1 package flavors 2 3 import ( 4 "github.com/huaweicloud/golangsdk" 5 "github.com/huaweicloud/golangsdk/pagination" 6 ) 7 8 // ListOptsBuilder allows extensions to add additional parameters to the 9 // List request. 10 type ListOptsBuilder interface { 11 ToFlavorListQuery() (string, error) 12 } 13 14 /* 15 AccessType maps to OpenStack's Flavor.is_public field. Although the is_public 16 field is boolean, the request options are ternary, which is why AccessType is 17 a string. The following values are allowed: 18 19 The AccessType arguement is optional, and if it is not supplied, OpenStack 20 returns the PublicAccess flavors. 21 */ 22 type AccessType string 23 24 const ( 25 // PublicAccess returns public flavors and private flavors associated with 26 // that project. 27 PublicAccess AccessType = "true" 28 29 // PrivateAccess (admin only) returns private flavors, across all projects. 30 PrivateAccess AccessType = "false" 31 32 // AllAccess (admin only) returns public and private flavors across all 33 // projects. 34 AllAccess AccessType = "None" 35 ) 36 37 /* 38 ListOpts filters the results returned by the List() function. 39 For example, a flavor with a minDisk field of 10 will not be returned if you 40 specify MinDisk set to 20. 41 42 Typically, software will use the last ID of the previous call to List to set 43 the Marker for the current call. 44 */ 45 type ListOpts struct { 46 // ChangesSince, if provided, instructs List to return only those things which 47 // have changed since the timestamp provided. 48 ChangesSince string `q:"changes-since"` 49 50 // MinDisk and MinRAM, if provided, elides flavors which do not meet your 51 // criteria. 52 MinDisk int `q:"minDisk"` 53 MinRAM int `q:"minRam"` 54 55 // SortDir allows to select sort direction. 56 // It can be "asc" or "desc" (default). 57 SortDir string `q:"sort_dir"` 58 59 // SortKey allows to sort by one of the flavors attributes. 60 // Default is flavorid. 61 SortKey string `q:"sort_key"` 62 63 // Marker and Limit control paging. 64 // Marker instructs List where to start listing from. 65 Marker string `q:"marker"` 66 67 // Limit instructs List to refrain from sending excessively large lists of 68 // flavors. 69 Limit int `q:"limit"` 70 71 // AccessType, if provided, instructs List which set of flavors to return. 72 // If IsPublic not provided, flavors for the current project are returned. 73 AccessType AccessType `q:"is_public"` 74 } 75 76 // ToFlavorListQuery formats a ListOpts into a query string. 77 func (opts ListOpts) ToFlavorListQuery() (string, error) { 78 q, err := golangsdk.BuildQueryString(opts) 79 return q.String(), err 80 } 81 82 // ListDetail instructs OpenStack to provide a list of flavors. 83 // You may provide criteria by which List curtails its results for easier 84 // processing. 85 func ListDetail(client *golangsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager { 86 url := listURL(client) 87 if opts != nil { 88 query, err := opts.ToFlavorListQuery() 89 if err != nil { 90 return pagination.Pager{Err: err} 91 } 92 url += query 93 } 94 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 95 return FlavorPage{pagination.LinkedPageBase{PageResult: r}} 96 }) 97 } 98 99 type CreateOptsBuilder interface { 100 ToFlavorCreateMap() (map[string]interface{}, error) 101 } 102 103 // CreateOpts specifies parameters used for creating a flavor. 104 type CreateOpts struct { 105 // Name is the name of the flavor. 106 Name string `json:"name" required:"true"` 107 108 // RAM is the memory of the flavor, measured in MB. 109 RAM int `json:"ram" required:"true"` 110 111 // VCPUs is the number of vcpus for the flavor. 112 VCPUs int `json:"vcpus" required:"true"` 113 114 // Disk the amount of root disk space, measured in GB. 115 Disk *int `json:"disk" required:"true"` 116 117 // ID is a unique ID for the flavor. 118 ID string `json:"id,omitempty"` 119 120 // Swap is the amount of swap space for the flavor, measured in MB. 121 Swap *int `json:"swap,omitempty"` 122 123 // RxTxFactor alters the network bandwidth of a flavor. 124 RxTxFactor float64 `json:"rxtx_factor,omitempty"` 125 126 // IsPublic flags a flavor as being available to all projects or not. 127 IsPublic *bool `json:"os-flavor-access:is_public,omitempty"` 128 129 // Ephemeral is the amount of ephemeral disk space, measured in GB. 130 Ephemeral *int `json:"OS-FLV-EXT-DATA:ephemeral,omitempty"` 131 } 132 133 // ToFlavorCreateMap constructs a request body from CreateOpts. 134 func (opts CreateOpts) ToFlavorCreateMap() (map[string]interface{}, error) { 135 return golangsdk.BuildRequestBody(opts, "flavor") 136 } 137 138 // Create requests the creation of a new flavor. 139 func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 140 b, err := opts.ToFlavorCreateMap() 141 if err != nil { 142 r.Err = err 143 return 144 } 145 _, r.Err = client.Post(createURL(client), b, &r.Body, &golangsdk.RequestOpts{ 146 OkCodes: []int{200, 201}, 147 }) 148 return 149 } 150 151 // Get retrieves details of a single flavor. Use ExtractFlavor to convert its 152 // result into a Flavor. 153 func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { 154 _, r.Err = client.Get(getURL(client, id), &r.Body, nil) 155 return 156 } 157 158 // Delete deletes the specified flavor ID. 159 func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) { 160 _, r.Err = client.Delete(deleteURL(client, id), nil) 161 return 162 } 163 164 // ListAccesses retrieves the tenants which have access to a flavor. 165 func ListAccesses(client *golangsdk.ServiceClient, id string) pagination.Pager { 166 url := accessURL(client, id) 167 168 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 169 return AccessPage{pagination.SinglePageBase(r)} 170 }) 171 } 172 173 // AddAccessOptsBuilder allows extensions to add additional parameters to the 174 // AddAccess requests. 175 type AddAccessOptsBuilder interface { 176 ToFlavorAddAccessMap() (map[string]interface{}, error) 177 } 178 179 // AddAccessOpts represents options for adding access to a flavor. 180 type AddAccessOpts struct { 181 // Tenant is the project/tenant ID to grant access. 182 Tenant string `json:"tenant"` 183 } 184 185 // ToFlavorAddAccessMap constructs a request body from AddAccessOpts. 186 func (opts AddAccessOpts) ToFlavorAddAccessMap() (map[string]interface{}, error) { 187 return golangsdk.BuildRequestBody(opts, "addTenantAccess") 188 } 189 190 // AddAccess grants a tenant/project access to a flavor. 191 func AddAccess(client *golangsdk.ServiceClient, id string, opts AddAccessOptsBuilder) (r AddAccessResult) { 192 b, err := opts.ToFlavorAddAccessMap() 193 if err != nil { 194 r.Err = err 195 return 196 } 197 _, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &golangsdk.RequestOpts{ 198 OkCodes: []int{200}, 199 }) 200 return 201 } 202 203 // RemoveAccessOptsBuilder allows extensions to add additional parameters to the 204 // RemoveAccess requests. 205 type RemoveAccessOptsBuilder interface { 206 ToFlavorRemoveAccessMap() (map[string]interface{}, error) 207 } 208 209 // RemoveAccessOpts represents options for removing access to a flavor. 210 type RemoveAccessOpts struct { 211 // Tenant is the project/tenant ID to grant access. 212 Tenant string `json:"tenant"` 213 } 214 215 // ToFlavorRemoveAccessMap constructs a request body from RemoveAccessOpts. 216 func (opts RemoveAccessOpts) ToFlavorRemoveAccessMap() (map[string]interface{}, error) { 217 return golangsdk.BuildRequestBody(opts, "removeTenantAccess") 218 } 219 220 // RemoveAccess removes/revokes a tenant/project access to a flavor. 221 func RemoveAccess(client *golangsdk.ServiceClient, id string, opts RemoveAccessOptsBuilder) (r RemoveAccessResult) { 222 b, err := opts.ToFlavorRemoveAccessMap() 223 if err != nil { 224 r.Err = err 225 return 226 } 227 _, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &golangsdk.RequestOpts{ 228 OkCodes: []int{200}, 229 }) 230 return 231 } 232 233 // ExtraSpecs requests all the extra-specs for the given flavor ID. 234 func ListExtraSpecs(client *golangsdk.ServiceClient, flavorID string) (r ListExtraSpecsResult) { 235 _, r.Err = client.Get(extraSpecsListURL(client, flavorID), &r.Body, nil) 236 return 237 } 238 239 func GetExtraSpec(client *golangsdk.ServiceClient, flavorID string, key string) (r GetExtraSpecResult) { 240 _, r.Err = client.Get(extraSpecsGetURL(client, flavorID, key), &r.Body, nil) 241 return 242 } 243 244 // CreateExtraSpecsOptsBuilder allows extensions to add additional parameters to the 245 // CreateExtraSpecs requests. 246 type CreateExtraSpecsOptsBuilder interface { 247 ToFlavorExtraSpecsCreateMap() (map[string]interface{}, error) 248 } 249 250 // ExtraSpecsOpts is a map that contains key-value pairs. 251 type ExtraSpecsOpts map[string]string 252 253 // ToFlavorExtraSpecsCreateMap assembles a body for a Create request based on 254 // the contents of ExtraSpecsOpts. 255 func (opts ExtraSpecsOpts) ToFlavorExtraSpecsCreateMap() (map[string]interface{}, error) { 256 return map[string]interface{}{"extra_specs": opts}, nil 257 } 258 259 // CreateExtraSpecs will create or update the extra-specs key-value pairs for 260 // the specified Flavor. 261 func CreateExtraSpecs(client *golangsdk.ServiceClient, flavorID string, opts CreateExtraSpecsOptsBuilder) (r CreateExtraSpecsResult) { 262 b, err := opts.ToFlavorExtraSpecsCreateMap() 263 if err != nil { 264 r.Err = err 265 return 266 } 267 _, r.Err = client.Post(extraSpecsCreateURL(client, flavorID), b, &r.Body, &golangsdk.RequestOpts{ 268 OkCodes: []int{200}, 269 }) 270 return 271 } 272 273 // UpdateExtraSpecOptsBuilder allows extensions to add additional parameters to 274 // the Update request. 275 type UpdateExtraSpecOptsBuilder interface { 276 ToFlavorExtraSpecUpdateMap() (map[string]string, string, error) 277 } 278 279 // ToFlavorExtraSpecUpdateMap assembles a body for an Update request based on 280 // the contents of a ExtraSpecOpts. 281 func (opts ExtraSpecsOpts) ToFlavorExtraSpecUpdateMap() (map[string]string, string, error) { 282 if len(opts) != 1 { 283 err := golangsdk.ErrInvalidInput{} 284 err.Argument = "flavors.ExtraSpecOpts" 285 err.Info = "Must have 1 and only one key-value pair" 286 return nil, "", err 287 } 288 289 var key string 290 for k := range opts { 291 key = k 292 } 293 294 return opts, key, nil 295 } 296 297 // UpdateExtraSpec will updates the value of the specified flavor's extra spec 298 // for the key in opts. 299 func UpdateExtraSpec(client *golangsdk.ServiceClient, flavorID string, opts UpdateExtraSpecOptsBuilder) (r UpdateExtraSpecResult) { 300 b, key, err := opts.ToFlavorExtraSpecUpdateMap() 301 if err != nil { 302 r.Err = err 303 return 304 } 305 _, r.Err = client.Put(extraSpecUpdateURL(client, flavorID, key), b, &r.Body, &golangsdk.RequestOpts{ 306 OkCodes: []int{200}, 307 }) 308 return 309 } 310 311 // DeleteExtraSpec will delete the key-value pair with the given key for the given 312 // flavor ID. 313 func DeleteExtraSpec(client *golangsdk.ServiceClient, flavorID, key string) (r DeleteExtraSpecResult) { 314 _, r.Err = client.Delete(extraSpecDeleteURL(client, flavorID, key), &golangsdk.RequestOpts{ 315 OkCodes: []int{200}, 316 }) 317 return 318 } 319 320 // IDFromName is a convienience function that returns a flavor's ID given its 321 // name. 322 func IDFromName(client *golangsdk.ServiceClient, name string) (string, error) { 323 count := 0 324 id := "" 325 allPages, err := ListDetail(client, nil).AllPages() 326 if err != nil { 327 return "", err 328 } 329 330 all, err := ExtractFlavors(allPages) 331 if err != nil { 332 return "", err 333 } 334 335 for _, f := range all { 336 if f.Name == name { 337 count++ 338 id = f.ID 339 } 340 } 341 342 switch count { 343 case 0: 344 err := &golangsdk.ErrResourceNotFound{} 345 err.ResourceType = "flavor" 346 err.Name = name 347 return "", err 348 case 1: 349 return id, nil 350 default: 351 err := &golangsdk.ErrMultipleResourcesFound{} 352 err.ResourceType = "flavor" 353 err.Name = name 354 err.Count = count 355 return "", err 356 } 357 }