Skip to content

Commit

Permalink
add support for retrieving IOPS tiers (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
0x4c6565 committed Sep 8, 2023
1 parent 1ed70ac commit 3d11caa
Show file tree
Hide file tree
Showing 10 changed files with 414 additions and 3 deletions.
1 change: 1 addition & 0 deletions cmd/ecloud/ecloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func ECloudRootCmd(f factory.ClientFactory, fs afero.Fs) *cobra.Command {
cmd.AddCommand(ecloudHostSpecRootCmd(f))
cmd.AddCommand(ecloudImageRootCmd(f))
cmd.AddCommand(ecloudInstanceRootCmd(f))
cmd.AddCommand(ecloudIOPSRootCmd(f))
cmd.AddCommand(ecloudIPAddressRootCmd(f))
cmd.AddCommand(ecloudLoadBalancerRootCmd(f))
cmd.AddCommand(ecloudLoadBalancerSpecRootCmd(f))
Expand Down
3 changes: 3 additions & 0 deletions cmd/ecloud/ecloud_availabilityzone.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ func ecloudAvailabilityZoneRootCmd(f factory.ClientFactory) *cobra.Command {
cmd.AddCommand(ecloudAvailabilityZoneListCmd(f))
cmd.AddCommand(ecloudAvailabilityZoneShowCmd(f))

// Child root commands
cmd.AddCommand(ecloudAvailabilityZoneIOPSRootCmd(f))

return cmd
}

Expand Down
64 changes: 64 additions & 0 deletions cmd/ecloud/ecloud_availabilityzone_iops.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package ecloud

import (
"errors"
"fmt"

"github.com/ans-group/cli/internal/pkg/factory"
"github.com/ans-group/cli/internal/pkg/helper"
"github.com/ans-group/cli/internal/pkg/output"
"github.com/ans-group/sdk-go/pkg/service/ecloud"
"github.com/spf13/cobra"
)

func ecloudAvailabilityZoneIOPSRootCmd(f factory.ClientFactory) *cobra.Command {
cmd := &cobra.Command{
Use: "iops",
Short: "sub-commands relating to availability zone IOPS tiers",
Aliases: []string{
"az",
},
}

// Child commands
cmd.AddCommand(ecloudAvailabilityZoneIOPSTierListCmd(f))

return cmd
}

func ecloudAvailabilityZoneIOPSTierListCmd(f factory.ClientFactory) *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "Lists availability zone IOPS tiers",
Long: "This command lists availability zone IOPS tiers",
Example: "ans ecloud availabilityzone iops list",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("Missing availability zone")
}

return nil
},
RunE: ecloudCobraRunEFunc(f, ecloudAvailabilityZoneIOPSTierList),
}

cmd.Flags().String("name", "", "IOPS name for filtering")

return cmd
}

func ecloudAvailabilityZoneIOPSTierList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error {
params, err := helper.GetAPIRequestParametersFromFlags(cmd,
helper.NewStringFilterFlagOption("name", "name"),
)
if err != nil {
return err
}

zones, err := service.GetAvailabilityZoneIOPSTiers(args[0], params)
if err != nil {
return fmt.Errorf("Error retrieving availability zones: %s", err)
}

return output.CommandOutput(cmd, OutputECloudIOPSTierProvider(zones))
}
68 changes: 68 additions & 0 deletions cmd/ecloud/ecloud_availabilityzone_iops_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package ecloud

import (
"errors"
"testing"

"github.com/ans-group/cli/internal/pkg/clierrors"
"github.com/ans-group/cli/test/mocks"
"github.com/ans-group/sdk-go/pkg/service/ecloud"
gomock "github.com/golang/mock/gomock"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)

func Test_ecloudAvailabilityZoneIOPSTiersListCmd_Args(t *testing.T) {
t.Run("ValidArgs_NoError", func(t *testing.T) {
err := ecloudAvailabilityZoneIOPSTierListCmd(nil).Args(nil, []string{"fwp-abcdef12"})

assert.Nil(t, err)
})

t.Run("InvalidArgs_Error", func(t *testing.T) {
err := ecloudAvailabilityZoneIOPSTierListCmd(nil).Args(nil, []string{})

assert.NotNil(t, err)
assert.Equal(t, "Missing availability zone", err.Error())
})
}

func Test_ecloudAvailabilityZoneIOPSTiersList(t *testing.T) {
t.Run("DefaultRetrieve", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)

service.EXPECT().GetAvailabilityZoneIOPSTiers("fwp-abcdef12", gomock.Any()).Return([]ecloud.IOPSTier{}, nil).Times(1)

ecloudAvailabilityZoneIOPSTierList(service, &cobra.Command{}, []string{"fwp-abcdef12"})
})

