From 857c88c87d9b736e9645ad48c8923abb3b877477 Mon Sep 17 00:00:00 2001 From: pauhull Date: Tue, 12 Dec 2023 12:08:15 +0100 Subject: [PATCH 1/3] feat(server): allow to filter list by server status --- internal/cmd/server/list.go | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/internal/cmd/server/list.go b/internal/cmd/server/list.go index 59d169fb..29644212 100644 --- a/internal/cmd/server/list.go +++ b/internal/cmd/server/list.go @@ -8,6 +8,7 @@ import ( "time" humanize "github.com/dustin/go-humanize" + "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/hetznercloud/cli/internal/cmd/base" @@ -24,11 +25,35 @@ var ListCmd = base.ListCmd{ DefaultColumns: []string{"id", "name", "status", "ipv4", "ipv6", "private_net", "datacenter", "age"}, - Fetch: func(ctx context.Context, client hcapi2.Client, _ *pflag.FlagSet, listOpts hcloud.ListOpts, sorts []string) ([]interface{}, error) { + AdditionalFlags: func(cmd *cobra.Command) { + cmd.Flags().StringSlice("status", nil, "Only servers with one of these statuses are displayed") + }, + + Fetch: func(ctx context.Context, client hcapi2.Client, flags *pflag.FlagSet, listOpts hcloud.ListOpts, sorts []string) ([]interface{}, error) { + statuses, _ := flags.GetStringSlice("status") + opts := hcloud.ServerListOpts{ListOpts: listOpts} if len(sorts) > 0 { opts.Sort = sorts } + if len(statuses) > 0 { + for _, status := range statuses { + switch status { + case string(hcloud.ServerStatusInitializing), + string(hcloud.ServerStatusOff), + string(hcloud.ServerStatusRunning), + string(hcloud.ServerStatusStarting), + string(hcloud.ServerStatusStopping), + string(hcloud.ServerStatusMigrating), + string(hcloud.ServerStatusRebuilding), + string(hcloud.ServerStatusDeleting), + string(hcloud.ServerStatusUnknown): + opts.Status = append(opts.Status, hcloud.ServerStatus(status)) + default: + return nil, fmt.Errorf("invalid status: %s", status) + } + } + } servers, err := client.Server().AllWithOpts(ctx, opts) var resources []interface{} From f88a7b198f9e51602cde373c694ec3168c9252c3 Mon Sep 17 00:00:00 2001 From: pauhull Date: Tue, 12 Dec 2023 12:12:20 +0100 Subject: [PATCH 2/3] Add test --- internal/cmd/server/list_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/cmd/server/list_test.go b/internal/cmd/server/list_test.go index 98f5d369..19aa89e3 100644 --- a/internal/cmd/server/list_test.go +++ b/internal/cmd/server/list_test.go @@ -28,6 +28,7 @@ func TestList(t *testing.T) { hcloud.ServerListOpts{ ListOpts: hcloud.ListOpts{PerPage: 50}, Sort: []string{"id:asc"}, + Status: []hcloud.ServerStatus{hcloud.ServerStatusRunning}, }, ). Return([]*hcloud.Server{ @@ -45,7 +46,7 @@ func TestList(t *testing.T) { }, }, nil) - out, _, err := fx.Run(cmd, []string{}) + out, _, err := fx.Run(cmd, []string{"--status", "running"}) expOut := `ID NAME STATUS IPV4 IPV6 PRIVATE NET DATACENTER AGE 123 test running 192.168.2.1 - - fsn1-dc14 20s From d863461168c8e5452cc4101e5744660e31660882 Mon Sep 17 00:00:00 2001 From: pauhull Date: Tue, 12 Dec 2023 12:15:51 +0100 Subject: [PATCH 3/3] Add auto completion suggestions --- internal/cmd/server/list.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/internal/cmd/server/list.go b/internal/cmd/server/list.go index 29644212..f040978f 100644 --- a/internal/cmd/server/list.go +++ b/internal/cmd/server/list.go @@ -3,6 +3,7 @@ package server import ( "context" "fmt" + "slices" "strconv" "strings" "time" @@ -12,6 +13,7 @@ import ( "github.com/spf13/pflag" "github.com/hetznercloud/cli/internal/cmd/base" + "github.com/hetznercloud/cli/internal/cmd/cmpl" "github.com/hetznercloud/cli/internal/cmd/output" "github.com/hetznercloud/cli/internal/cmd/util" "github.com/hetznercloud/cli/internal/hcapi2" @@ -19,6 +21,18 @@ import ( "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) +var serverStatusStrings = []string{ + string(hcloud.ServerStatusInitializing), + string(hcloud.ServerStatusOff), + string(hcloud.ServerStatusRunning), + string(hcloud.ServerStatusStarting), + string(hcloud.ServerStatusStopping), + string(hcloud.ServerStatusMigrating), + string(hcloud.ServerStatusRebuilding), + string(hcloud.ServerStatusDeleting), + string(hcloud.ServerStatusUnknown), +} + var ListCmd = base.ListCmd{ ResourceNamePlural: "Servers", JSONKeyGetByName: "servers", @@ -27,6 +41,7 @@ var ListCmd = base.ListCmd{ AdditionalFlags: func(cmd *cobra.Command) { cmd.Flags().StringSlice("status", nil, "Only servers with one of these statuses are displayed") + _ = cmd.RegisterFlagCompletionFunc("status", cmpl.SuggestCandidates(serverStatusStrings...)) }, Fetch: func(ctx context.Context, client hcapi2.Client, flags *pflag.FlagSet, listOpts hcloud.ListOpts, sorts []string) ([]interface{}, error) { @@ -38,18 +53,9 @@ var ListCmd = base.ListCmd{ } if len(statuses) > 0 { for _, status := range statuses { - switch status { - case string(hcloud.ServerStatusInitializing), - string(hcloud.ServerStatusOff), - string(hcloud.ServerStatusRunning), - string(hcloud.ServerStatusStarting), - string(hcloud.ServerStatusStopping), - string(hcloud.ServerStatusMigrating), - string(hcloud.ServerStatusRebuilding), - string(hcloud.ServerStatusDeleting), - string(hcloud.ServerStatusUnknown): + if slices.Contains(serverStatusStrings, status) { opts.Status = append(opts.Status, hcloud.ServerStatus(status)) - default: + } else { return nil, fmt.Errorf("invalid status: %s", status) } }