From c609adcac3a283139b1d88d377151b4924b99331 Mon Sep 17 00:00:00 2001 From: Toni Kangas Date: Wed, 3 Apr 2024 22:59:37 +0300 Subject: [PATCH] feat(objectstorage): add support for managed object storage names --- CHANGELOG.md | 5 +++ internal/commands/objectstorage/delete.go | 5 +++ internal/commands/objectstorage/list.go | 2 ++ internal/commands/objectstorage/show.go | 5 +++ internal/completion/objectstorage.go | 29 ++++++++++++++++ internal/resolver/objectstorage.go | 42 +++++++++++++++++++++++ 6 files changed, 88 insertions(+) create mode 100644 internal/completion/objectstorage.go create mode 100644 internal/resolver/objectstorage.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 32b650151..744b84c74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add managed object storage name to `show` and `list` command outputs. +- Add completions for managed object storages and allow using managed object storage name (in addition to its UUID) as a positional argument. + ## [3.6.0] - 2024-03-07 ### Added diff --git a/internal/commands/objectstorage/delete.go b/internal/commands/objectstorage/delete.go index 294d4620e..07ff94566 100644 --- a/internal/commands/objectstorage/delete.go +++ b/internal/commands/objectstorage/delete.go @@ -4,8 +4,10 @@ import ( "fmt" "github.com/UpCloudLtd/upcloud-cli/v3/internal/commands" + "github.com/UpCloudLtd/upcloud-cli/v3/internal/completion" "github.com/UpCloudLtd/upcloud-cli/v3/internal/config" "github.com/UpCloudLtd/upcloud-cli/v3/internal/output" + "github.com/UpCloudLtd/upcloud-cli/v3/internal/resolver" "github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request" "github.com/spf13/pflag" @@ -24,6 +26,9 @@ func DeleteCommand() commands.Command { type deleteCommand struct { *commands.BaseCommand + resolver.CachingObjectStorage + completion.ObjectStorage + deleteUsers config.OptionalBoolean deletePolicies config.OptionalBoolean } diff --git a/internal/commands/objectstorage/list.go b/internal/commands/objectstorage/list.go index f79f0c414..cf18c52d4 100644 --- a/internal/commands/objectstorage/list.go +++ b/internal/commands/objectstorage/list.go @@ -32,6 +32,7 @@ func (c *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Ou for _, objectstorage := range objectstorages { rows = append(rows, output.TableRow{ objectstorage.UUID, + objectstorage.Name, objectstorage.Region, objectstorage.ConfiguredStatus, objectstorage.OperationalState, @@ -43,6 +44,7 @@ func (c *listCommand) ExecuteWithoutArguments(exec commands.Executor) (output.Ou Output: output.Table{ Columns: []output.TableColumn{ {Key: "uuid", Header: "UUID", Colour: ui.DefaultUUUIDColours}, + {Key: "name", Header: "Name"}, {Key: "region", Header: "Region"}, {Key: "configured_status", Header: "Configured status", Format: format.ObjectStorageConfiguredStatus}, {Key: "operational_state", Header: "Operational state", Format: format.ObjectStorageOperationalState}, diff --git a/internal/commands/objectstorage/show.go b/internal/commands/objectstorage/show.go index fd2f97ea6..f7a78f34c 100644 --- a/internal/commands/objectstorage/show.go +++ b/internal/commands/objectstorage/show.go @@ -2,9 +2,11 @@ package objectstorage import ( "github.com/UpCloudLtd/upcloud-cli/v3/internal/commands" + "github.com/UpCloudLtd/upcloud-cli/v3/internal/completion" "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/resolver" "github.com/UpCloudLtd/upcloud-cli/v3/internal/ui" "github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request" ) @@ -22,6 +24,8 @@ func ShowCommand() commands.Command { type showCommand struct { *commands.BaseCommand + resolver.CachingObjectStorage + completion.ObjectStorage } // Execute implements commands.MultipleArgumentCommand @@ -119,6 +123,7 @@ func (c *showCommand) Execute(exec commands.Executor, uuid string) (output.Outpu Title: "Overview:", Rows: []output.DetailRow{ {Title: "UUID:", Value: objectStorage.UUID, Colour: ui.DefaultUUUIDColours}, + {Title: "Name:", Value: objectStorage.Name}, {Title: "Region:", Value: objectStorage.Region}, {Title: "Configured status:", Value: objectStorage.ConfiguredStatus, Format: format.ObjectStorageConfiguredStatus}, {Title: "Operational state:", Value: objectStorage.OperationalState, Format: format.ObjectStorageOperationalState}, diff --git a/internal/completion/objectstorage.go b/internal/completion/objectstorage.go new file mode 100644 index 000000000..ab52985b9 --- /dev/null +++ b/internal/completion/objectstorage.go @@ -0,0 +1,29 @@ +package completion + +import ( + "context" + + "github.com/UpCloudLtd/upcloud-cli/v3/internal/service" + "github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request" + "github.com/spf13/cobra" +) + +// ObjectStorage implements argument completion for gateways, by uuid or name. +type ObjectStorage struct{} + +// make sure ObjectStorage implements the interface +var _ Provider = ObjectStorage{} + +// CompleteArgument implements completion.Provider +func (s ObjectStorage) CompleteArgument(ctx context.Context, svc service.AllServices, toComplete string) ([]string, cobra.ShellCompDirective) { + objectstorages, err := svc.GetManagedObjectStorages(ctx, &request.GetManagedObjectStoragesRequest{}) + if err != nil { + return None(toComplete) + } + var vals []string + for _, objsto := range objectstorages { + vals = append(vals, objsto.UUID, objsto.Name) + } + + return MatchStringPrefix(vals, toComplete, true), cobra.ShellCompDirectiveNoFileComp +} diff --git a/internal/resolver/objectstorage.go b/internal/resolver/objectstorage.go new file mode 100644 index 000000000..817628c3e --- /dev/null +++ b/internal/resolver/objectstorage.go @@ -0,0 +1,42 @@ +package resolver + +import ( + "context" + + internal "github.com/UpCloudLtd/upcloud-cli/v3/internal/service" + "github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request" +) + +// CachingObjectStorage implements resolver for ObjectStorages, caching the results +type CachingObjectStorage struct{} + +// make sure we implement the ResolutionProvider interface +var _ ResolutionProvider = CachingObjectStorage{} + +// Get implements ResolutionProvider.Get +func (s CachingObjectStorage) Get(ctx context.Context, svc internal.AllServices) (Resolver, error) { + objectstorages, err := svc.GetManagedObjectStorages(ctx, &request.GetManagedObjectStoragesRequest{}) + if err != nil { + return nil, err + } + return func(arg string) (uuid string, err error) { + rv := "" + for _, objsto := range objectstorages { + if MatchArgWithWhitespace(arg, objsto.Name) || objsto.UUID == arg { + if rv != "" { + return "", AmbiguousResolutionError(arg) + } + rv = objsto.UUID + } + } + if rv != "" { + return rv, nil + } + return "", NotFoundError(arg) + }, nil +} + +// PositionalArgumentHelp implements resolver.ResolutionProvider +func (s CachingObjectStorage) PositionalArgumentHelp() string { + return helpUUIDTitle +}