Skip to content

Commit

Permalink
Merge pull request digitalocean#101 from digitalocean/asb/feature/resize
Browse files Browse the repository at this point in the history
Add support for resizing volumes.
  • Loading branch information
andrewsomething authored Jul 17, 2016
2 parents e03ac28 + f2d6127 commit 25f12cd
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 1 deletion.
65 changes: 64 additions & 1 deletion storage_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import "fmt"
type StorageActionsService interface {
Attach(volumeID string, dropletID int) (*Action, *Response, error)
Detach(volumeID string) (*Action, *Response, error)
Get(volumeID string, actionID int) (*Action, *Response, error)
List(volumeID string, opt *ListOptions) ([]Action, *Response, error)
Resize(volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error)
}

// StorageActionsServiceOp handles communication with the floating IPs
// StorageActionsServiceOp handles communication with the storage volumes
// action related methods of the DigitalOcean API.
type StorageActionsServiceOp struct {
client *Client
Expand Down Expand Up @@ -39,6 +42,33 @@ func (s *StorageActionsServiceOp) Detach(volumeID string) (*Action, *Response, e
return s.doAction(volumeID, request)
}

// Get an action for a particular storage volume by id.
func (s *StorageActionsServiceOp) Get(volumeID string, actionID int) (*Action, *Response, error) {
path := fmt.Sprintf("%s/%d", storageAllocationActionPath(volumeID), actionID)
return s.get(path)
}

// List the actions for a particular storage volume.
func (s *StorageActionsServiceOp) List(volumeID string, opt *ListOptions) ([]Action, *Response, error) {
path := storageAllocationActionPath(volumeID)
path, err := addOptions(path, opt)
if err != nil {
return nil, nil, err
}

return s.list(path)
}

// Resize a storage volume.
func (s *StorageActionsServiceOp) Resize(volumeID string, sizeGigabytes int, regionSlug string) (*Action, *Response, error) {
request := &ActionRequest{
"type": "resize",
"size_gigabytes": sizeGigabytes,
"region": regionSlug,
}
return s.doAction(volumeID, request)
}

func (s *StorageActionsServiceOp) doAction(volumeID string, request *ActionRequest) (*Action, *Response, error) {
path := storageAllocationActionPath(volumeID)

Expand All @@ -56,6 +86,39 @@ func (s *StorageActionsServiceOp) doAction(volumeID string, request *ActionReque
return &root.Event, resp, err
}

func (s *StorageActionsServiceOp) get(path string) (*Action, *Response, error) {
req, err := s.client.NewRequest("GET", path, nil)
if err != nil {
return nil, nil, err
}

root := new(actionRoot)
resp, err := s.client.Do(req, root)
if err != nil {
return nil, resp, err
}

return &root.Event, resp, err
}

func (s *StorageActionsServiceOp) list(path string) ([]Action, *Response, error) {
req, err := s.client.NewRequest("GET", path, nil)
if err != nil {
return nil, nil, err
}

root := new(actionsRoot)
resp, err := s.client.Do(req, root)
if err != nil {
return nil, resp, err
}
if l := root.Links; l != nil {
resp.Links = l
}

return root.Actions, resp, err
}

func storageAllocationActionPath(volumeID string) string {
return fmt.Sprintf("%s/%s/actions", storageAllocPath, volumeID)
}
74 changes: 74 additions & 0 deletions storage_actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,77 @@ func TestStoragesActions_Detach(t *testing.T) {
t.Errorf("StoragesActions.Detach returned error: %v", err)
}
}

func TestStorageActions_Get(t *testing.T) {
setup()
defer teardown()
volumeID := "98d414c6-295e-4e3a-ac58-eb9456c1e1d1"

mux.HandleFunc("/v2/volumes/"+volumeID+"/actions/456", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`)
})

action, _, err := client.StorageActions.Get(volumeID, 456)
if err != nil {
t.Errorf("StorageActions.Get returned error: %v", err)
}

expected := &Action{Status: "in-progress"}
if !reflect.DeepEqual(action, expected) {
t.Errorf("StorageActions.Get returned %+v, expected %+v", action, expected)
}
}

func TestStorageActions_List(t *testing.T) {
setup()
defer teardown()
volumeID := "98d414c6-295e-4e3a-ac58-eb9456c1e1d1"

mux.HandleFunc("/v2/volumes/"+volumeID+"/actions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprintf(w, `{"actions":[{"status":"in-progress"}]}`)
})

actions, _, err := client.StorageActions.List(volumeID, nil)
if err != nil {
t.Errorf("StorageActions.List returned error: %v", err)
}

expected := []Action{Action{Status: "in-progress"}}
if !reflect.DeepEqual(actions, expected) {
t.Errorf("StorageActions.List returned %+v, expected %+v", actions, expected)
}
}

func TestStoragesActions_Resize(t *testing.T) {
setup()
defer teardown()
volumeID := "98d414c6-295e-4e3a-ac58-eb9456c1e1d1"

resizeRequest := &ActionRequest{
"type": "resize",
"size_gigabytes": float64(500),
"region": "nyc1",
}

mux.HandleFunc("/v2/volumes/"+volumeID+"/actions", func(w http.ResponseWriter, r *http.Request) {
v := new(ActionRequest)
err := json.NewDecoder(r.Body).Decode(v)
if err != nil {
t.Fatalf("decode json: %v", err)
}

testMethod(t, r, "POST")
if !reflect.DeepEqual(v, resizeRequest) {
t.Errorf("want=%#v", resizeRequest)
t.Errorf("got=%#v", v)
}
fmt.Fprintf(w, `{"action":{"status":"in-progress"}}`)
})

_, _, err := client.StorageActions.Resize(volumeID, 500, "nyc1")
if err != nil {
t.Errorf("StoragesActions.Resize returned error: %v", err)
}
}

0 comments on commit 25f12cd

Please sign in to comment.