From 595953f5ab5357c9f508196af829b95e704d2fe2 Mon Sep 17 00:00:00 2001 From: Dan Norris Date: Sun, 12 Feb 2017 15:32:47 -0800 Subject: [PATCH] Add ability to query for a storage volume by name This allows you to get a volume by name and region which corresponds to calling: ``` /v2/volumes?name=$NAME®ion=$REGION ``` --- storage.go | 27 ++++++++++++++++++----- storage_test.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/storage.go b/storage.go index e3a9606d..4ca5a74d 100644 --- a/storage.go +++ b/storage.go @@ -15,7 +15,7 @@ const ( // endpoints of the Digital Ocean API. // See: https://developers.digitalocean.com/documentation/v2#storage type StorageService interface { - ListVolumes(*ListOptions) ([]Volume, *Response, error) + ListVolumes(*ListVolumeParams) ([]Volume, *Response, error) GetVolume(string) (*Volume, *Response, error) CreateVolume(*VolumeCreateRequest) (*Volume, *Response, error) DeleteVolume(string) (*Response, error) @@ -31,6 +31,13 @@ type StorageServiceOp struct { client *Client } +// ListVolumeParams stores the options you can set for a ListVolumeCall +type ListVolumeParams struct { + Region string `json:"region"` + Name string `json:"name"` + ListOptions *ListOptions `json:"list_options,omitempty"` +} + var _ StorageService = &StorageServiceOp{} // Volume represents a Digital Ocean block store volume. @@ -68,10 +75,20 @@ type VolumeCreateRequest struct { } // ListVolumes lists all storage volumes. -func (svc *StorageServiceOp) ListVolumes(opt *ListOptions) ([]Volume, *Response, error) { - path, err := addOptions(storageAllocPath, opt) - if err != nil { - return nil, nil, err +func (svc *StorageServiceOp) ListVolumes(params *ListVolumeParams) ([]Volume, *Response, error) { + path := storageAllocPath + if params != nil { + if params.Region != "" && params.Name != "" { + path = fmt.Sprintf("%s?name=%s®ion=%s", path, params.Name, params.Region) + } + + if params.ListOptions != nil { + var err error + path, err = addOptions(path, params.ListOptions) + if err != nil { + return nil, nil, err + } + } } req, err := svc.client.NewRequest("GET", path, nil) diff --git a/storage_test.go b/storage_test.go index 44175518..9c7b8ed5 100644 --- a/storage_test.go +++ b/storage_test.go @@ -127,6 +127,63 @@ func TestStorageVolumes_Get(t *testing.T) { } } +func TestStorageVolumes_ListVolumesByName(t *testing.T) { + setup() + defer teardown() + + jBlob := + `{ + "volumes": [ + { + "region": {"slug": "nyc3"}, + "id": "80d414c6-295e-4e3a-ac58-eb9456c1e1d1", + "name": "myvolume", + "description": "my description", + "size_gigabytes": 100, + "droplet_ids": [10], + "created_at": "2002-10-02T15:00:00.05Z" + } + ], + "links": {}, + "meta": { + "total": 1 + } + }` + + expected := []Volume{ + { + Region: &Region{Slug: "nyc3"}, + ID: "80d414c6-295e-4e3a-ac58-eb9456c1e1d1", + Name: "myvolume", + Description: "my description", + SizeGigaBytes: 100, + DropletIDs: []int{10}, + CreatedAt: time.Date(2002, 10, 02, 15, 00, 00, 50000000, time.UTC), + }, + } + + mux.HandleFunc("/v2/volumes", func(w http.ResponseWriter, r *http.Request) { + if r.URL.Query().Get("name") != "myvolume" || r.URL.Query().Get("region") != "nyc3" { + t.Errorf("Storage.GetVolumeByName did not request the correct name or region") + } + testMethod(t, r, "GET") + fmt.Fprint(w, jBlob) + }) + + options := &ListVolumeParams{ + Name: "myvolume", + Region: "nyc3", + } + volumes, _, err := client.Storage.ListVolumes(options) + if err != nil { + t.Errorf("Storage.GetVolumeByName returned error: %v", err) + } + + if !reflect.DeepEqual(volumes, expected) { + t.Errorf("Storage.GetVolumeByName returned %+v, expected %+v", volumes, expected) + } +} + func TestStorageVolumes_Create(t *testing.T) { setup() defer teardown()