gopkg.in/goose.v2@v2.0.1/cinder/autogenerated_client.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the LGPLv3, see LICENCE file for details. 3 4 // This file was initially autogenerated from the upstream wadl file, but has 5 // since been updated by hand. 6 // The WADLs were originally sourced from: 7 // https://github.com/openstack/api-site/tree/master/api-ref/src/wadls/volume-api/src/v2 8 9 package cinder 10 11 import ( 12 "bytes" 13 "encoding/json" 14 "fmt" 15 "io/ioutil" 16 "net/http" 17 "net/url" 18 19 "gopkg.in/goose.v2/client" 20 gooseerrors "gopkg.in/goose.v2/errors" 21 goosehttp "gopkg.in/goose.v2/http" 22 ) 23 24 // RequestHandlerFn specifies a function signature which wadl2go will 25 // use to process the http.Request. What this means is up to the 26 // implementor. 27 type RequestHandlerFn func(*http.Request) (*http.Response, error) 28 29 // RoundTrip is part of the http.RoundTripper interface. 30 func (f RequestHandlerFn) RoundTrip(req *http.Request) (*http.Response, error) { 31 return f(req) 32 } 33 34 type UpdateVolumeTypeParams struct { 35 36 // VolumeType is required. 37 // 38 // A volume type offers a way to categorize or group volumes. 39 VolumeType string `json:"volume_type"` 40 41 // 42 // The unique identifier of the tenant or account. 43 TenantId string `json:"-"` 44 45 // VolumeTypeId is required. 46 // 47 // The unique identifier for an existing volume type. 48 VolumeTypeId string `json:"-"` 49 } 50 51 type VolumeType struct { 52 ExtraSpecs struct { 53 Capabilities string `json:"capabilities"` 54 } `json:"extra_specs"` 55 ID string `json:"id"` 56 Name string `json:"name"` 57 } 58 59 type UpdateVolumeTypeResults struct { 60 VolumeType VolumeType `json:"volume_type"` 61 } 62 63 // 64 // Updates a volume type. 65 func updateVolumeType(client *Client, args UpdateVolumeTypeParams) (*UpdateVolumeTypeResults, error) { 66 67 argsAsJson, err := json.Marshal(args) 68 if err != nil { 69 return nil, err 70 } 71 72 urlPath := url.URL{Path: fmt.Sprintf("types/%s", args.VolumeTypeId)} 73 url := client.endpoint.ResolveReference(&urlPath).String() 74 75 var req *http.Request 76 if string(argsAsJson) != "{}" { 77 req, err = http.NewRequest("PUT", url, bytes.NewBuffer(argsAsJson)) 78 if err != nil { 79 return nil, err 80 } 81 req.Header.Set("Content-Type", "application/json") 82 } else { 83 req, err = http.NewRequest("PUT", url, nil) 84 if err != nil { 85 return nil, err 86 } 87 } 88 89 resp, err := client.handleRequest(req) 90 if err != nil { 91 return nil, err 92 } 93 94 body, err := ioutil.ReadAll(resp.Body) 95 if err != nil { 96 return nil, err 97 } 98 99 switch resp.StatusCode { 100 default: 101 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 102 case 200: 103 break 104 } 105 106 var results UpdateVolumeTypeResults 107 json.Unmarshal(body, &results) 108 109 return &results, nil 110 } 111 112 type UpdateVolumeTypeExtraSpecsParams struct { 113 114 // VolumeType is required. 115 // 116 // A volume type offers a way to categorize or group volumes. 117 VolumeType string `json:"volume_type"` 118 119 // ExtraSpecs is required. 120 // 121 // A key:value pair that offers a way to show additional specifications associated with the volume type. Examples include capabilities, capacity, compression, and so on, depending on the storage driver in use. 122 ExtraSpecs string `json:"extra_specs"` 123 124 // 125 // The unique identifier of the tenant or account. 126 TenantId string `json:"-"` 127 128 // VolumeTypeId is required. 129 // 130 // The unique identifier for an existing volume type. 131 VolumeTypeId string `json:"-"` 132 } 133 134 type UpdateVolumeTypeExtraSpecsResults struct { 135 VolumeType VolumeType `json:"volume_type"` 136 } 137 138 // 139 // Updates the extra specifications assigned to a volume type. 140 func updateVolumeTypeExtraSpecs(client *Client, args UpdateVolumeTypeExtraSpecsParams) (*UpdateVolumeTypeExtraSpecsResults, error) { 141 142 argsAsJson, err := json.Marshal(args) 143 if err != nil { 144 return nil, err 145 } 146 147 urlPath := url.URL{Path: fmt.Sprintf("types/%s", args.VolumeTypeId)} 148 url := client.endpoint.ResolveReference(&urlPath).String() 149 150 var req *http.Request 151 if string(argsAsJson) != "{}" { 152 req, err = http.NewRequest("PUT", url, bytes.NewBuffer(argsAsJson)) 153 if err != nil { 154 return nil, err 155 } 156 req.Header.Set("Content-Type", "application/json") 157 } else { 158 req, err = http.NewRequest("PUT", url, nil) 159 if err != nil { 160 return nil, err 161 } 162 } 163 164 resp, err := client.handleRequest(req) 165 if err != nil { 166 return nil, err 167 } 168 169 body, err := ioutil.ReadAll(resp.Body) 170 if err != nil { 171 return nil, err 172 } 173 174 switch resp.StatusCode { 175 default: 176 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 177 case 200: 178 break 179 } 180 181 var results UpdateVolumeTypeExtraSpecsResults 182 json.Unmarshal(body, &results) 183 184 return &results, nil 185 } 186 187 type GetSnapshotsSimpleParams struct { 188 189 // 190 // The unique identifier of the tenant or account. 191 TenantId string `json:"-"` 192 } 193 194 type Snapshot struct { 195 CreatedAt string `json:"created_at"` 196 Description string `json:"description"` 197 ID string `json:"id"` 198 Metadata struct { 199 Key string `json:"key"` 200 } `json:"metadata"` 201 Name string `json:"name"` 202 Size int `json:"size"` 203 Status string `json:"status"` 204 VolumeID string `json:"volume_id"` 205 Os_Extended_Snapshot_Attributes_Progress string `json:"os-extended-snapshot-attributes:progress"` 206 Os_Extended_Snapshot_Attributes_ProjectID string `json:"os-extended-snapshot-attributes:project_id"` 207 } 208 209 type GetSnapshotsSimpleResults struct { 210 Snapshots []Snapshot `json:"snapshots"` 211 } 212 213 // 214 // Lists summary information for all Block Storage snapshots that the tenant who submits the request can access. 215 func getSnapshotsSimple(client *Client, args GetSnapshotsSimpleParams) (*GetSnapshotsSimpleResults, error) { 216 217 argsAsJson, err := json.Marshal(args) 218 if err != nil { 219 return nil, err 220 } 221 222 urlPath := url.URL{Path: "snapshots"} 223 url := client.endpoint.ResolveReference(&urlPath).String() 224 225 var req *http.Request 226 if string(argsAsJson) != "{}" { 227 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 228 if err != nil { 229 return nil, err 230 } 231 req.Header.Set("Content-Type", "application/json") 232 } else { 233 req, err = http.NewRequest("GET", url, nil) 234 if err != nil { 235 return nil, err 236 } 237 } 238 239 resp, err := client.handleRequest(req) 240 if err != nil { 241 return nil, err 242 } 243 244 body, err := ioutil.ReadAll(resp.Body) 245 if err != nil { 246 return nil, err 247 } 248 249 switch resp.StatusCode { 250 default: 251 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 252 case 200: 253 break 254 } 255 256 var results GetSnapshotsSimpleResults 257 json.Unmarshal(body, &results) 258 259 return &results, nil 260 } 261 262 type UpdateSnapshotSnapshotParams struct { 263 264 // Describes the snapshot. 265 Description string `json:"description,omitempty"` 266 267 // The name of the snapshot. 268 Name string `json:"name,omitempty"` 269 } 270 271 type UpdateSnapshotParams struct { 272 273 // Snapshot is required. 274 275 Snapshot UpdateSnapshotSnapshotParams `json:"snapshot"` 276 277 // 278 // The unique identifier of the tenant or account. 279 TenantId string `json:"-"` 280 281 // SnapshotId is required. 282 // 283 // The unique identifier of an existing snapshot. 284 SnapshotId string `json:"-"` 285 } 286 287 type UpdateSnapshotResults struct { 288 Snapshot Snapshot `json:"snapshot"` 289 } 290 291 // 292 // Updates a specified snapshot. 293 func updateSnapshot(client *Client, args UpdateSnapshotParams) (*UpdateSnapshotResults, error) { 294 295 argsAsJson, err := json.Marshal(args) 296 if err != nil { 297 return nil, err 298 } 299 300 urlPath := url.URL{Path: fmt.Sprintf("snapshots/%s", args.SnapshotId)} 301 url := client.endpoint.ResolveReference(&urlPath).String() 302 303 var req *http.Request 304 if string(argsAsJson) != "{}" { 305 req, err = http.NewRequest("PUT", url, bytes.NewBuffer(argsAsJson)) 306 if err != nil { 307 return nil, err 308 } 309 req.Header.Set("Content-Type", "application/json") 310 } else { 311 req, err = http.NewRequest("PUT", url, nil) 312 if err != nil { 313 return nil, err 314 } 315 } 316 317 resp, err := client.handleRequest(req) 318 if err != nil { 319 return nil, err 320 } 321 322 body, err := ioutil.ReadAll(resp.Body) 323 if err != nil { 324 return nil, err 325 } 326 327 switch resp.StatusCode { 328 default: 329 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 330 case 200: 331 break 332 } 333 334 var results UpdateSnapshotResults 335 json.Unmarshal(body, &results) 336 337 return &results, nil 338 } 339 340 type ShowSnapshotMetadataParams struct { 341 342 // 343 // The unique identifier of the tenant or account. 344 TenantId string `json:"-"` 345 346 // SnapshotId is required. 347 // 348 // The unique identifier of an existing snapshot. 349 SnapshotId string `json:"-"` 350 } 351 352 type ShowSnapshotMetadataResults struct { 353 Snapshot Snapshot `json:"snapshot"` 354 } 355 356 // 357 // Shows the metadata for a specified snapshot. 358 func showSnapshotMetadata(client *Client, args ShowSnapshotMetadataParams) (*ShowSnapshotMetadataResults, error) { 359 360 argsAsJson, err := json.Marshal(args) 361 if err != nil { 362 return nil, err 363 } 364 365 urlPath := url.URL{Path: fmt.Sprintf("snapshots/%s/metadata", args.SnapshotId)} 366 url := client.endpoint.ResolveReference(&urlPath).String() 367 368 var req *http.Request 369 if string(argsAsJson) != "{}" { 370 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 371 if err != nil { 372 return nil, err 373 } 374 req.Header.Set("Content-Type", "application/json") 375 } else { 376 req, err = http.NewRequest("GET", url, nil) 377 if err != nil { 378 return nil, err 379 } 380 } 381 382 resp, err := client.handleRequest(req) 383 if err != nil { 384 return nil, err 385 } 386 387 body, err := ioutil.ReadAll(resp.Body) 388 if err != nil { 389 return nil, err 390 } 391 392 switch resp.StatusCode { 393 default: 394 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 395 case 200: 396 break 397 } 398 399 var results ShowSnapshotMetadataResults 400 json.Unmarshal(body, &results) 401 402 return &results, nil 403 } 404 405 type GetVolumesDetailParams struct { 406 407 // 408 // The unique identifier of the tenant or account. 409 TenantId string `json:"-"` 410 } 411 412 type VolumeAttachment struct { 413 Device string `json:"device"` 414 Id string `json:"id"` 415 ServerId string `json:"server_id"` 416 VolumeId string `json:"volume_id"` 417 } 418 419 type Volume struct { 420 Attachments []VolumeAttachment `json:"attachments"` 421 AvailabilityZone string `json:"availability_zone"` 422 Bootable string `json:"bootable"` 423 CreatedAt string `json:"created_at"` 424 Description string `json:"description"` 425 ID string `json:"id"` 426 Links []struct { 427 Href string `json:"href"` 428 Rel string `json:"rel"` 429 } `json:"links"` 430 Metadata map[string]string `json:"metadata"` 431 Name string `json:"name"` 432 Os_Vol_Host_Attr_Host string `json:"os-vol-host-attr:host"` 433 Os_Vol_Tenant_Attr_TenantID string `json:"os-vol-tenant-attr:tenant_id"` 434 Size int `json:"size"` 435 SnapshotID interface{} `json:"snapshot_id"` 436 SourceVolid interface{} `json:"source_volid"` 437 Status string `json:"status"` 438 VolumeType string `json:"volume_type"` 439 } 440 441 type GetVolumesDetailResults struct { 442 Volumes []Volume `json:"volumes"` 443 } 444 445 // 446 // Lists detailed information for all Block Storage volumes that the tenant who submits the request can access. 447 func getVolumesDetail(client *Client, args GetVolumesDetailParams) (*GetVolumesDetailResults, error) { 448 449 argsAsJson, err := json.Marshal(args) 450 if err != nil { 451 return nil, err 452 } 453 454 urlPath := url.URL{Path: "volumes/detail"} 455 url := client.endpoint.ResolveReference(&urlPath).String() 456 457 var req *http.Request 458 if string(argsAsJson) != "{}" { 459 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 460 if err != nil { 461 return nil, err 462 } 463 req.Header.Set("Content-Type", "application/json") 464 } else { 465 req, err = http.NewRequest("GET", url, nil) 466 if err != nil { 467 return nil, err 468 } 469 } 470 471 resp, err := client.handleRequest(req) 472 if err != nil { 473 return nil, err 474 } 475 476 body, err := ioutil.ReadAll(resp.Body) 477 if err != nil { 478 return nil, err 479 } 480 481 switch resp.StatusCode { 482 default: 483 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 484 case 200: 485 break 486 } 487 488 var results GetVolumesDetailResults 489 json.Unmarshal(body, &results) 490 491 return &results, nil 492 } 493 494 type GetVolumeParams struct { 495 496 // 497 // The unique identifier of the tenant or account. 498 TenantId string `json:"-"` 499 500 // VolumeId is required. 501 // 502 // The unique identifier of an existing volume. 503 VolumeId string `json:"-"` 504 } 505 506 type GetVolumeResults struct { 507 Volume Volume `json:"volume"` 508 } 509 510 // 511 // Shows information about a specified volume. 512 // Preconditions 513 // 514 // The specified volume must exist. : 515 func getVolume(c *Client, args GetVolumeParams) (*GetVolumeResults, error) { 516 var results GetVolumeResults 517 requestData := goosehttp.RequestData{ 518 RespValue: &results, 519 ExpectedStatus: []int{http.StatusOK}, 520 } 521 urlPath := url.URL{Path: fmt.Sprintf("volumes/%s", args.VolumeId)} 522 url := c.endpoint.ResolveReference(&urlPath).String() 523 err := c.client.JsonRequest(client.GET, url, "", &requestData, nil) 524 if err != nil { 525 return nil, err 526 } 527 return &results, nil 528 } 529 530 type UpdateVolumeVolumeParams struct { 531 Name string `json:"name,omitempty"` 532 533 Description string `json:"description,omitempty"` 534 } 535 536 type UpdateVolumeParams struct { 537 538 // Volume is required. 539 540 Volume UpdateVolumeVolumeParams `json:"volume"` 541 542 // 543 // The unique identifier of the tenant or account. 544 TenantId string `json:"-"` 545 546 // VolumeId is required. 547 // 548 // The unique identifier of an existing volume. 549 VolumeId string `json:"-"` 550 } 551 552 type UpdateVolumeResults struct { 553 Volume Volume `json:"volume"` 554 } 555 556 // 557 // Updates a volume. 558 func updateVolume(client *Client, args UpdateVolumeParams) (*UpdateVolumeResults, error) { 559 560 argsAsJson, err := json.Marshal(args) 561 if err != nil { 562 return nil, err 563 } 564 565 urlPath := url.URL{Path: fmt.Sprintf("volumes/%s", args.VolumeId)} 566 url := client.endpoint.ResolveReference(&urlPath).String() 567 568 var req *http.Request 569 if string(argsAsJson) != "{}" { 570 req, err = http.NewRequest("PUT", url, bytes.NewBuffer(argsAsJson)) 571 if err != nil { 572 return nil, err 573 } 574 req.Header.Set("Content-Type", "application/json") 575 } else { 576 req, err = http.NewRequest("PUT", url, nil) 577 if err != nil { 578 return nil, err 579 } 580 } 581 582 resp, err := client.handleRequest(req) 583 if err != nil { 584 return nil, err 585 } 586 587 body, err := ioutil.ReadAll(resp.Body) 588 if err != nil { 589 return nil, err 590 } 591 592 switch resp.StatusCode { 593 default: 594 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 595 case 200: 596 break 597 } 598 599 var results UpdateVolumeResults 600 json.Unmarshal(body, &results) 601 602 return &results, nil 603 } 604 605 type DeleteVolumeParams struct { 606 607 // 608 // The unique identifier of the tenant or account. 609 TenantId string `json:"-"` 610 611 // VolumeId is required. 612 // 613 // The unique identifier of an existing volume. 614 VolumeId string `json:"-"` 615 } 616 617 type DeleteVolumeResults struct { 618 } 619 620 // 621 // Deletes a specified volume. 622 // Preconditions 623 // 624 // Volume status must be available, in-use, error, or error_restoring. 625 // You cannot already have a snapshot related to the specified volume. 626 // You cannot delete a volume that is in a migration. : 627 // Asynchronous Postconditions 628 // 629 // The volume is deleted in volume index. 630 // The volume managed by OpenStack Block Storage is deleted in storage node. : 631 // Troubleshooting 632 // 633 // If volume status remains in deleting or becomes error_deleting the request failed. Ensure you meet the preconditions then investigate the storage backend. 634 // The volume managed by OpenStack Block Storage is not deleted from the storage system. : 635 func deleteVolume(c *Client, args DeleteVolumeParams) (*DeleteVolumeResults, error) { 636 var results DeleteVolumeResults 637 requestData := goosehttp.RequestData{ 638 RespValue: &results, 639 ExpectedStatus: []int{http.StatusAccepted}, 640 } 641 urlPath := url.URL{Path: fmt.Sprintf("volumes/%s", args.VolumeId)} 642 url := c.endpoint.ResolveReference(&urlPath).String() 643 err := c.client.JsonRequest(client.DELETE, url, "", &requestData, nil) 644 if err != nil { 645 return nil, err 646 } 647 return &results, nil 648 } 649 650 type CreateVolumeTypeVolumeTypeExtraSpecsParams struct { 651 Capabilities string `json:"capabilities,omitempty"` 652 } 653 654 type CreateVolumeTypeVolumeTypeParams struct { 655 656 // The name of the volume type. 657 Name string `json:"name,omitempty"` 658 659 ExtraSpecs CreateVolumeTypeVolumeTypeExtraSpecsParams `json:"extra_specs,omitempty"` 660 } 661 662 type CreateVolumeTypeParams struct { 663 664 // VolumeType is required. 665 // A partial representation of a volume type used in the creation process. 666 VolumeType CreateVolumeTypeVolumeTypeParams `json:"volume_type"` 667 668 // 669 // The unique identifier of the tenant or account. 670 TenantId string `json:"-"` 671 } 672 673 type CreateVolumeTypeResults struct { 674 VolumeType VolumeType `json:"volume_type"` 675 } 676 677 // 678 // Creates a volume type. 679 func createVolumeType(client *Client, args CreateVolumeTypeParams) (*CreateVolumeTypeResults, error) { 680 681 argsAsJson, err := json.Marshal(args) 682 if err != nil { 683 return nil, err 684 } 685 686 urlPath := url.URL{Path: "types"} 687 url := client.endpoint.ResolveReference(&urlPath).String() 688 689 var req *http.Request 690 if string(argsAsJson) != "{}" { 691 req, err = http.NewRequest("POST", url, bytes.NewBuffer(argsAsJson)) 692 if err != nil { 693 return nil, err 694 } 695 req.Header.Set("Content-Type", "application/json") 696 } else { 697 req, err = http.NewRequest("POST", url, nil) 698 if err != nil { 699 return nil, err 700 } 701 } 702 703 resp, err := client.handleRequest(req) 704 if err != nil { 705 return nil, err 706 } 707 708 body, err := ioutil.ReadAll(resp.Body) 709 if err != nil { 710 return nil, err 711 } 712 713 switch resp.StatusCode { 714 default: 715 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 716 case 200: 717 break 718 } 719 720 var results CreateVolumeTypeResults 721 json.Unmarshal(body, &results) 722 723 return &results, nil 724 } 725 726 type CreateSnapshotSnapshotParams struct { 727 728 // [True/False] Indicate whether to snapshot, even if the volume is attached. Default==False. 729 Force bool `json:"force,omitempty"` 730 731 // Name of the snapshot. The default is None. 732 Name string `json:"name,omitempty"` 733 734 // Description of the snapshot. The default is None. 735 Description string `json:"description,omitempty"` 736 737 // VolumeId is required. 738 // To create a snapshot from an existing volume, specify the ID of the existing volume. 739 VolumeId string `json:"volume_id"` 740 } 741 742 type CreateSnapshotParams struct { 743 744 // Snapshot is required. 745 // A partial representation of a snapshot used in the creation process. 746 Snapshot CreateSnapshotSnapshotParams `json:"snapshot"` 747 748 // 749 // The unique identifier of the tenant or account. 750 TenantId string `json:"-"` 751 } 752 753 type CreateSnapshotResults struct { 754 Snapshot Snapshot `json:"snapshot"` 755 } 756 757 // 758 // Creates a snapshot, which is a point-in-time complete copy of a volume. You can create a volume from the snapshot. 759 func createSnapshot(client *Client, args CreateSnapshotParams) (*CreateSnapshotResults, error) { 760 761 argsAsJson, err := json.Marshal(args) 762 if err != nil { 763 return nil, err 764 } 765 766 urlPath := url.URL{Path: "snapshots"} 767 url := client.endpoint.ResolveReference(&urlPath).String() 768 769 var req *http.Request 770 if string(argsAsJson) != "{}" { 771 req, err = http.NewRequest("POST", url, bytes.NewBuffer(argsAsJson)) 772 if err != nil { 773 return nil, err 774 } 775 req.Header.Set("Content-Type", "application/json") 776 } else { 777 req, err = http.NewRequest("POST", url, nil) 778 if err != nil { 779 return nil, err 780 } 781 } 782 783 resp, err := client.handleRequest(req) 784 if err != nil { 785 return nil, err 786 } 787 788 body, err := ioutil.ReadAll(resp.Body) 789 if err != nil { 790 return nil, err 791 } 792 793 switch resp.StatusCode { 794 default: 795 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 796 case 200, 202: 797 break 798 } 799 800 var results CreateSnapshotResults 801 json.Unmarshal(body, &results) 802 803 return &results, nil 804 } 805 806 type GetSnapshotsDetailParams struct { 807 808 // 809 // The unique identifier of the tenant or account. 810 TenantId string `json:"-"` 811 } 812 813 type GetSnapshotsDetailResults struct { 814 Snapshots []Snapshot `json:"snapshots"` 815 } 816 817 // 818 // Lists detailed information for all Block Storage snapshots that the tenant who submits the request can access. 819 func getSnapshotsDetail(client *Client, args GetSnapshotsDetailParams) (*GetSnapshotsDetailResults, error) { 820 821 argsAsJson, err := json.Marshal(args) 822 if err != nil { 823 return nil, err 824 } 825 826 urlPath := url.URL{Path: "snapshots/detail"} 827 url := client.endpoint.ResolveReference(&urlPath).String() 828 829 var req *http.Request 830 if string(argsAsJson) != "{}" { 831 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 832 if err != nil { 833 return nil, err 834 } 835 req.Header.Set("Content-Type", "application/json") 836 } else { 837 req, err = http.NewRequest("GET", url, nil) 838 if err != nil { 839 return nil, err 840 } 841 } 842 843 resp, err := client.handleRequest(req) 844 if err != nil { 845 return nil, err 846 } 847 848 body, err := ioutil.ReadAll(resp.Body) 849 if err != nil { 850 return nil, err 851 } 852 853 switch resp.StatusCode { 854 default: 855 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 856 case 200: 857 break 858 } 859 860 var results GetSnapshotsDetailResults 861 json.Unmarshal(body, &results) 862 863 return &results, nil 864 } 865 866 type GetSnapshotParams struct { 867 868 // 869 // The unique identifier of the tenant or account. 870 TenantId string `json:"-"` 871 872 // SnapshotId is required. 873 // 874 // The unique identifier of an existing snapshot. 875 SnapshotId string `json:"-"` 876 } 877 878 type GetSnapshotResults struct { 879 Snapshot Snapshot `json:"snapshot"` 880 } 881 882 // 883 // Shows information for a specified snapshot. 884 func getSnapshot(client *Client, args GetSnapshotParams) (*GetSnapshotResults, error) { 885 886 argsAsJson, err := json.Marshal(args) 887 if err != nil { 888 return nil, err 889 } 890 891 urlPath := url.URL{Path: fmt.Sprintf("snapshots/%s", args.SnapshotId)} 892 url := client.endpoint.ResolveReference(&urlPath).String() 893 894 var req *http.Request 895 if string(argsAsJson) != "{}" { 896 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 897 if err != nil { 898 return nil, err 899 } 900 req.Header.Set("Content-Type", "application/json") 901 } else { 902 req, err = http.NewRequest("GET", url, nil) 903 if err != nil { 904 return nil, err 905 } 906 } 907 908 resp, err := client.handleRequest(req) 909 if err != nil { 910 return nil, err 911 } 912 913 body, err := ioutil.ReadAll(resp.Body) 914 if err != nil { 915 return nil, err 916 } 917 918 switch resp.StatusCode { 919 default: 920 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 921 case 200: 922 break 923 } 924 925 var results GetSnapshotResults 926 json.Unmarshal(body, &results) 927 928 return &results, nil 929 } 930 931 type ListVersionsParams struct { 932 } 933 934 type Version struct { 935 ID string `json:"id"` 936 Links []struct { 937 Href string `json:"href"` 938 Rel string `json:"rel"` 939 } `json:"links"` 940 Media_Types []struct { 941 Base string `json:"base"` 942 Type string `json:"type"` 943 } `json:"media-types"` 944 Status string `json:"status"` 945 Updated string `json:"updated"` 946 } 947 948 type ListVersionsResults struct { 949 Versions []Version `json:"versions"` 950 } 951 952 // 953 // Lists information about all Block Storage API versions. 954 func listVersions(client *Client, args ListVersionsParams) (*ListVersionsResults, error) { 955 956 argsAsJson, err := json.Marshal(args) 957 if err != nil { 958 return nil, err 959 } 960 961 urlPath := url.URL{Path: "../.."} 962 url := client.endpoint.ResolveReference(&urlPath).String() 963 964 var req *http.Request 965 if string(argsAsJson) != "{}" { 966 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 967 if err != nil { 968 return nil, err 969 } 970 req.Header.Set("Content-Type", "application/json") 971 } else { 972 req, err = http.NewRequest("GET", url, nil) 973 if err != nil { 974 return nil, err 975 } 976 } 977 978 resp, err := client.handleRequest(req) 979 if err != nil { 980 return nil, err 981 } 982 983 body, err := ioutil.ReadAll(resp.Body) 984 if err != nil { 985 return nil, err 986 } 987 988 switch resp.StatusCode { 989 default: 990 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 991 case 200, 300: 992 break 993 } 994 995 var results ListVersionsResults 996 json.Unmarshal(body, &results) 997 998 return &results, nil 999 } 1000 1001 type VersionDetailsParams struct { 1002 } 1003 1004 type VersionDetailsResults struct { 1005 Version Version `json:"version"` 1006 } 1007 1008 // 1009 // Shows details for Block Storage API v2. 1010 func versionDetails(client *Client, args VersionDetailsParams) (*VersionDetailsResults, error) { 1011 1012 argsAsJson, err := json.Marshal(args) 1013 if err != nil { 1014 return nil, err 1015 } 1016 1017 urlPath := url.URL{Path: ".."} 1018 url := client.endpoint.ResolveReference(&urlPath).String() 1019 1020 var req *http.Request 1021 if string(argsAsJson) != "{}" { 1022 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 1023 if err != nil { 1024 return nil, err 1025 } 1026 req.Header.Set("Content-Type", "application/json") 1027 } else { 1028 req, err = http.NewRequest("GET", url, nil) 1029 if err != nil { 1030 return nil, err 1031 } 1032 } 1033 1034 resp, err := client.handleRequest(req) 1035 if err != nil { 1036 return nil, err 1037 } 1038 1039 body, err := ioutil.ReadAll(resp.Body) 1040 if err != nil { 1041 return nil, err 1042 } 1043 1044 switch resp.StatusCode { 1045 default: 1046 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1047 case 200, 203: 1048 break 1049 } 1050 1051 var results VersionDetailsResults 1052 json.Unmarshal(body, &results) 1053 1054 return &results, nil 1055 } 1056 1057 type CreateVolumeVolumeParams struct { 1058 1059 // To create a volume from an existing volume, specify the ID of the existing volume. If specified, the volume is created with same size of the source volume. 1060 SourceVolid string `json:"source_volid,omitempty"` 1061 1062 // To create a volume from an existing snapshot, specify the ID of the existing volume snapshot. If specified, the volume is created in same availability zone and with same size of the snapshot. 1063 SnapshotId string `json:"snapshot_id,omitempty"` 1064 1065 // The ID of the image from which you want to create the volume. Required to create a bootable volume. 1066 ImageRef string `json:"imageRef,omitempty"` 1067 1068 // The associated volume type. 1069 VolumeType string `json:"volume_type,omitempty"` 1070 1071 // Enables or disables the bootable attribute. You can boot an instance from a bootable volume. 1072 Bootable bool `json:"bootable,omitempty"` 1073 1074 // One or more metadata key and value pairs to associate with the volume. 1075 Metadata interface{} `json:"metadata,omitempty"` 1076 1077 // The availability zone. 1078 AvailabilityZone string `json:"availability_zone,omitempty"` 1079 1080 // The volume description. 1081 Description string `json:"description,omitempty"` 1082 1083 // Size is required. 1084 // The size of the volume, in GBs. 1085 Size int `json:"size"` 1086 1087 // The volume name. 1088 Name string `json:"name,omitempty"` 1089 } 1090 1091 type CreateVolumeParams struct { 1092 1093 // Volume is required. 1094 1095 Volume CreateVolumeVolumeParams `json:"volume"` 1096 1097 // 1098 // The unique identifier of the tenant or account. 1099 TenantId string `json:"-"` 1100 } 1101 1102 type CreateVolumeResults struct { 1103 Volume Volume `json:"volume"` 1104 } 1105 1106 // 1107 // Creates a volume. 1108 // To create a bootable volume, include the image ID and set the bootable flag to true in the request body. 1109 // Preconditions 1110 // 1111 // The user must have enough volume storage quota remaining to create a volume of size requested. : 1112 // Asynchronous Postconditions 1113 // 1114 // With correct permissions, you can see the volume status as available through API calls. 1115 // With correct access, you can see the created volume in the storage system that OpenStack Block Storage manages. : 1116 // Troubleshooting 1117 // 1118 // If volume status remains creating or shows another error status, the request failed. Ensure you meet the preconditions then investigate the storage backend. 1119 // Volume is not created in the storage system which OpenStack Block Storage manages. 1120 // The storage node needs enough free storage space to match the specified size of the volume creation request. : 1121 func createVolume(client *Client, args CreateVolumeParams) (*CreateVolumeResults, error) { 1122 1123 argsAsJson, err := json.Marshal(args) 1124 if err != nil { 1125 return nil, err 1126 } 1127 1128 urlPath := url.URL{Path: "volumes"} 1129 url := client.endpoint.ResolveReference(&urlPath).String() 1130 1131 var req *http.Request 1132 if string(argsAsJson) != "{}" { 1133 req, err = http.NewRequest("POST", url, bytes.NewBuffer(argsAsJson)) 1134 if err != nil { 1135 return nil, err 1136 } 1137 req.Header.Set("Content-Type", "application/json") 1138 } else { 1139 req, err = http.NewRequest("POST", url, nil) 1140 if err != nil { 1141 return nil, err 1142 } 1143 } 1144 1145 resp, err := client.handleRequest(req) 1146 if err != nil { 1147 return nil, err 1148 } 1149 1150 body, err := ioutil.ReadAll(resp.Body) 1151 if err != nil { 1152 return nil, err 1153 } 1154 1155 switch resp.StatusCode { 1156 default: 1157 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1158 case 200, 202: 1159 break 1160 } 1161 1162 var results CreateVolumeResults 1163 json.Unmarshal(body, &results) 1164 1165 return &results, nil 1166 } 1167 1168 type GetVolumesSimpleParams struct { 1169 1170 // 1171 // The unique identifier of the tenant or account. 1172 TenantId string `json:"-"` 1173 } 1174 1175 type GetVolumesSimpleResults struct { 1176 Volumes []Volume `json:"volumes"` 1177 } 1178 1179 // 1180 // Lists summary information for all Block Storage volumes that the tenant who submits the request can access. 1181 func getVolumesSimple(client *Client, args GetVolumesSimpleParams) (*GetVolumesSimpleResults, error) { 1182 1183 argsAsJson, err := json.Marshal(args) 1184 if err != nil { 1185 return nil, err 1186 } 1187 1188 urlPath := url.URL{Path: "volumes"} 1189 url := client.endpoint.ResolveReference(&urlPath).String() 1190 1191 var req *http.Request 1192 if string(argsAsJson) != "{}" { 1193 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 1194 if err != nil { 1195 return nil, err 1196 } 1197 req.Header.Set("Content-Type", "application/json") 1198 } else { 1199 req, err = http.NewRequest("GET", url, nil) 1200 if err != nil { 1201 return nil, err 1202 } 1203 } 1204 1205 resp, err := client.handleRequest(req) 1206 if err != nil { 1207 return nil, err 1208 } 1209 1210 body, err := ioutil.ReadAll(resp.Body) 1211 if err != nil { 1212 return nil, err 1213 } 1214 1215 switch resp.StatusCode { 1216 default: 1217 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1218 case 200: 1219 break 1220 } 1221 1222 var results GetVolumesSimpleResults 1223 json.Unmarshal(body, &results) 1224 1225 return &results, nil 1226 } 1227 1228 type GetVolumeTypeParams struct { 1229 1230 // 1231 // The unique identifier of the tenant or account. 1232 TenantId string `json:"-"` 1233 1234 // VolumeTypeId is required. 1235 // 1236 // The unique identifier for an existing volume type. 1237 VolumeTypeId string `json:"-"` 1238 } 1239 1240 type GetVolumeTypeResults struct { 1241 VolumeType VolumeType `json:"volume_type"` 1242 } 1243 1244 // 1245 // Shows information about a specified volume type. 1246 func getVolumeType(client *Client, args GetVolumeTypeParams) (*GetVolumeTypeResults, error) { 1247 1248 argsAsJson, err := json.Marshal(args) 1249 if err != nil { 1250 return nil, err 1251 } 1252 1253 urlPath := url.URL{Path: fmt.Sprintf("types/%s", args.VolumeTypeId)} 1254 url := client.endpoint.ResolveReference(&urlPath).String() 1255 1256 var req *http.Request 1257 if string(argsAsJson) != "{}" { 1258 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 1259 if err != nil { 1260 return nil, err 1261 } 1262 req.Header.Set("Content-Type", "application/json") 1263 } else { 1264 req, err = http.NewRequest("GET", url, nil) 1265 if err != nil { 1266 return nil, err 1267 } 1268 } 1269 1270 resp, err := client.handleRequest(req) 1271 if err != nil { 1272 return nil, err 1273 } 1274 1275 body, err := ioutil.ReadAll(resp.Body) 1276 if err != nil { 1277 return nil, err 1278 } 1279 1280 switch resp.StatusCode { 1281 default: 1282 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1283 case 200: 1284 break 1285 } 1286 1287 var results GetVolumeTypeResults 1288 json.Unmarshal(body, &results) 1289 1290 return &results, nil 1291 } 1292 1293 type DeleteSnapshotParams struct { 1294 1295 // 1296 // The unique identifier of the tenant or account. 1297 TenantId string `json:"-"` 1298 1299 // SnapshotId is required. 1300 // 1301 // The unique identifier of an existing snapshot. 1302 SnapshotId string `json:"-"` 1303 } 1304 1305 type DeleteSnapshotResults struct { 1306 } 1307 1308 // 1309 // Deletes a specified snapshot. 1310 func deleteSnapshot(client *Client, args DeleteSnapshotParams) (*DeleteSnapshotResults, error) { 1311 1312 argsAsJson, err := json.Marshal(args) 1313 if err != nil { 1314 return nil, err 1315 } 1316 1317 urlPath := url.URL{Path: fmt.Sprintf("snapshots/%s", args.SnapshotId)} 1318 url := client.endpoint.ResolveReference(&urlPath).String() 1319 1320 var req *http.Request 1321 if string(argsAsJson) != "{}" { 1322 req, err = http.NewRequest("DELETE", url, bytes.NewBuffer(argsAsJson)) 1323 if err != nil { 1324 return nil, err 1325 } 1326 req.Header.Set("Content-Type", "application/json") 1327 } else { 1328 req, err = http.NewRequest("DELETE", url, nil) 1329 if err != nil { 1330 return nil, err 1331 } 1332 } 1333 1334 resp, err := client.handleRequest(req) 1335 if err != nil { 1336 return nil, err 1337 } 1338 1339 body, err := ioutil.ReadAll(resp.Body) 1340 if err != nil { 1341 return nil, err 1342 } 1343 1344 switch resp.StatusCode { 1345 default: 1346 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1347 case 202: 1348 break 1349 } 1350 1351 var results DeleteSnapshotResults 1352 json.Unmarshal(body, &results) 1353 1354 return &results, nil 1355 } 1356 1357 type ListExtensionsCinderV2Params struct { 1358 } 1359 1360 type Extension struct { 1361 Alias string `json:"alias"` 1362 Description string `json:"description"` 1363 Links []interface{} `json:"links"` 1364 Name string `json:"name"` 1365 Namespace string `json:"namespace"` 1366 Updated string `json:"updated"` 1367 } 1368 1369 type ListExtensionsCinderV2Results struct { 1370 Extensions []Extension `json:"extensions"` 1371 } 1372 1373 // 1374 // Lists Block Storage API extensions. 1375 func listExtensionsCinderV2(client *Client, args ListExtensionsCinderV2Params) (*ListExtensionsCinderV2Results, error) { 1376 1377 argsAsJson, err := json.Marshal(args) 1378 if err != nil { 1379 return nil, err 1380 } 1381 1382 urlPath := url.URL{Path: ".."} 1383 url := client.endpoint.ResolveReference(&urlPath).String() 1384 1385 var req *http.Request 1386 if string(argsAsJson) != "{}" { 1387 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 1388 if err != nil { 1389 return nil, err 1390 } 1391 req.Header.Set("Content-Type", "application/json") 1392 } else { 1393 req, err = http.NewRequest("GET", url, nil) 1394 if err != nil { 1395 return nil, err 1396 } 1397 } 1398 1399 resp, err := client.handleRequest(req) 1400 if err != nil { 1401 return nil, err 1402 } 1403 1404 body, err := ioutil.ReadAll(resp.Body) 1405 if err != nil { 1406 return nil, err 1407 } 1408 1409 switch resp.StatusCode { 1410 default: 1411 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1412 case 200, 300: 1413 break 1414 } 1415 1416 var results ListExtensionsCinderV2Results 1417 json.Unmarshal(body, &results) 1418 1419 return &results, nil 1420 } 1421 1422 type GetVolumeTypesParams struct { 1423 1424 // 1425 // The unique identifier of the tenant or account. 1426 TenantId string `json:"-"` 1427 } 1428 1429 type GetVolumeTypesResults struct { 1430 VolumeTypes []VolumeType `json:"volume_types"` 1431 } 1432 1433 // 1434 // Lists volume types. 1435 func getVolumeTypes(client *Client, args GetVolumeTypesParams) (*GetVolumeTypesResults, error) { 1436 1437 argsAsJson, err := json.Marshal(args) 1438 if err != nil { 1439 return nil, err 1440 } 1441 1442 urlPath := url.URL{Path: "types"} 1443 url := client.endpoint.ResolveReference(&urlPath).String() 1444 1445 var req *http.Request 1446 if string(argsAsJson) != "{}" { 1447 req, err = http.NewRequest("GET", url, bytes.NewBuffer(argsAsJson)) 1448 if err != nil { 1449 return nil, err 1450 } 1451 req.Header.Set("Content-Type", "application/json") 1452 } else { 1453 req, err = http.NewRequest("GET", url, nil) 1454 if err != nil { 1455 return nil, err 1456 } 1457 } 1458 1459 resp, err := client.handleRequest(req) 1460 if err != nil { 1461 return nil, err 1462 } 1463 1464 body, err := ioutil.ReadAll(resp.Body) 1465 if err != nil { 1466 return nil, err 1467 } 1468 1469 switch resp.StatusCode { 1470 default: 1471 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1472 case 200: 1473 break 1474 } 1475 1476 var results GetVolumeTypesResults 1477 json.Unmarshal(body, &results) 1478 1479 return &results, nil 1480 } 1481 1482 type DeleteVolumeTypeParams struct { 1483 1484 // 1485 // The unique identifier of the tenant or account. 1486 TenantId string `json:"-"` 1487 1488 // VolumeTypeId is required. 1489 // 1490 // The unique identifier for an existing volume type. 1491 VolumeTypeId string `json:"-"` 1492 } 1493 1494 type DeleteVolumeTypeResults struct { 1495 } 1496 1497 // 1498 // Deletes a specified volume type. 1499 func deleteVolumeType(client *Client, args DeleteVolumeTypeParams) (*DeleteVolumeTypeResults, error) { 1500 1501 argsAsJson, err := json.Marshal(args) 1502 if err != nil { 1503 return nil, err 1504 } 1505 1506 urlPath := url.URL{Path: fmt.Sprintf("types/%s", args.VolumeTypeId)} 1507 url := client.endpoint.ResolveReference(&urlPath).String() 1508 1509 var req *http.Request 1510 if string(argsAsJson) != "{}" { 1511 req, err = http.NewRequest("DELETE", url, bytes.NewBuffer(argsAsJson)) 1512 if err != nil { 1513 return nil, err 1514 } 1515 req.Header.Set("Content-Type", "application/json") 1516 } else { 1517 req, err = http.NewRequest("DELETE", url, nil) 1518 if err != nil { 1519 return nil, err 1520 } 1521 } 1522 1523 resp, err := client.handleRequest(req) 1524 if err != nil { 1525 return nil, err 1526 } 1527 1528 body, err := ioutil.ReadAll(resp.Body) 1529 if err != nil { 1530 return nil, err 1531 } 1532 1533 switch resp.StatusCode { 1534 default: 1535 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1536 case 202: 1537 break 1538 } 1539 1540 var results DeleteVolumeTypeResults 1541 json.Unmarshal(body, &results) 1542 1543 return &results, nil 1544 } 1545 1546 type UpdateSnapshotMetadataMetadataParams struct { 1547 1548 // Key is required. 1549 1550 Key string `json:"key"` 1551 } 1552 1553 type UpdateSnapshotMetadataParams struct { 1554 1555 // Metadata is required. 1556 // One or more metadata key and value pairs to set or unset for the snapshot. To unset a metadata key value, specify only the key name. To set a metadata key value, specify the key and value pair. The Block Storage server does not respect case-sensitive key names. For example, if you specify both "key": "v1" and "KEY": "V1", the server sets and returns only the KEY key and value pair. 1557 Metadata UpdateSnapshotMetadataMetadataParams `json:"metadata"` 1558 1559 // 1560 // The unique identifier of the tenant or account. 1561 TenantId string `json:"-"` 1562 1563 // SnapshotId is required. 1564 // 1565 // The unique identifier of an existing snapshot. 1566 SnapshotId string `json:"-"` 1567 } 1568 1569 type UpdateSnapshotMetadataResults struct { 1570 Metadata struct { 1571 Key string `json:"key"` 1572 } `json:"metadata"` 1573 } 1574 1575 // 1576 // Updates the metadata for a specified snapshot. 1577 func updateSnapshotMetadata(client *Client, args UpdateSnapshotMetadataParams) (*UpdateSnapshotMetadataResults, error) { 1578 1579 argsAsJson, err := json.Marshal(args) 1580 if err != nil { 1581 return nil, err 1582 } 1583 1584 urlPath := url.URL{Path: fmt.Sprintf("snapshots/%s/metadata", args.SnapshotId)} 1585 url := client.endpoint.ResolveReference(&urlPath).String() 1586 1587 var req *http.Request 1588 if string(argsAsJson) != "{}" { 1589 req, err = http.NewRequest("PUT", url, bytes.NewBuffer(argsAsJson)) 1590 if err != nil { 1591 return nil, err 1592 } 1593 req.Header.Set("Content-Type", "application/json") 1594 } else { 1595 req, err = http.NewRequest("PUT", url, nil) 1596 if err != nil { 1597 return nil, err 1598 } 1599 } 1600 1601 resp, err := client.handleRequest(req) 1602 if err != nil { 1603 return nil, err 1604 } 1605 1606 body, err := ioutil.ReadAll(resp.Body) 1607 if err != nil { 1608 return nil, err 1609 } 1610 1611 switch resp.StatusCode { 1612 default: 1613 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1614 case 200: 1615 break 1616 } 1617 1618 var results UpdateSnapshotMetadataResults 1619 json.Unmarshal(body, &results) 1620 1621 return &results, nil 1622 } 1623 1624 type UpdateVolumeMetadataParams struct { 1625 // Key-value pairs to set in the volume metadata. 1626 Metadata map[string]string `json:"metadata"` 1627 } 1628 1629 // Updates the metadata for a specified volume. 1630 func updateVolumeMetadata(client *Client, volumeId string, args *UpdateVolumeMetadataParams) (*UpdateVolumeMetadataParams, error) { 1631 argsAsJson, err := json.Marshal(args) 1632 if err != nil { 1633 return nil, err 1634 } 1635 1636 urlPath := url.URL{Path: fmt.Sprintf("volumes/%s/metadata", volumeId)} 1637 url := client.endpoint.ResolveReference(&urlPath).String() 1638 // Contrary to what the documentation says, using POST here means 1639 // that we can update a single key. Using PUT will always 1640 // overwrite the entire metadata, throwing away keys it they 1641 // aren't in the request. 1642 // https://developer.openstack.org/api-ref/block-storage/v3/?expanded=update-a-volume-s-metadata-detail#update-a-volume-s-metadata 1643 req, err := http.NewRequest("POST", url, bytes.NewBuffer(argsAsJson)) 1644 if err != nil { 1645 return nil, err 1646 } 1647 req.Header.Set("Content-Type", "application/json") 1648 1649 resp, err := client.handleRequest(req) 1650 if err != nil { 1651 return nil, err 1652 } 1653 1654 body, err := ioutil.ReadAll(resp.Body) 1655 if err != nil { 1656 return nil, err 1657 } 1658 1659 switch resp.StatusCode { 1660 default: 1661 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1662 case 200: 1663 break 1664 } 1665 1666 var results UpdateVolumeMetadataParams 1667 json.Unmarshal(body, &results) 1668 1669 return &results, nil 1670 } 1671 1672 // GetAvailabilityZonesResults holds the result of getting availability zones. 1673 type GetAvailabilityZonesResults struct { 1674 AvailabilityZoneInfo []AvailabilityZone 1675 } 1676 1677 // AvailabilityZone identifies an availability zone, and describes its state. 1678 type AvailabilityZone struct { 1679 Name string `json:"zoneName"` 1680 State AvailabilityZoneState `json:"zoneState"` 1681 } 1682 1683 // AvailabilityZoneState describes an availability zone's state. 1684 type AvailabilityZoneState struct { 1685 Available bool 1686 } 1687 1688 // 1689 // Lists volume availability zones. 1690 func listAvailabilityZones(client *Client) (*GetAvailabilityZonesResults, error) { 1691 1692 urlPath := url.URL{Path: "os-availability-zone"} 1693 url := client.endpoint.ResolveReference(&urlPath).String() 1694 1695 req, err := http.NewRequest("GET", url, nil) 1696 if err != nil { 1697 return nil, err 1698 } 1699 1700 resp, err := client.handleRequest(req) 1701 if err != nil { 1702 return nil, err 1703 } 1704 1705 body, err := ioutil.ReadAll(resp.Body) 1706 if err != nil { 1707 return nil, err 1708 } 1709 1710 switch resp.StatusCode { 1711 default: 1712 return nil, fmt.Errorf("invalid status (%d): %s", resp.StatusCode, body) 1713 case 400, 404: 1714 return nil, gooseerrors.NewNotImplementedf( 1715 err, nil, "the server does not support availability zones for volumes", 1716 ) 1717 case 200: 1718 break 1719 } 1720 1721 var results GetAvailabilityZonesResults 1722 json.Unmarshal(body, &results) 1723 1724 return &results, nil 1725 }