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  }