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  }