t.Run("MalformedFlag_ReturnsError", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)
cmd := &cobra.Command{}
cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "")

err := ecloudAvailabilityZoneIOPSTierList(service, cmd, []string{})

assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err)
})

t.Run("GetAvailabilityZonesError_ReturnsError", func(t *testing.T) {

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)

service.EXPECT().GetAvailabilityZoneIOPSTiers("fwp-abcdef12", gomock.Any()).Return([]ecloud.IOPSTier{}, errors.New("test error")).Times(1)

err := ecloudAvailabilityZoneIOPSTierList(service, &cobra.Command{}, []string{"fwp-abcdef12"})

assert.Equal(t, "Error retrieving availability zone ports: test error", err.Error())
})
}
87 changes: 87 additions & 0 deletions cmd/ecloud/ecloud_iops.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package ecloud

import (
"errors"
"fmt"

"github.com/ans-group/cli/internal/pkg/factory"
"github.com/ans-group/cli/internal/pkg/helper"
"github.com/ans-group/cli/internal/pkg/output"
"github.com/ans-group/sdk-go/pkg/service/ecloud"
"github.com/spf13/cobra"
)

func ecloudIOPSRootCmd(f factory.ClientFactory) *cobra.Command {
cmd := &cobra.Command{
Use: "iops",
Short: "sub-commands relating to IOPS tiers",
}

// Child commands
cmd.AddCommand(ecloudIOPSTierListCmd(f))
cmd.AddCommand(ecloudIOPSTierShowCmd(f))

return cmd
}

func ecloudIOPSTierListCmd(f factory.ClientFactory) *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "Lists IOPS tiers",
Long: "This command lists IOPS tiers",
Example: "ans ecloud iops list",
RunE: ecloudCobraRunEFunc(f, ecloudIOPSTierList),
}

cmd.Flags().String("name", "", "IOPS name for filtering")

return cmd
}

func ecloudIOPSTierList(service ecloud.ECloudService, cmd *cobra.Command, args []string) error {
params, err := helper.GetAPIRequestParametersFromFlags(cmd,
helper.NewStringFilterFlagOption("name", "name"),
)
if err != nil {
return err
}

tiers, err := service.GetIOPSTiers(params)
if err != nil {
return fmt.Errorf("Error retrieving IOPS tiers: %s", err)
}

return output.CommandOutput(cmd, OutputECloudIOPSTierProvider(tiers))
}

func ecloudIOPSTierShowCmd(f factory.ClientFactory) *cobra.Command {
return &cobra.Command{
Use: "show <iops: id>...",
Short: "Shows an IOPS tier",
Long: "This command shows one or more IOPS tiers",
Example: "ans ecloud IOPS show iops-abcdef12",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("Missing IOPS tier")
}

return nil
},
RunE: ecloudCobraRunEFunc(f, ecloudIOPSTierShow),
}
}

func ecloudIOPSTierShow(service ecloud.ECloudService, cmd *cobra.Command, args []string) error {
var tiersList []ecloud.IOPSTier
for _, arg := range args {
tiers, err := service.GetIOPSTier(arg)
if err != nil {
output.OutputWithErrorLevelf("Error retrieving IOPS tier [%s]: %s", arg, err)
continue
}

tiersList = append(tiersList, tiers)
}

return output.CommandOutput(cmd, OutputECloudIOPSTierProvider(tiersList))
}
109 changes: 109 additions & 0 deletions cmd/ecloud/ecloud_iops_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package ecloud

import (
"errors"
"testing"

"github.com/ans-group/cli/internal/pkg/clierrors"
"github.com/ans-group/cli/test/mocks"
"github.com/ans-group/cli/test/test_output"
"github.com/ans-group/sdk-go/pkg/service/ecloud"
gomock "github.com/golang/mock/gomock"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)

func Test_ecloudIOPSTierList(t *testing.T) {
t.Run("DefaultRetrieve", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)

service.EXPECT().GetIOPSTiers(gomock.Any()).Return([]ecloud.IOPSTier{}, nil).Times(1)

ecloudIOPSTierList(service, &cobra.Command{}, []string{})
})

t.Run("MalformedFlag_ReturnsError", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)
cmd := &cobra.Command{}
cmd.Flags().StringArray("filter", []string{"invalidfilter"}, "")

