Skip to content

Commit

Permalink
added new volume and volume-action actions
Browse files Browse the repository at this point in the history
fixed imports

added copyright headers

vendoring godo update

changes for digitalocean#171
  • Loading branch information
xmudrii committed Dec 23, 2016
1 parent 658f28e commit d8576e6
Show file tree
Hide file tree
Showing 9 changed files with 294 additions and 15 deletions.
2 changes: 2 additions & 0 deletions args.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,6 @@ const (

// ArgResourceType is the resource type for snapshot.
ArgResourceType = "resource"
// ArgSnapshotDesc is the description for volume snapshot.
ArgSnapshotDesc = "snapshot-desc"
)
65 changes: 65 additions & 0 deletions commands/volume_actions.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
/*
Copyright 2016 The Doctl Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package commands

import (
Expand Down Expand Up @@ -51,6 +64,16 @@ func VolumeAction() *Command {
CmdBuilder(cmd, RunVolumeDetach, "detach <volume-id>", "detach a volume", Writer,
aliasOpt("d"))

CmdBuilder(cmd, RunVolumeDetachByDropletID, "detach-by-droplet-id <volume-id> <droplet-id>", "detach a volume by droplet ID", Writer,
aliasOpt("dd"))

cmdRunVolumeResize := CmdBuilder(cmd, RunVolumeResize, "resize <volume-id>", "resize a volume", Writer,
aliasOpt("r"))
AddIntFlag(cmdRunVolumeResize, doctl.ArgSizeSlug, "", 0, "New size",
requiredOpt())
AddStringFlag(cmdRunVolumeResize, doctl.ArgRegionSlug, "", "", "Volume region",
requiredOpt())

return cmd

}
Expand Down Expand Up @@ -85,3 +108,45 @@ func RunVolumeDetach(c *CmdConfig) error {
}
return performVolumeAction(c, fn)
}

// RunVolumeDetachByDropletID detaches a volume by droplet ID
func RunVolumeDetachByDropletID(c *CmdConfig) error {
fn := func(das do.VolumeActionsService) (*do.Action, error) {
if len(c.Args) != 2 {
return nil, doctl.NewMissingArgsErr(c.NS)
}
volumeID := c.Args[0]
dropletID, err := strconv.Atoi(c.Args[1])
if err != nil {
return nil, err
}
a, err := das.DetachByDropletID(volumeID, dropletID)
return a, err
}
return performVolumeAction(c, fn)
}

// RunVolumeResize resizes a volume
func RunVolumeResize(c *CmdConfig) error {
fn := func(das do.VolumeActionsService) (*do.Action, error) {
if len(c.Args) != 1 {
return nil, doctl.NewMissingArgsErr(c.NS)
}

volumeID := c.Args[0]

size, err := c.Doit.GetInt(c.NS, doctl.ArgSizeSlug)
if err != nil {
return nil, err
}

region, err := c.Doit.GetString(c.NS, doctl.ArgRegionSlug)
if err != nil {
return nil, err
}

a, err := das.Resize(volumeID, size, region)
return a, err
}
return performVolumeAction(c, fn)
}
40 changes: 39 additions & 1 deletion commands/volume_actions_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
/*
Copyright 2016 The Doctl Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package commands

import (
"fmt"
"testing"

"github.com/digitalocean/doctl"
"github.com/stretchr/testify/assert"
)

func TestVolumeActionCommand(t *testing.T) {
cmd := VolumeAction()
assert.NotNil(t, cmd)
assertCommandNames(t, cmd, "attach", "detach")
assertCommandNames(t, cmd, "attach", "detach", "detach-by-droplet-id", "resize")
}

func TestVolumeActionsAttach(t *testing.T) {
Expand All @@ -33,3 +47,27 @@ func TestVolumeActionsDetach(t *testing.T) {
assert.NoError(t, err)
})
}

func TestVolumeDetachByDropletID(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
tm.volumeActions.On("DetachByDropletID", testVolume.ID, testDroplet.ID).Return(&testAction, nil)
config.Args = append(config.Args, testVolume.ID)
config.Args = append(config.Args, fmt.Sprintf("%d", testDroplet.ID))

err := RunVolumeDetachByDropletID(config)
assert.NoError(t, err)
})
}

func TestVolumeResize(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
tm.volumeActions.On("Resize", testVolume.ID, 150, "dev0").Return(&testAction, nil)
config.Args = append(config.Args, testVolume.ID)

config.Doit.Set(config.NS, doctl.ArgSizeSlug, 150)
config.Doit.Set(config.NS, doctl.ArgRegionSlug, "dev0")

err := RunVolumeResize(config)
assert.NoError(t, err)
})
}
51 changes: 51 additions & 0 deletions commands/volumes.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
/*
Copyright 2016 The Doctl Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package commands

import (
Expand Down Expand Up @@ -39,6 +52,11 @@ func Volume() *Command {
CmdBuilder(cmd, RunVolumeGet, "get [ID]", "get a volume", Writer, aliasOpt("g"),
displayerType(&volume{}))

cmdRunVolumeSnapshot := CmdBuilder(cmd, RunVolumeSnapshot, "snapshot [volume-id]", "create a volume snapshot", Writer,
aliasOpt("s"), displayerType(&volume{}))
AddStringFlag(cmdRunVolumeSnapshot, doctl.ArgSnapshotName, "", "Snapshot name", requiredOpt())
AddStringFlag(cmdRunVolumeSnapshot, doctl.ArgSnapshotDesc, "", "Snapshot description")

return cmd

}
Expand Down Expand Up @@ -174,3 +192,36 @@ func RunVolumeGet(c *CmdConfig) error {
item := &volume{volumes: []do.Volume{*d}}
return c.Display(item)
}

// RunVolumeSnapshot creates a snapshot of a volume
func RunVolumeSnapshot(c *CmdConfig) error {
var err error
if len(c.Args) == 0 {
return doctl.NewMissingArgsErr(c.NS)
}

al := c.Volumes()
id := c.Args[0]

name, err := c.Doit.GetString(c.NS, doctl.ArgSnapshotName)
if err != nil {
return err
}

desc, err := c.Doit.GetString(c.NS, doctl.ArgSnapshotDesc)
if err != nil {
return nil
}

req := &godo.SnapshotCreateRequest{
VolumeID: id,
Name: name,
Description: desc,
}

if _, err := al.CreateSnapshot(req); err != nil {
return err
}

return nil
}
33 changes: 32 additions & 1 deletion commands/volumes_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
/*
Copyright 2016 The Doctl Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package commands

import (
Expand Down Expand Up @@ -28,7 +41,7 @@ var (
func TestVolumeCommand(t *testing.T) {
cmd := Volume()
assert.NotNil(t, cmd)
assertCommandNames(t, cmd, "create", "delete", "get", "list")
assertCommandNames(t, cmd, "create", "delete", "get", "list", "snapshot")
}

func TestVolumesGet(t *testing.T) {
Expand Down Expand Up @@ -104,3 +117,21 @@ func TestVolumesDelete(t *testing.T) {
assert.NoError(t, err)
})
}

func TestVolumesSnapshot(t *testing.T) {
withTestClient(t, func(config *CmdConfig, tm *tcMocks) {
tcr := godo.SnapshotCreateRequest{
VolumeID: testVolume.ID,
Name: "test-volume-snapshot",
Description: "test description",
}
tm.volumes.On("CreateSnapshot", &tcr).Return(nil, nil)

config.Args = append(config.Args, testVolume.ID)
config.Doit.Set(config.NS, doctl.ArgSnapshotName, "test-volume-snapshot")
config.Doit.Set(config.NS, doctl.ArgSnapshotDesc, "test description")

err := RunVolumeSnapshot(config)
assert.NoError(t, err)
})
}
54 changes: 50 additions & 4 deletions do/mocks/VolumeActionsService.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package mocks

import "github.com/digitalocean/doctl/do"
import "github.com/stretchr/testify/mock"

// Generated: please do not edit by hand
import do "github.com/digitalocean/doctl/do"
import mock "github.com/stretchr/testify/mock"

// VolumeActionsService is an autogenerated mock type for the VolumeActionsService type
type VolumeActionsService struct {
Expand Down Expand Up @@ -55,3 +53,51 @@ func (_m *VolumeActionsService) Detach(_a0 string) (*do.Action, error) {

return r0, r1
}

// DetachByDropletID provides a mock function with given fields: _a0, _a1
func (_m *VolumeActionsService) DetachByDropletID(_a0 string, _a1 int) (*do.Action, error) {
ret := _m.Called(_a0, _a1)

var r0 *do.Action
if rf, ok := ret.Get(0).(func(string, int) *do.Action); ok {
r0 = rf(_a0, _a1)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*do.Action)
}
}

var r1 error
if rf, ok := ret.Get(1).(func(string, int) error); ok {
r1 = rf(_a0, _a1)
} else {
r1 = ret.Error(1)
}

return r0, r1
}

// Resize provides a mock function with given fields: _a0, _a1, _a2
func (_m *VolumeActionsService) Resize(_a0 string, _a1 int, _a2 string) (*do.Action, error) {
ret := _m.Called(_a0, _a1, _a2)

var r0 *do.Action
if rf, ok := ret.Get(0).(func(string, int, string) *do.Action); ok {
r0 = rf(_a0, _a1, _a2)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*do.Action)
}
}

var r1 error
if rf, ok := ret.Get(1).(func(string, int, string) error); ok {
r1 = rf(_a0, _a1, _a2)
} else {
r1 = ret.Error(1)
}

return r0, r1
}

var _ do.VolumeActionsService = (*VolumeActionsService)(nil)
34 changes: 28 additions & 6 deletions do/mocks/VolumesService.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
package mocks

import "github.com/digitalocean/doctl/do"
import "github.com/stretchr/testify/mock"

import "github.com/digitalocean/godo"

// Generated: please do not edit by hand
import do "github.com/digitalocean/doctl/do"
import godo "github.com/digitalocean/godo"
import mock "github.com/stretchr/testify/mock"

// VolumesService is an autogenerated mock type for the VolumesService type
type VolumesService struct {
mock.Mock
}

// CreateSnapshot provides a mock function with given fields: _a0
func (_m *VolumesService) CreateSnapshot(_a0 *godo.SnapshotCreateRequest) (*do.Snapshot, error) {
ret := _m.Called(_a0)

var r0 *do.Snapshot
if rf, ok := ret.Get(0).(func(*godo.SnapshotCreateRequest) *do.Snapshot); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*do.Snapshot)
}
}

var r1 error
if rf, ok := ret.Get(1).(func(*godo.SnapshotCreateRequest) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}

return r0, r1
}

// CreateVolume provides a mock function with given fields: _a0
func (_m *VolumesService) CreateVolume(_a0 *godo.VolumeCreateRequest) (*do.Volume, error) {
ret := _m.Called(_a0)
Expand Down Expand Up @@ -94,3 +114,5 @@ func (_m *VolumesService) List() ([]do.Volume, error) {

return r0, r1
}

var _ do.VolumesService = (*VolumesService)(nil)
Loading

0 comments on commit d8576e6

Please sign in to comment.