diff --git a/command/node_status.go b/command/node_status.go index f7f7b587802..9538e90622b 100644 --- a/command/node_status.go +++ b/command/node_status.go @@ -13,6 +13,7 @@ import ( "time" humanize "github.com/dustin/go-humanize" + "github.com/hashicorp/go-set/v3" "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/api/contexts" "github.com/hashicorp/nomad/helper/pointer" @@ -129,8 +130,12 @@ func (c *NodeStatusCommand) AutocompleteFlags() complete.Flags { } func (c *NodeStatusCommand) AutocompleteArgs() complete.Predictor { + return nodePredictor(c.Client, nil) +} + +func nodePredictor(factory ApiClientFactory, filter *set.Set[string]) complete.Predictor { return complete.PredictFunc(func(a complete.Args) []string { - client, err := c.Meta.Client() + client, err := factory() if err != nil { return nil } diff --git a/command/plugin_status.go b/command/plugin_status.go index 02c61c65a9a..92dbdc7f26b 100644 --- a/command/plugin_status.go +++ b/command/plugin_status.go @@ -58,21 +58,10 @@ func (c *PluginStatusCommand) Synopsis() string { return "Display status information about a plugin" } -// predictVolumeType is also used in volume_status -var predictVolumeType = complete.PredictFunc(func(a complete.Args) []string { - types := []string{"csi"} - for _, t := range types { - if strings.Contains(t, a.Last) { - return []string{t} - } - } - return nil -}) - func (c *PluginStatusCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ - "-type": predictVolumeType, + "-type": complete.PredictSet("csi"), "-short": complete.PredictNothing, "-verbose": complete.PredictNothing, "-json": complete.PredictNothing, diff --git a/command/volume_create.go b/command/volume_create.go index f566cfa8f2d..1e3dcbad02a 100644 --- a/command/volume_create.go +++ b/command/volume_create.go @@ -52,7 +52,11 @@ Create Options: } func (c *VolumeCreateCommand) AutocompleteFlags() complete.Flags { - return c.Meta.AutocompleteFlags(FlagSetClient) + return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), + complete.Flags{ + "-detach": complete.PredictNothing, + "-verbose": complete.PredictNothing, + }) } func (c *VolumeCreateCommand) AutocompleteArgs() complete.Predictor { diff --git a/command/volume_delete.go b/command/volume_delete.go index ab8be61104b..678dd181c95 100644 --- a/command/volume_delete.go +++ b/command/volume_delete.go @@ -40,7 +40,7 @@ Delete Options: -secret Secrets to pass to the plugin to delete the snapshot. Accepts multiple - flags in the form -secret key=value + flags in the form -secret key=value. Only available for CSI volumes. -type Type of volume to delete. Must be one of "csi" or "host". Defaults to "csi". @@ -50,7 +50,10 @@ Delete Options: func (c *VolumeDeleteCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), - complete.Flags{}) + complete.Flags{ + "-type": complete.PredictSet("csi", "host"), + "-secret": complete.PredictNothing, + }) } func (c *VolumeDeleteCommand) AutocompleteArgs() complete.Predictor { @@ -66,11 +69,11 @@ func (c *VolumeDeleteCommand) AutocompleteArgs() complete.Predictor { } matches := resp.Matches[contexts.Volumes] - resp, _, err = client.Search().PrefixSearch(a.Last, contexts.Nodes, nil) + resp, _, err = client.Search().PrefixSearch(a.Last, contexts.HostVolumes, nil) if err != nil { return []string{} } - matches = append(matches, resp.Matches[contexts.Nodes]...) + matches = append(matches, resp.Matches[contexts.HostVolumes]...) return matches }) } diff --git a/command/volume_delete_host_test.go b/command/volume_delete_host_test.go index fde8994df33..353063c34cc 100644 --- a/command/volume_delete_host_test.go +++ b/command/volume_delete_host_test.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/ci" "github.com/mitchellh/cli" + "github.com/posener/complete" "github.com/shoenig/test/must" ) @@ -62,8 +63,18 @@ capability { ui.OutputWriter.Reset() + // autocomplete + cmd := &VolumeDeleteCommand{Meta: Meta{Ui: ui, namespace: "*", flagAddress: url}} + prefix := id[:len(id)-5] + cargs := complete.Args{Last: prefix} + predictor := cmd.AutocompleteArgs() + + res := predictor.Predict(cargs) + must.SliceLen(t, 1, res) + must.Eq(t, id, res[0]) + // missing the namespace - cmd := &VolumeDeleteCommand{Meta: Meta{Ui: ui}} + cmd = &VolumeDeleteCommand{Meta: Meta{Ui: ui}} args = []string{"-address", url, "-type", "host", id} code = cmd.Run(args) must.Eq(t, 1, code) @@ -76,4 +87,5 @@ capability { must.Eq(t, 0, code, must.Sprintf("got error: %s", ui.ErrorWriter.String())) out = ui.OutputWriter.String() must.StrContains(t, out, fmt.Sprintf("Successfully deleted volume %q!", id)) + } diff --git a/command/volume_deregister.go b/command/volume_deregister.go index c4c78cfcc2d..60851e66954 100644 --- a/command/volume_deregister.go +++ b/command/volume_deregister.go @@ -53,7 +53,6 @@ func (c *VolumeDeregisterCommand) AutocompleteArgs() complete.Predictor { return nil } - // When multiple volume types are implemented, this search should merge contexts resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Volumes, nil) if err != nil { return []string{} diff --git a/command/volume_status.go b/command/volume_status.go index b6163cca6f4..d599e349e83 100644 --- a/command/volume_status.go +++ b/command/volume_status.go @@ -69,15 +69,13 @@ func (c *VolumeStatusCommand) Synopsis() string { func (c *VolumeStatusCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ - "-type": predictVolumeType, - "-short": complete.PredictNothing, - "-verbose": complete.PredictNothing, - "-json": complete.PredictNothing, - "-t": complete.PredictAnything, - - // TODO(1.10.0): wire-up predictions for nodes and node pools - "-node": complete.PredictNothing, - "-node-pool": complete.PredictNothing, + "-type": complete.PredictSet("csi", "host"), + "-short": complete.PredictNothing, + "-verbose": complete.PredictNothing, + "-json": complete.PredictNothing, + "-t": complete.PredictAnything, + "-node": nodePredictor(c.Client, nil), + "-node-pool": nodePoolPredictor(c.Client, nil), }) } @@ -92,7 +90,14 @@ func (c *VolumeStatusCommand) AutocompleteArgs() complete.Predictor { if err != nil { return []string{} } - return resp.Matches[contexts.Volumes] + matches := resp.Matches[contexts.Volumes] + + resp, _, err = client.Search().PrefixSearch(a.Last, contexts.HostVolumes, nil) + if err != nil { + return []string{} + } + matches = append(matches, resp.Matches[contexts.HostVolumes]...) + return matches }) } diff --git a/command/volume_status_host_test.go b/command/volume_status_host_test.go index 0ec8d930550..c51e931096b 100644 --- a/command/volume_status_host_test.go +++ b/command/volume_status_host_test.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/ci" "github.com/mitchellh/cli" + "github.com/posener/complete" "github.com/shoenig/test/must" ) @@ -141,8 +142,19 @@ capability { ui.OutputWriter.Reset() + // autocomplete + cmd := &VolumeStatusCommand{Meta: Meta{Ui: ui, namespace: "*", flagAddress: url}} + cmd.Meta.namespace = "*" + prefix := id[:len(id)-5] + cargs := complete.Args{Last: prefix} + predictor := cmd.AutocompleteArgs() + + res := predictor.Predict(cargs) + must.SliceLen(t, 1, res) + must.Eq(t, id, res[0]) + // missing the namespace - cmd := &VolumeStatusCommand{Meta: Meta{Ui: ui}} + cmd = &VolumeStatusCommand{Meta: Meta{Ui: ui}} args = []string{"-address", url, "-type", "host", id} code = cmd.Run(args) must.Eq(t, 1, code)