github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/openstack/compute/v2/flavors/requests.go (about) 1 package flavors 2 3 import ( 4 "github.com/opentelekomcloud/gophertelekomcloud" 5 "github.com/opentelekomcloud/gophertelekomcloud/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 if err != nil { 80 return "", err 81 } 82 return q.String(), err 83 } 84 85 // ListDetail instructs OpenStack to provide a list of flavors. 86 // You may provide criteria by which List curtails its results for easier 87 // processing. 88 func ListDetail(client *golangsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager { 89 url := listURL(client) 90 if opts != nil { 91 query, err := opts.ToFlavorListQuery() 92 if err != nil { 93 return pagination.Pager{Err: err} 94 } 95 url += query 96 } 97 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 98 return FlavorPage{pagination.LinkedPageBase{PageResult: r}} 99 }) 100 } 101 102 type CreateOptsBuilder interface { 103 ToFlavorCreateMap() (map[string]interface{}, error) 104 } 105 106 // CreateOpts specifies parameters used for creating a flavor. 107 type CreateOpts struct { 108 // Name is the name of the flavor. 109 Name string `json:"name" required:"true"` 110 111 // RAM is the memory of the flavor, measured in MB. 112 RAM int `json:"ram" required:"true"` 113 114 // VCPUs is the number of vcpus for the flavor. 115 VCPUs int `json:"vcpus" required:"true"` 116 117 // Disk the amount of root disk space, measured in GB. 118 Disk *int `json:"disk" required:"true"` 119 120 // ID is a unique ID for the flavor. 121 ID string `json:"id,omitempty"` 122 123 // Swap is the amount of swap space for the flavor, measured in MB. 124 Swap *int `json:"swap,omitempty"` 125 126 // RxTxFactor alters the network bandwidth of a flavor. 127 RxTxFactor float64 `json:"rxtx_factor,omitempty"` 128 129 // IsPublic flags a flavor as being available to all projects or not. 130 IsPublic *bool `json:"os-flavor-access:is_public,omitempty"` 131 132 // Ephemeral is the amount of ephemeral disk space, measured in GB. 133 Ephemeral *int `json:"OS-FLV-EXT-DATA:ephemeral,omitempty"` 134 } 135 136 // ToFlavorCreateMap constructs a request body from CreateOpts. 137 func (opts CreateOpts) ToFlavorCreateMap() (map[string]interface{}, error) { 138 return golangsdk.BuildRequestBody(opts, "flavor") 139 } 140 141 // Create requests the creation of a new flavor. 142 func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 143 b, err := opts.ToFlavorCreateMap() 144 if err != nil { 145 r.Err = err 146 return 147 } 148 _, r.Err = client.Post(createURL(client), b, &r.Body, &golangsdk.RequestOpts{ 149 OkCodes: []int{200, 201}, 150 }) 151 return 152 } 153 154 // Get retrieves details of a single flavor. Use ExtractFlavor to convert its 155 // result into a Flavor. 156 func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { 157 _, r.Err = client.Get(getURL(client, id), &r.Body, nil) 158 return 159 } 160 161 // Delete deletes the specified flavor ID. 162 func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) { 163 _, r.Err = client.Delete(deleteURL(client, id), nil) 164 return 165 } 166 167 // ListAccesses retrieves the tenants which have access to a flavor. 168 func ListAccesses(client *golangsdk.ServiceClient, id string) pagination.Pager { 169 url := accessURL(client, id) 170 171 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { 172 return AccessPage{pagination.SinglePageBase(r)} 173 }) 174 } 175 176 // AddAccessOptsBuilder allows extensions to add additional parameters to the 177 // AddAccess requests. 178 type AddAccessOptsBuilder interface { 179 ToFlavorAddAccessMap() (map[string]interface{}, error) 180 } 181 182 // AddAccessOpts represents options for adding access to a flavor. 183 type AddAccessOpts struct { 184 // Tenant is the project/tenant ID to grant access. 185 Tenant string `json:"tenant"` 186 } 187 188 // ToFlavorAddAccessMap constructs a request body from AddAccessOpts. 189 func (opts AddAccessOpts) ToFlavorAddAccessMap() (map[string]interface{}, error) { 190 return golangsdk.BuildRequestBody(opts, "addTenantAccess") 191 } 192 193 // AddAccess grants a tenant/project access to a flavor. 194 func AddAccess(client *golangsdk.ServiceClient, id string, opts AddAccessOptsBuilder) (r AddAccessResult) { 195 b, err := opts.ToFlavorAddAccessMap() 196 if err != nil { 197 r.Err = err 198 return 199 } 200 _, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &golangsdk.RequestOpts{ 201 OkCodes: []int{200}, 202 }) 203 return 204 } 205 206 // RemoveAccessOptsBuilder allows extensions to add additional parameters to the 207 // RemoveAccess requests. 208 type RemoveAccessOptsBuilder interface { 209 ToFlavorRemoveAccessMap() (map[string]interface{}, error) 210 } 211 212 // RemoveAccessOpts represents options for removing access to a flavor. 213 type RemoveAccessOpts struct { 214 // Tenant is the project/tenant ID to grant access. 215 Tenant string `json:"tenant"` 216 } 217 218 // ToFlavorRemoveAccessMap constructs a request body from RemoveAccessOpts. 219 func (opts RemoveAccessOpts) ToFlavorRemoveAccessMap() (map[string]interface{}, error) { 220 return golangsdk.BuildRequestBody(opts, "removeTenantAccess") 221 } 222 223 // RemoveAccess removes/revokes a tenant/project access to a flavor. 224 func RemoveAccess(client *golangsdk.ServiceClient, id string, opts RemoveAccessOptsBuilder) (r RemoveAccessResult) { 225 b, err := opts.ToFlavorRemoveAccessMap() 226 if err != nil { 227 r.Err = err 228 return 229 } 230 _, r.Err = client.Post(accessActionURL(client, id), b, &r.Body, &golangsdk.RequestOpts{ 231 OkCodes: []int{200}, 232 }) 233 return 234 } 235 236 // ExtraSpecs requests all the extra-specs for the given flavor ID. 237 func ListExtraSpecs(client *golangsdk.ServiceClient, flavorID string) (r ListExtraSpecsResult) { 238 _, r.Err = client.Get(extraSpecsListURL(client, flavorID), &r.Body, nil) 239 return 240 } 241 242 func GetExtraSpec(client *golangsdk.ServiceClient, flavorID string, key string) (r GetExtraSpecResult) { 243 _, r.Err = client.Get(extraSpecsGetURL(client, flavorID, key), &r.Body, nil) 244 return 245 } 246 247 // CreateExtraSpecsOptsBuilder allows extensions to add additional parameters to the 248 // CreateExtraSpecs requests. 249 type CreateExtraSpecsOptsBuilder interface { 250 ToFlavorExtraSpecsCreateMap() (map[string]interface{}, error) 251 } 252 253 // ExtraSpecsOpts is a map that contains key-value pairs. 254 type ExtraSpecsOpts map[string]string 255 256 // ToFlavorExtraSpecsCreateMap assembles a body for a Create request based on 257 // the contents of ExtraSpecsOpts. 258 func (opts ExtraSpecsOpts) ToFlavorExtraSpecsCreateMap() (map[string]interface{}, error) { 259 return map[string]interface{}{"extra_specs": opts}, nil 260 } 261 262 // CreateExtraSpecs will create or update the extra-specs key-value pairs for 263 // the specified Flavor. 264 func CreateExtraSpecs(client *golangsdk.ServiceClient, flavorID string, opts CreateExtraSpecsOptsBuilder) (r CreateExtraSpecsResult) { 265 b, err := opts.ToFlavorExtraSpecsCreateMap() 266 if err != nil { 267 r.Err = err 268 return 269 } 270 _, r.Err = client.Post(extraSpecsCreateURL(client, flavorID), b, &r.Body, &golangsdk.RequestOpts{ 271 OkCodes: []int{200}, 272 }) 273 return 274 } 275 276 // UpdateExtraSpecOptsBuilder allows extensions to add additional parameters to 277 // the Update request. 278 type UpdateExtraSpecOptsBuilder interface { 279 ToFlavorExtraSpecUpdateMap() (map[string]string, string, error) 280 } 281 282 // ToFlavorExtraSpecUpdateMap assembles a body for an Update request based on 283 // the contents of a ExtraSpecOpts. 284 func (opts ExtraSpecsOpts) ToFlavorExtraSpecUpdateMap() (map[string]string, string, error) { 285 if len(opts) != 1 { 286 err := golangsdk.ErrInvalidInput{} 287 err.Argument = "flavors.ExtraSpecOpts" 288 err.Info = "Must have 1 and only one key-value pair" 289 return nil, "", err 290 } 291 292 var key string 293 for k := range opts { 294 key = k 295 } 296 297 return opts, key, nil 298 } 299 300 // UpdateExtraSpec will updates the value of the specified flavor's extra spec 301 // for the key in opts. 302 func UpdateExtraSpec(client *golangsdk.ServiceClient, flavorID string, opts UpdateExtraSpecOptsBuilder) (r UpdateExtraSpecResult) { 303 b, key, err := opts.ToFlavorExtraSpecUpdateMap() 304 if err != nil { 305 r.Err = err 306 return 307 } 308 _, r.Err = client.Put(extraSpecUpdateURL(client, flavorID, key), b, &r.Body, &golangsdk.RequestOpts{ 309 OkCodes: []int{200}, 310 }) 311 return 312 } 313 314 // DeleteExtraSpec will delete the key-value pair with the given key for the given 315 // flavor ID. 316 func DeleteExtraSpec(client *golangsdk.ServiceClient, flavorID, key string) (r DeleteExtraSpecResult) { 317 _, r.Err = client.Delete(extraSpecDeleteURL(client, flavorID, key), &golangsdk.RequestOpts{ 318 OkCodes: []int{200}, 319 }) 320 return 321 } 322 323 // IDFromName is a convienience function that returns a flavor's ID given its 324 // name. 325 func IDFromName(client *golangsdk.ServiceClient, name string) (string, error) { 326 count := 0 327 id := "" 328 allPages, err := ListDetail(client, nil).AllPages() 329 if err != nil { 330 return "", err 331 } 332 333 all, err := ExtractFlavors(allPages) 334 if err != nil { 335 return "", err 336 } 337 338 for _, f := range all { 339 if f.Name == name { 340 count++ 341 id = f.ID 342 } 343 } 344 345 switch count { 346 case 0: 347 err := &golangsdk.ErrResourceNotFound{} 348 err.ResourceType = "flavor" 349 err.Name = name 350 return "", err 351 case 1: 352 return id, nil 353 default: 354 err := &golangsdk.ErrMultipleResourcesFound{} 355 err.ResourceType = "flavor" 356 err.Name = name 357 err.Count = count 358 return "", err 359 } 360 }