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