Skip to content

Commit

Permalink
feat(objectstorage): delete, list & show commands (#268)
Browse files Browse the repository at this point in the history
  • Loading branch information
villevsv-upcloud authored Nov 15, 2023
1 parent 5b948a0 commit c3b76dd
Show file tree
Hide file tree
Showing 10 changed files with 491 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
- Add `objectstorage` commands (`delete`, `list`, `show`) for Managed object storage management

## [3.1.0] - 2023-11-06

### Added
Expand Down
7 changes: 7 additions & 0 deletions internal/commands/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands/kubernetes/nodegroup"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands/loadbalancer"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands/network"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands/objectstorage"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands/root"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands/router"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands/server"
Expand Down Expand Up @@ -175,6 +176,12 @@ func BuildCommands(rootCmd *cobra.Command, conf *config.Config) {
commands.BuildCommand(servergroup.ModifyCommand(), serverGroupCommand.Cobra(), conf)
commands.BuildCommand(servergroup.ShowCommand(), serverGroupCommand.Cobra(), conf)

// Managed object storage operations
objectStorageCommand := commands.BuildCommand(objectstorage.BaseobjectstorageCommand(), rootCmd, conf)
commands.BuildCommand(objectstorage.DeleteCommand(), objectStorageCommand.Cobra(), conf)
commands.BuildCommand(objectstorage.ListCommand(), objectStorageCommand.Cobra(), conf)
commands.BuildCommand(objectstorage.ShowCommand(), objectStorageCommand.Cobra(), conf)

// Misc
commands.BuildCommand(
&root.VersionCommand{
Expand Down
42 changes: 42 additions & 0 deletions internal/commands/objectstorage/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package objectstorage

import (
"fmt"

"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/output"
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud/request"
)

// DeleteCommand creates the "objectstorage delete" command
func DeleteCommand() commands.Command {
return &deleteCommand{
BaseCommand: commands.New(
"delete",
"Delete a Managed object storage service",
"upctl objectstorage delete 55199a44-4751-4e27-9394-7c7661910be8",
),
}
}

type deleteCommand struct {
*commands.BaseCommand
}

// Execute implements commands.MultipleArgumentCommand
func (c *deleteCommand) Execute(exec commands.Executor, arg string) (output.Output, error) {
svc := exec.All()
msg := fmt.Sprintf("Deleting object storage service %v", arg)
exec.PushProgressStarted(msg)

err := svc.DeleteManagedObjectStorage(exec.Context(), &request.DeleteManagedObjectStorageRequest{
UUID: arg,
})
if err != nil {
return commands.HandleError(exec, msg, err)
}

exec.PushProgressSuccess(msg)

return output.None{}, nil
}
52 changes: 52 additions & 0 deletions internal/commands/objectstorage/delete_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package objectstorage

import (
"testing"

"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/config"
smock "github.com/UpCloudLtd/upcloud-cli/v3/internal/mock"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud/request"
"github.com/gemalto/flume"
"github.com/stretchr/testify/assert"
)

func TestDeleteCommand(t *testing.T) {
targetMethod := "DeleteManagedObjectStorage"

objectstorage := upcloud.ManagedObjectStorage{
UUID: "17fbd082-30b0-11eb-adc1-0242ac120003",
}

for _, test := range []struct {
name string
arg string
error string
req request.DeleteManagedObjectStorageRequest
}{
{
name: "delete with UUID",
arg: objectstorage.UUID,
req: request.DeleteManagedObjectStorageRequest{UUID: objectstorage.UUID},
},
} {
t.Run(test.name, func(t *testing.T) {
mService := smock.Service{}
mService.On(targetMethod, &test.req).Return(nil)

conf := config.New()
c := commands.BuildCommand(DeleteCommand(), nil, conf)

_, err := c.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, &mService, flume.New("test")), test.arg)

if test.error != "" {
assert.EqualError(t, err, test.error)
} else {
assert.NoError(t, err)
mService.AssertNumberOfCalls(t, targetMethod, 1)
}
})
}
}
52 changes: 52 additions & 0 deletions internal/commands/objectstorage/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package objectstorage

import (
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/format"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/output"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/ui"
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud/request"
)

// ListCommand creates the "objectstorage list" command
func ListCommand() commands.Command {
return &listCommand{
BaseCommand: commands.New("list", "List current Managed object storage services", "upctl objectstorage list"),
}
}

type listCommand struct {
*commands.BaseCommand
}

// ExecuteWithoutArguments implements commands.NoArgumentCommand
func (c *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Output, error) {
svc := exec.All()
objectstorages, err := svc.GetManagedObjectStorages(exec.Context(), &request.GetManagedObjectStoragesRequest{})
if err != nil {
return nil, err
}

rows := []output.TableRow{}
for _, objectstorage := range objectstorages {
rows = append(rows, output.TableRow{
objectstorage.UUID,
objectstorage.Region,
objectstorage.ConfiguredStatus,
objectstorage.OperationalState,
})
}

return output.MarshaledWithHumanOutput{
Value: objectstorages,
Output: output.Table{
Columns: []output.TableColumn{
{Key: "uuid", Header: "UUID", Colour: ui.DefaultUUUIDColours},
{Key: "region", Header: "Region"},
{Key: "configured_status", Header: "Configured status", Format: format.ObjectStorageConfiguredStatus},
{Key: "operational_state", Header: "Operational state", Format: format.ObjectStorageOperationalState},
},
Rows: rows,
},
}, nil
}
21 changes: 21 additions & 0 deletions internal/commands/objectstorage/objectstorage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package objectstorage

import (
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
)

// BaseobjectstorageCommand creates the base "objectstorage" command
func BaseobjectstorageCommand() commands.Command {
return &objectstorageCommand{
commands.New("objectstorage", "Manage Managed object storage services"),
}
}

type objectstorageCommand struct {
*commands.BaseCommand
}

// InitCommand implements Command.InitCommand
func (c *objectstorageCommand) InitCommand() {
c.Cobra().Aliases = []string{"object-storage", "objsto"}
}
137 changes: 137 additions & 0 deletions internal/commands/objectstorage/show.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package objectstorage

import (
"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/format"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/labels"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/output"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/ui"
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud/request"
)

// ShowCommand creates the "objectstorage show" command
func ShowCommand() commands.Command {
return &showCommand{
BaseCommand: commands.New(
"show",
"Show Managed object storage service details",
"upctl objectstorage show 55199a44-4751-4e27-9394-7c7661910be8",
),
}
}

type showCommand struct {
*commands.BaseCommand
}

// Execute implements commands.MultipleArgumentCommand
func (c *showCommand) Execute(exec commands.Executor, uuid string) (output.Output, error) {
svc := exec.All()
objectStorage, err := svc.GetManagedObjectStorage(exec.Context(), &request.GetManagedObjectStorageRequest{UUID: uuid})
if err != nil {
return nil, err
}

endpointRows := make([]output.TableRow, 0)
for _, endpoint := range objectStorage.Endpoints {
endpointRows = append(endpointRows, output.TableRow{
endpoint.DomainName,
endpoint.Type,
})
}

endpointColumns := []output.TableColumn{
{Key: "domain_name", Header: "Domain"},
{Key: "type", Header: "Type"},
}

networkRows := make([]output.TableRow, 0)
for _, network := range objectStorage.Networks {
networkUUID := ""
if network.UUID != nil {
networkUUID = *network.UUID
}
networkRows = append(networkRows, output.TableRow{
network.Name,
networkUUID,
network.Type,
network.Family,
})
}

networkColumns := []output.TableColumn{
{Key: "name", Header: "Name"},
{Key: "uuid", Header: "UUID", Colour: ui.DefaultUUUIDColours, Format: format.PossiblyUnknownString},
{Key: "type", Header: "Type"},
{Key: "Family", Header: "Family"},
}

userRows := make([]output.TableRow, 0)
for _, user := range objectStorage.Users {
userRows = append(userRows, output.TableRow{
user.Username,
user.CreatedAt,
user.UpdatedAt,
user.OperationalState,
})
}

userColumns := []output.TableColumn{
{Key: "name", Header: "Username"},
{Key: "created_at", Header: "Created"},
{Key: "updated_at", Header: "Updated"},
{Key: "operational_state", Header: "Updated", Format: format.ObjectStorageUserOperationalState},
}

// For JSON and YAML output, passthrough API response
return output.MarshaledWithHumanOutput{
Value: objectStorage,
Output: output.Combined{
output.CombinedSection{
Contents: output.Details{
Sections: []output.DetailSection{
{
Title: "Overview:",
Rows: []output.DetailRow{
{Title: "UUID:", Value: objectStorage.UUID, Colour: ui.DefaultUUUIDColours},
{Title: "Region:", Value: objectStorage.Region},
{Title: "Configured status:", Value: objectStorage.ConfiguredStatus, Format: format.ObjectStorageConfiguredStatus},
{Title: "Operational state:", Value: objectStorage.OperationalState, Format: format.ObjectStorageOperationalState},
{Title: "Created:", Value: objectStorage.CreatedAt},
{Title: "Updated:", Value: objectStorage.UpdatedAt},
},
},
},
},
},
labels.GetLabelsSectionWithResourceType(objectStorage.Labels, "managed object storage"),
output.CombinedSection{
Key: "endpoints",
Title: "Endpoints:",
Contents: output.Table{
Columns: endpointColumns,
Rows: endpointRows,
EmptyMessage: "No endpoints found for this Managed object storage service.",
},
},
output.CombinedSection{
Key: "networks",
Title: "Networks:",
Contents: output.Table{
Columns: networkColumns,
Rows: networkRows,
EmptyMessage: "No networks found for this Managed object storage service.",
},
},
output.CombinedSection{
Key: "users",
Title: "Users:",
Contents: output.Table{
Columns: userColumns,
Rows: userRows,
EmptyMessage: "No users found for this Managed object storage service.",
},
},
},
}, nil
}
Loading

0 comments on commit c3b76dd

Please sign in to comment.