Add basic autocompletion (#3223)

* Add basic autocompletion

* Add autocomplete to some common commands

* Autocomplete the generate-root flags

* Add information about autocomplete to the docs
This commit is contained in:
Brian Kassouf 2017-08-24 15:23:40 -07:00 committed by GitHub
parent fe8528e56c
commit 23089dafbc
13 changed files with 240 additions and 7 deletions

View File

@ -36,9 +36,11 @@ func RunCustom(args []string, commands map[string]cli.CommandFactory) int {
}
cli := &cli.CLI{
Args: args,
Commands: commands,
HelpFunc: cli.FilteredHelpFunc(commandsInclude, HelpFunc),
Args: args,
Commands: commands,
Name: "vault",
Autocomplete: true,
HelpFunc: cli.FilteredHelpFunc(commandsInclude, HelpFunc),
}
exitCode, err := cli.Run()

View File

@ -10,6 +10,7 @@ import (
"github.com/hashicorp/vault/helper/kv-builder"
"github.com/hashicorp/vault/meta"
"github.com/mitchellh/mapstructure"
"github.com/posener/complete"
)
// AuditEnableCommand is a Command that mounts a new mount.
@ -127,3 +128,19 @@ Audit Enable Options:
`
return strings.TrimSpace(helpText)
}
func (c *AuditEnableCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictSet(
"file",
"syslog",
"socket",
)
}
func (c *AuditEnableCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-description": complete.PredictNothing,
"-path": complete.PredictNothing,
"-local": complete.PredictNothing,
}
}

View File

@ -15,6 +15,7 @@ import (
"github.com/hashicorp/vault/helper/password"
"github.com/hashicorp/vault/meta"
"github.com/mitchellh/mapstructure"
"github.com/posener/complete"
"github.com/ryanuber/columnize"
)
@ -301,15 +302,22 @@ func (c *AuthCommand) Run(args []string) int {
}
func (c *AuthCommand) listMethods() int {
func (c *AuthCommand) getMethods() (map[string]*api.AuthMount, error) {
client, err := c.Client()
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Error initializing client: %s", err))
return 1
return nil, err
}
auth, err := client.Sys().ListAuth()
if err != nil {
return nil, err
}
return auth, nil
}
func (c *AuthCommand) listMethods() int {
auth, err := c.getMethods()
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Error reading auth table: %s", err))
@ -458,3 +466,35 @@ tokens are created via the API or command line interface (with the
return strings.TrimSpace(help)
}
func (c *AuthCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *AuthCommand) AutocompleteFlags() complete.Flags {
var predictFunc complete.PredictFunc = func(a complete.Args) []string {
auths, err := c.getMethods()
if err != nil {
return []string{}
}
methods := make([]string, 0, len(auths))
for _, auth := range auths {
if strings.HasPrefix(auth.Type, a.Last) {
methods = append(methods, auth.Type)
}
}
return methods
}
return complete.Flags{
"-method": predictFunc,
"-methods": complete.PredictNothing,
"-method-help": complete.PredictNothing,
"-no-verify": complete.PredictNothing,
"-no-store": complete.PredictNothing,
"-token-only": complete.PredictNothing,
"-path": complete.PredictNothing,
}
}

View File

@ -6,6 +6,7 @@ import (
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/meta"
"github.com/posener/complete"
)
// AuthEnableCommand is a Command that enables a new endpoint.
@ -110,3 +111,29 @@ Auth Enable Options:
`
return strings.TrimSpace(helpText)
}
func (c *AuthEnableCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictSet(
"approle",
"cert",
"aws",
"app-id",
"gcp",
"github",
"userpass",
"ldap",
"okta",
"radius",
"plugin",
)
}
func (c *AuthEnableCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-description": complete.PredictNothing,
"-path": complete.PredictNothing,
"-plugin-name": complete.PredictNothing,
"-local": complete.PredictNothing,
}
}

View File

@ -14,9 +14,12 @@ import (
"github.com/ghodss/yaml"
"github.com/hashicorp/vault/api"
"github.com/mitchellh/cli"
"github.com/posener/complete"
"github.com/ryanuber/columnize"
)
var predictFormat complete.Predictor = complete.PredictSet("json", "yaml")
func OutputSecret(ui cli.Ui, format string, secret *api.Secret) int {
return outputWithFormat(ui, format, secret, secret)
}

View File

