github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/imageservice/v2/images/requests.go (about)

     1  package images
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"time"
     7  
     8  	"github.com/huaweicloud/golangsdk"
     9  	"github.com/huaweicloud/golangsdk/pagination"
    10  )
    11  
    12  // ListOptsBuilder allows extensions to add additional parameters to the
    13  // List request.
    14  type ListOptsBuilder interface {
    15  	ToImageListQuery() (string, error)
    16  }
    17  
    18  // ListOpts allows the filtering and sorting of paginated collections through
    19  // the API. Filtering is achieved by passing in struct field values that map to
    20  // the server attributes you want to see returned. Marker and Limit are used
    21  // for pagination.
    22  //
    23  // http://developer.openstack.org/api-ref-image-v2.html
    24  type ListOpts struct {
    25  	// ID is the ID of the image.
    26  	// Multiple IDs can be specified by constructing a string
    27  	// such as "in:uuid1,uuid2,uuid3".
    28  	ID string `q:"id"`
    29  
    30  	// Integer value for the limit of values to return.
    31  	Limit int `q:"limit"`
    32  
    33  	// UUID of the server at which you want to set a marker.
    34  	Marker string `q:"marker"`
    35  
    36  	// Name filters on the name of the image.
    37  	// Multiple names can be specified by constructing a string
    38  	// such as "in:name1,name2,name3".
    39  	Name string `q:"name"`
    40  
    41  	// Visibility filters on the visibility of the image.
    42  	Visibility ImageVisibility `q:"visibility"`
    43  
    44  	// MemberStatus filters on the member status of the image.
    45  	MemberStatus ImageMemberStatus `q:"member_status"`
    46  
    47  	// Owner filters on the project ID of the image.
    48  	Owner string `q:"owner"`
    49  
    50  	// Status filters on the status of the image.
    51  	// Multiple statuses can be specified by constructing a string
    52  	// such as "in:saving,queued".
    53  	Status ImageStatus `q:"status"`
    54  
    55  	// SizeMin filters on the size_min image property.
    56  	SizeMin int64 `q:"size_min"`
    57  
    58  	// SizeMax filters on the size_max image property.
    59  	SizeMax int64 `q:"size_max"`
    60  
    61  	// Sort sorts the results using the new style of sorting. See the OpenStack
    62  	// Image API reference for the exact syntax.
    63  	//
    64  	// Sort cannot be used with the classic sort options (sort_key and sort_dir).
    65  	Sort string `q:"sort"`
    66  
    67  	// SortKey will sort the results based on a specified image property.
    68  	SortKey string `q:"sort_key"`
    69  
    70  	// SortDir will sort the list results either ascending or decending.
    71  	SortDir string `q:"sort_dir"`
    72  
    73  	// Tags filters on specific image tags.
    74  	Tag string `q:"tag"`
    75  
    76  	// CreatedAtQuery filters images based on their creation date.
    77  	CreatedAtQuery *ImageDateQuery
    78  
    79  	// UpdatedAtQuery filters images based on their updated date.
    80  	UpdatedAtQuery *ImageDateQuery
    81  
    82  	// ContainerFormat filters images based on the container_format.
    83  	// Multiple container formats can be specified by constructing a
    84  	// string such as "in:bare,ami".
    85  	ContainerFormat string `q:"container_format"`
    86  
    87  	// DiskFormat filters images based on the disk_format.
    88  	// Multiple disk formats can be specified by constructing a string
    89  	// such as "in:qcow2,iso".
    90  	DiskFormat string `q:"disk_format"`
    91  }
    92  
    93  // ToImageListQuery formats a ListOpts into a query string.
    94  func (opts ListOpts) ToImageListQuery() (string, error) {
    95  	q, err := golangsdk.BuildQueryString(opts)
    96  	params := q.Query()
    97  
    98  	if opts.CreatedAtQuery != nil {
    99  		createdAt := opts.CreatedAtQuery.Date.Format(time.RFC3339)
   100  		if v := opts.CreatedAtQuery.Filter; v != "" {
   101  			createdAt = fmt.Sprintf("%s:%s", v, createdAt)
   102  		}
   103  
   104  		params.Add("created_at", createdAt)
   105  	}
   106  
   107  	if opts.UpdatedAtQuery != nil {
   108  		updatedAt := opts.UpdatedAtQuery.Date.Format(time.RFC3339)
   109  		if v := opts.UpdatedAtQuery.Filter; v != "" {
   110  			updatedAt = fmt.Sprintf("%s:%s", v, updatedAt)
   111  		}
   112  
   113  		params.Add("updated_at", updatedAt)
   114  	}
   115  
   116  	q = &url.URL{RawQuery: params.Encode()}
   117  
   118  	return q.String(), err
   119  }
   120  
   121  // List implements image list request.
   122  func List(c *golangsdk.ServiceClient, opts ListOptsBuilder) pagination.Pager {
   123  	url := listURL(c)
   124  	if opts != nil {
   125  		query, err := opts.ToImageListQuery()
   126  		if err != nil {
   127  			return pagination.Pager{Err: err}
   128  		}
   129  		url += query
   130  	}
   131  	return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
   132  		imagePage := ImagePage{
   133  			serviceURL:     c.ServiceURL(),
   134  			LinkedPageBase: pagination.LinkedPageBase{PageResult: r},
   135  		}
   136  
   137  		return imagePage
   138  	})
   139  }
   140  
   141  // CreateOptsBuilder allows extensions to add parameters to the Create request.
   142  type CreateOptsBuilder interface {
   143  	// Returns value that can be passed to json.Marshal
   144  	ToImageCreateMap() (map[string]interface{}, error)
   145  }
   146  
   147  // CreateOpts represents options used to create an image.
   148  type CreateOpts struct {
   149  	// Name is the name of the new image.
   150  	Name string `json:"name" required:"true"`
   151  
   152  	// Id is the the image ID.
   153  	ID string `json:"id,omitempty"`
   154  
   155  	// Visibility defines who can see/use the image.
   156  	Visibility *ImageVisibility `json:"visibility,omitempty"`
   157  
   158  	// Tags is a set of image tags.
   159  	Tags []string `json:"tags,omitempty"`
   160  
   161  	// ContainerFormat is the format of the
   162  	// container. Valid values are ami, ari, aki, bare, and ovf.
   163  	ContainerFormat string `json:"container_format,omitempty"`
   164  
   165  	// DiskFormat is the format of the disk. If set,
   166  	// valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi,
   167  	// and iso.
   168  	DiskFormat string `json:"disk_format,omitempty"`
   169  
   170  	// MinDisk is the amount of disk space in
   171  	// GB that is required to boot the image.
   172  	MinDisk int `json:"min_disk,omitempty"`
   173  
   174  	// MinRAM is the amount of RAM in MB that
   175  	// is required to boot the image.
   176  	MinRAM int `json:"min_ram,omitempty"`
   177  
   178  	// protected is whether the image is not deletable.
   179  	Protected *bool `json:"protected,omitempty"`
   180  
   181  	// properties is a set of properties, if any, that
   182  	// are associated with the image.
   183  	Properties map[string]string `json:"-"`
   184  }
   185  
   186  // ToImageCreateMap assembles a request body based on the contents of
   187  // a CreateOpts.
   188  func (opts CreateOpts) ToImageCreateMap() (map[string]interface{}, error) {
   189  	b, err := golangsdk.BuildRequestBody(opts, "")
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  
   194  	if opts.Properties != nil {
   195  		for k, v := range opts.Properties {
   196  			b[k] = v
   197  		}
   198  	}
   199  	return b, nil
   200  }
   201  
   202  // Create implements create image request.
   203  func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
   204  	b, err := opts.ToImageCreateMap()
   205  	if err != nil {
   206  		r.Err = err
   207  		return r
   208  	}
   209  	_, r.Err = client.Post(createURL(client), b, &r.Body, &golangsdk.RequestOpts{OkCodes: []int{201}})
   210  	return
   211  }
   212  
   213  // Delete implements image delete request.
   214  func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) {
   215  	_, r.Err = client.Delete(deleteURL(client, id), nil)
   216  	return
   217  }
   218  
   219  // Get implements image get request.
   220  func Get(client *golangsdk.ServiceClient, id string) (r GetResult) {
   221  	_, r.Err = client.Get(getURL(client, id), &r.Body, nil)
   222  	return
   223  }
   224  
   225  // Update implements image updated request.
   226  func Update(client *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
   227  	b, err := opts.ToImageUpdateMap()
   228  	if err != nil {
   229  		r.Err = err
   230  		return r
   231  	}
   232  	_, r.Err = client.Patch(updateURL(client, id), b, &r.Body, &golangsdk.RequestOpts{
   233  		OkCodes:     []int{200},
   234  		MoreHeaders: map[string]string{"Content-Type": "application/openstack-images-v2.1-json-patch"},
   235  	})
   236  	return
   237  }
   238  
   239  // UpdateOptsBuilder allows extensions to add additional parameters to the
   240  // Update request.
   241  type UpdateOptsBuilder interface {
   242  	// returns value implementing json.Marshaler which when marshaled matches
   243  	// the patch schema:
   244  	// http://specs.openstack.org/openstack/glance-specs/specs/api/v2/http-patch-image-api-v2.html
   245  	ToImageUpdateMap() ([]interface{}, error)
   246  }
   247  
   248  // UpdateOpts implements UpdateOpts
   249  type UpdateOpts []Patch
   250  
   251  // ToImageUpdateMap assembles a request body based on the contents of
   252  // UpdateOpts.
   253  func (opts UpdateOpts) ToImageUpdateMap() ([]interface{}, error) {
   254  	m := make([]interface{}, len(opts))
   255  	for i, patch := range opts {
   256  		patchJSON := patch.ToImagePatchMap()
   257  		m[i] = patchJSON
   258  	}
   259  	return m, nil
   260  }
   261  
   262  // Patch represents a single update to an existing image. Multiple updates
   263  // to an image can be submitted at the same time.
   264  type Patch interface {
   265  	ToImagePatchMap() map[string]interface{}
   266  }
   267  
   268  // UpdateVisibility represents an updated visibility property request.
   269  type UpdateVisibility struct {
   270  	Visibility ImageVisibility
   271  }
   272  
   273  // ToImagePatchMap assembles a request body based on UpdateVisibility.
   274  func (r UpdateVisibility) ToImagePatchMap() map[string]interface{} {
   275  	return map[string]interface{}{
   276  		"op":    "replace",
   277  		"path":  "/visibility",
   278  		"value": r.Visibility,
   279  	}
   280  }
   281  
   282  // ReplaceImageName represents an updated image_name property request.
   283  type ReplaceImageName struct {
   284  	NewName string
   285  }
   286  
   287  // ToImagePatchMap assembles a request body based on ReplaceImageName.
   288  func (r ReplaceImageName) ToImagePatchMap() map[string]interface{} {
   289  	return map[string]interface{}{
   290  		"op":    "replace",
   291  		"path":  "/name",
   292  		"value": r.NewName,
   293  	}
   294  }
   295  
   296  // ReplaceImageChecksum represents an updated checksum property request.
   297  type ReplaceImageChecksum struct {
   298  	Checksum string
   299  }
   300  
   301  // ReplaceImageChecksum assembles a request body based on ReplaceImageChecksum.
   302  func (r ReplaceImageChecksum) ToImagePatchMap() map[string]interface{} {
   303  	return map[string]interface{}{
   304  		"op":    "replace",
   305  		"path":  "/checksum",
   306  		"value": r.Checksum,
   307  	}
   308  }
   309  
   310  // ReplaceImageTags represents an updated tags property request.
   311  type ReplaceImageTags struct {
   312  	NewTags []string
   313  }
   314  
   315  // ToImagePatchMap assembles a request body based on ReplaceImageTags.
   316  func (r ReplaceImageTags) ToImagePatchMap() map[string]interface{} {
   317  	return map[string]interface{}{
   318  		"op":    "replace",
   319  		"path":  "/tags",
   320  		"value": r.NewTags,
   321  	}
   322  }
   323  
   324  // UpdateOp represents a valid update operation.
   325  type UpdateOp string
   326  
   327  const (
   328  	AddOp     UpdateOp = "add"
   329  	ReplaceOp UpdateOp = "replace"
   330  	RemoveOp  UpdateOp = "remove"
   331  )
   332  
   333  // UpdateImageProperty represents an update property request.
   334  type UpdateImageProperty struct {
   335  	Op    UpdateOp
   336  	Name  string
   337  	Value string
   338  }
   339  
   340  // ToImagePatchMap assembles a request body based on UpdateImageProperty.
   341  func (r UpdateImageProperty) ToImagePatchMap() map[string]interface{} {
   342  	updateMap := map[string]interface{}{
   343  		"op":   r.Op,
   344  		"path": fmt.Sprintf("/%s", r.Name),
   345  	}
   346  
   347  	if r.Value != "" {
   348  		updateMap["value"] = r.Value
   349  	}
   350  
   351  	return updateMap
   352  }