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 }