diff --git a/internal/cmd/server/list.go b/internal/cmd/server/list.go index 1ecc9587..e8804cdb 100644 --- a/internal/cmd/server/list.go +++ b/internal/cmd/server/list.go @@ -3,14 +3,17 @@ package server import ( "context" "fmt" + "slices" "strconv" "strings" "time" humanize "github.com/dustin/go-humanize" + "github.com/spf13/cobra" "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" @@ -18,17 +21,45 @@ 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", 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") + _ = cmd.RegisterFlagCompletionFunc("status", cmpl.SuggestCandidates(serverStatusStrings...)) + }, + + 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 { + if slices.Contains(serverStatusStrings, status) { + opts.Status = append(opts.Status, hcloud.ServerStatus(status)) + } else { + return nil, fmt.Errorf("invalid status: %s", status) + } + } + } servers, err := client.Server().AllWithOpts(ctx, opts) var resources []interface{} 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