err := ecloudIOPSTierList(service, cmd, []string{})

assert.IsType(t, &clierrors.ErrInvalidFlagValue{}, err)
})

t.Run("GetIOPSTiersError_ReturnsError", func(t *testing.T) {

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)

service.EXPECT().GetIOPSTiers(gomock.Any()).Return([]ecloud.IOPSTier{}, errors.New("test error")).Times(1)

err := ecloudIOPSTierList(service, &cobra.Command{}, []string{})

assert.Equal(t, "Error retrieving IOPS tiers: test error", err.Error())
})
}

func Test_ecloudIOPSTierShowCmd_Args(t *testing.T) {
t.Run("ValidArgs_NoError", func(t *testing.T) {
err := ecloudIOPSTierShowCmd(nil).Args(nil, []string{"iops-abcdef12"})

assert.Nil(t, err)
})

t.Run("InvalidArgs_Error", func(t *testing.T) {
err := ecloudIOPSTierShowCmd(nil).Args(nil, []string{})

assert.NotNil(t, err)
assert.Equal(t, "Missing IOPS", err.Error())
})
}

func Test_ecloudIOPSTierShow(t *testing.T) {
t.Run("SingleIOPS", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)

service.EXPECT().GetIOPSTier("iops-abcdef12").Return(ecloud.IOPSTier{}, nil).Times(1)

ecloudIOPSTierShow(service, &cobra.Command{}, []string{"iops-abcdef12"})
})

t.Run("MultipleIOPSs", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)

gomock.InOrder(
service.EXPECT().GetIOPSTier("iops-abcdef12").Return(ecloud.IOPSTier{}, nil),
service.EXPECT().GetIOPSTier("iops-abcdef23").Return(ecloud.IOPSTier{}, nil),
)

ecloudIOPSTierShow(service, &cobra.Command{}, []string{"iops-abcdef12", "iops-abcdef23"})
})

t.Run("GetIOPSError_OutputsError", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

service := mocks.NewMockECloudService(mockCtrl)

service.EXPECT().GetIOPSTier("iops-abcdef12").Return(ecloud.IOPSTier{}, errors.New("test error"))

test_output.AssertErrorOutput(t, "Error retrieving IOPS tier [iops-abcdef12]: test error\n", func() {
ecloudIOPSTierShow(service, &cobra.Command{}, []string{"iops-abcdef12"})
})
})
}
4 changes: 4 additions & 0 deletions cmd/ecloud/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,3 +479,7 @@ func OutputECloudResourceTiersProvider(tiers []ecloud.ResourceTier) output.Outpu
func OutputECloudNATOverloadRulesProvider(rules []ecloud.NATOverloadRule) output.OutputHandlerDataProvider {
return output.NewSerializedOutputHandlerDataProvider(rules).WithDefaultFields([]string{"id", "name", "network_id", "subnet", "floating_ip_id", "action"})
}

func OutputECloudIOPSTierProvider(tiers []ecloud.IOPSTier) output.OutputHandlerDataProvider {
return output.NewSerializedOutputHandlerDataProvider(tiers).WithDefaultFields([]string{"id", "name", "level"})
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/ans-group/cli
go 1.18

require (
github.com/ans-group/sdk-go v1.16.5
github.com/ans-group/sdk-go v1.16.6
github.com/blang/semver v3.5.1+incompatible
github.com/golang/mock v1.6.0
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ans-group/go-durationstring v1.2.0 h1:UJIuQATkp0t1rBvZsHRwki33YHV9E+Ulro+3NbMB7MM=
github.com/ans-group/go-durationstring v1.2.0/go.mod h1:QGF9Mdpq9058QXaut8r55QWu6lcHX6i/GvF1PZVkV6o=
github.com/ans-group/sdk-go v1.16.5 h1:FoBcdhM209iS2EfjVfq98GrDJNlJRu2mygZ0Xi8Mb3Q=
github.com/ans-group/sdk-go v1.16.5/go.mod h1:p1vrXBxHPvMOGlS4sFUSgeLeKAl9vIe/lJ6UaExe49A=
github.com/ans-group/sdk-go v1.16.6 h1:WPdKk8Ze8SDh2afStBWmaLdufPhLxYgGdEKThIboD24=
github.com/ans-group/sdk-go v1.16.6/go.mod h1:p1vrXBxHPvMOGlS4sFUSgeLeKAl9vIe/lJ6UaExe49A=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
Expand Down
Loading

0 comments on commit 3d11caa

Please sign in to comment.