mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
dynamic host volumes: autocomplete for CLI (#24533)
Adds dynamic host volumes to argument autocomplete for the `volume status` and `volume delete` commands. Adds flag autocompletion for those commands plus `volume create`. Ref: https://github.com/hashicorp/nomad/pull/24479
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
}
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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,
|
||||
"-type": complete.PredictSet("csi", "host"),
|
||||
"-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,
|
||||
"-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
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user