@ -13,6 +13,7 @@ import (
"github.com/hashicorp/vault/helper/pgpkeys"
"github.com/hashicorp/vault/helper/xor"
"github.com/hashicorp/vault/meta"
"github.com/posener/complete"
)
// GenerateRootCommand is a Command that generates a new root token.
@ -352,3 +353,20 @@ Generate Root Options:
`
return strings.TrimSpace(helpText)
}
func (c *GenerateRootCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *GenerateRootCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-init": complete.PredictNothing,
"-cancel": complete.PredictNothing,
"-status": complete.PredictNothing,
"-decode": complete.PredictNothing,
"-genotp": complete.PredictNothing,
"-otp": complete.PredictNothing,
"-pgp-key": complete.PredictNothing,
"-nonce": complete.PredictNothing,
}
}

View File

@ -12,6 +12,7 @@ import (
"github.com/hashicorp/vault/helper/pgpkeys"
"github.com/hashicorp/vault/meta"
"github.com/hashicorp/vault/physical/consul"
"github.com/posener/complete"
)
// InitCommand is a Command that initializes a new Vault server.
@ -384,3 +385,22 @@ Init Options:
`
return strings.TrimSpace(helpText)
}
func (c *InitCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *InitCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-check": complete.PredictNothing,
"-key-shares": complete.PredictNothing,
"-key-threshold": complete.PredictNothing,
"-pgp-keys": complete.PredictNothing,
"-root-token-pgp-key": complete.PredictNothing,
"-recovery-shares": complete.PredictNothing,
"-recovery-threshold": complete.PredictNothing,
"-recovery-pgp-keys": complete.PredictNothing,
"-auto": complete.PredictNothing,
"-consul-service": complete.PredictNothing,
}
}

View File

@ -6,6 +6,7 @@ import (
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/meta"
"github.com/posener/complete"
)
// MountCommand is a Command that mounts a new mount.
@ -133,3 +134,31 @@ Mount Options:
`
return strings.TrimSpace(helpText)
}
func (c *MountCommand) AutocompleteArgs() complete.Predictor {
// This list does not contain deprecated backends
return complete.PredictSet(
"aws",
"consul",
"pki",
"transit",
"ssh",
"rabbitmq",
"database",
"totp",
"plugin",
)
}
func (c *MountCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-description": complete.PredictNothing,
"-path": complete.PredictNothing,
"-default-lease-ttl": complete.PredictNothing,
"-max-lease-ttl": complete.PredictNothing,
"-force-no-cache": complete.PredictNothing,
"-plugin-name": complete.PredictNothing,
"-local": complete.PredictNothing,
}
}

View File

@ -7,6 +7,7 @@ import (
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/meta"
"github.com/posener/complete"
)
// ReadCommand is a Command that reads data from the Vault.
@ -95,3 +96,14 @@ Read Options:
`
return strings.TrimSpace(helpText)
}
func (c *ReadCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *ReadCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-format": predictFormat,
"-field": complete.PredictNothing,
}
}

View File

@ -10,6 +10,7 @@ import (
"github.com/hashicorp/vault/helper/password"
"github.com/hashicorp/vault/helper/pgpkeys"
"github.com/hashicorp/vault/meta"
"github.com/posener/complete"
)
// RekeyCommand is a Command that rekeys the vault.
@ -418,3 +419,23 @@ Rekey Options:
`
return strings.TrimSpace(helpText)
}
func (c *RekeyCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *RekeyCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-init": complete.PredictNothing,
"-cancel": complete.PredictNothing,
"-status": complete.PredictNothing,
"-retrieve": complete.PredictNothing,
"-delete": complete.PredictNothing,
"-key-shares": complete.PredictNothing,
"-key-threshold": complete.PredictNothing,
"-nonce": complete.PredictNothing,
"-pgp-keys": complete.PredictNothing,
"-backup": complete.PredictNothing,
"-recovery-key": complete.PredictNothing,
}
}

View File

@ -23,6 +23,7 @@ import (
colorable "github.com/mattn/go-colorable"
log "github.com/mgutz/logxi/v1"
testing "github.com/mitchellh/go-testing-interface"
"github.com/posener/complete"
"google.golang.org/grpc/grpclog"
@ -1200,6 +1201,20 @@ General Options:
return strings.TrimSpace(helpText)
}
func (c *ServerCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *ServerCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-config": complete.PredictOr(complete.PredictFiles("*.hcl"), complete.PredictFiles("*.json")),
"-dev": complete.PredictNothing,
"-dev-root-token-id": complete.PredictNothing,
"-dev-listen-address": complete.PredictNothing,
"-log-level": complete.PredictSet("trace", "debug", "info", "warn", "err"),
}
}
// MakeShutdownCh returns a channel that can be used for shutdown
// notifications for commands. This channel will send a message for every
// SIGINT or SIGTERM received.

View File

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/vault/helper/kv-builder"
"github.com/hashicorp/vault/meta"
"github.com/posener/complete"
)
// WriteCommand is a Command that puts data into the Vault.
@ -139,3 +140,15 @@ Write Options:
`
return strings.TrimSpace(helpText)
}
func (c *WriteCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictNothing
}
func (c *WriteCommand) AutocompleteFlags() complete.Flags {
return complete.Flags{
"-force": complete.PredictNothing,
"-format": predictFormat,
"-field": complete.PredictNothing,
}
}

View File

@ -24,3 +24,19 @@ with the `-h` argument.
The help output is very comprehensive, so we defer you to that for documentation.
We've included some guides to the left of common interactions with the
CLI.
## Autocompletion
The `vault` command features opt-in subcommand autocompletion that you can
enable for your shell with `vault -autocomplete-install`. After doing so,
you can invoke a new shell and use the feature.
For example, assume a tab is typed at the end of each prompt line:
```
$ vault au
audit-disable audit-enable audit-list auth auth-disable auth-enable
$ vault s
seal server ssh status step-down
```