move gossip keyring command to their own subcommands (#13383)
Move all the gossip keyring and key generation commands under `operator gossip keyring` subcommands to align with the new `operator secure-variables keyring` subcommands. Deprecate the `operator keyring` and `operator keygen` commands.
This commit is contained in:
parent
4a8463595b
commit
4d011d4c53
|
@ -44,7 +44,7 @@ func (c *DeprecatedCommand) Run(args []string) int {
|
|||
func (c *DeprecatedCommand) warn() {
|
||||
c.Ui.Warn(wrapAtLength(fmt.Sprintf(
|
||||
"WARNING! The \"nomad %s\" command is deprecated. Please use \"nomad %s\" "+
|
||||
"instead. This command will be removed in Nomad 0.10 (or later).",
|
||||
"instead. This command will be removed a later version of Nomad.",
|
||||
c.Old,
|
||||
c.New)))
|
||||
c.Ui.Warn("")
|
||||
|
@ -305,16 +305,6 @@ func Commands(metaPtr *Meta, agentUi cli.Ui) map[string]cli.CommandFactory {
|
|||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"keygen": func() (cli.Command, error) {
|
||||
return &OperatorKeygenCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"keyring": func() (cli.Command, error) {
|
||||
return &OperatorKeyringCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"job": func() (cli.Command, error) {
|
||||
return &JobCommand{
|
||||
Meta: meta,
|
||||
|
@ -529,16 +519,49 @@ func Commands(metaPtr *Meta, agentUi cli.Ui) map[string]cli.CommandFactory {
|
|||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"operator keygen": func() (cli.Command, error) {
|
||||
return &OperatorKeygenCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
|
||||
// COMPAT(1.4.0): deprecated, remove in Nomad 1.5.0
|
||||
// Note: we can't just put this in the DeprecatedCommand list
|
||||
// because the flags have changed too. So we've provided the
|
||||
// deprecation warning in the original command and when it's
|
||||
// time to remove it we can remove the entire command
|
||||
"operator keyring": func() (cli.Command, error) {
|
||||
return &OperatorKeyringCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
|
||||
"operator gossip keyring": func() (cli.Command, error) {
|
||||
return &OperatorGossipKeyringCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"operator gossip keyring install": func() (cli.Command, error) {
|
||||
return &OperatorGossipKeyringInstallCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"operator gossip keyring use": func() (cli.Command, error) {
|
||||
return &OperatorGossipKeyringUseCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"operator gossip keyring list": func() (cli.Command, error) {
|
||||
return &OperatorGossipKeyringListCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"operator gossip keyring remove": func() (cli.Command, error) {
|
||||
return &OperatorGossipKeyringRemoveCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
"operator gossip keyring generate": func() (cli.Command, error) {
|
||||
return &OperatorGossipKeyringGenerateCommand{
|
||||
Meta: meta,
|
||||
}, nil
|
||||
},
|
||||
|
||||
"operator metrics": func() (cli.Command, error) {
|
||||
return &OperatorMetricsCommand{
|
||||
Meta: meta,
|
||||
|
@ -961,9 +984,20 @@ func Commands(metaPtr *Meta, agentUi cli.Ui) map[string]cli.CommandFactory {
|
|||
"keygen": func() (cli.Command, error) {
|
||||
return &DeprecatedCommand{
|
||||
Old: "keygen",
|
||||
New: "operator keygen",
|
||||
New: "operator gossip keyring generate",
|
||||
Meta: meta,
|
||||
Command: &OperatorKeygenCommand{
|
||||
Command: &OperatorGossipKeyringGenerateCommand{
|
||||
Meta: meta,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
|
||||
"operator keygen": func() (cli.Command, error) {
|
||||
return &DeprecatedCommand{
|
||||
Old: "operator keygen",
|
||||
New: "operator gossip keyring generate",
|
||||
Meta: meta,
|
||||
Command: &OperatorGossipKeyringGenerateCommand{
|
||||
Meta: meta,
|
||||
},
|
||||
}, nil
|
||||
|
@ -972,7 +1006,7 @@ func Commands(metaPtr *Meta, agentUi cli.Ui) map[string]cli.CommandFactory {
|
|||
"keyring": func() (cli.Command, error) {
|
||||
return &DeprecatedCommand{
|
||||
Old: "keyring",
|
||||
New: "operator keyring",
|
||||
New: "operator gossip keyring",
|
||||
Meta: meta,
|
||||
Command: &OperatorKeyringCommand{
|
||||
Meta: meta,
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// OperatorGossipKeyringCommand is a Command implementation that
|
||||
// handles querying, installing, and removing gossip encryption keys
|
||||
// from a keyring.
|
||||
type OperatorGossipKeyringCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: nomad operator gossip keyring [options]
|
||||
|
||||
Manages encryption keys used for gossip messages between Nomad servers. Gossip
|
||||
encryption is optional. When enabled, this command may be used to examine
|
||||
active encryption keys in the cluster, add new keys, and remove old ones. When
|
||||
combined, this functionality provides the ability to perform key rotation
|
||||
cluster-wide, without disrupting the cluster.
|
||||
|
||||
Generate an encryption key:
|
||||
|
||||
$ nomad operator gossip keyring generate
|
||||
|
||||
List all gossip encryption keys:
|
||||
|
||||
$ nomad operator gossip keyring list
|
||||
|
||||
Remove an encryption key from the keyring:
|
||||
|
||||
$ nomad operator gossip keyring remove <key>
|
||||
|
||||
Install an encryption key from backup:
|
||||
|
||||
$ nomad operator gossip keyring install <key>
|
||||
|
||||
Use an already-installed encryption key:
|
||||
|
||||
$ nomad operator gossip keyring use <key>
|
||||
|
||||
Please see individual subcommand help for detailed usage information.
|
||||
|
||||
General Options:
|
||||
|
||||
` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace)
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringCommand) Synopsis() string {
|
||||
return "Manages gossip layer encryption keys"
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Meta.AutocompleteFlags(FlagSetClient)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictNothing
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringCommand) Name() string { return "operator gossip keyring" }
|
||||
|
||||
func (c *OperatorGossipKeyringCommand) Run(args []string) int {
|
||||
return cli.RunResultHelp
|
||||
}
|
|
@ -7,19 +7,20 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// OperatorKeygenCommand is a Command implementation that generates an encryption
|
||||
// key for use in `nomad agent`.
|
||||
type OperatorKeygenCommand struct {
|
||||
// OperatorGossipKeyringGenerateCommand is a Command implementation that
|
||||
// generates an encryption key for use in `nomad agent`.
|
||||
type OperatorGossipKeyringGenerateCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
func (c *OperatorKeygenCommand) Synopsis() string {
|
||||
func (c *OperatorGossipKeyringGenerateCommand) Synopsis() string {
|
||||
return "Generates a new encryption key"
|
||||
}
|
||||
|
||||
func (c *OperatorKeygenCommand) Help() string {
|
||||
func (c *OperatorGossipKeyringGenerateCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: nomad operator keygen
|
||||
Usage: nomad operator gossip keying generate
|
||||
Alias: nomad operator keygen
|
||||
|
||||
Generates a new 32-byte encryption key that can be used to configure the
|
||||
agent to encrypt traffic. The output of this command is already
|
||||
|
@ -28,9 +29,11 @@ Usage: nomad operator keygen
|
|||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *OperatorKeygenCommand) Name() string { return "operator keygen" }
|
||||
func (c *OperatorGossipKeyringGenerateCommand) Name() string {
|
||||
return "operator gossip keyring generate"
|
||||
}
|
||||
|
||||
func (c *OperatorKeygenCommand) Run(_ []string) int {
|
||||
func (c *OperatorGossipKeyringGenerateCommand) Run(_ []string) int {
|
||||
key := make([]byte, 32)
|
||||
n, err := rand.Reader.Read(key)
|
||||
if err != nil {
|
|
@ -0,0 +1,87 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// OperatorGossipKeyringInstallCommand is a Command implementation
|
||||
// that handles installing a gossip encryption key from a keyring
|
||||
type OperatorGossipKeyringInstallCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringInstallCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: nomad operator gossip keyring install [options] <key>
|
||||
|
||||
Install a new encryption key used for gossip. This will broadcast the new key
|
||||
to all members in the cluster.
|
||||
|
||||
This command can only be run against server nodes. It returns 0 if all nodes
|
||||
reply and there are no errors. If any node fails to reply or reports failure,
|
||||
the exit code will be 1.
|
||||
|
||||
If ACLs are enabled, this command requires a token with the 'agent:write'
|
||||
capability.
|
||||
|
||||
General Options:
|
||||
|
||||
` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace)
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringInstallCommand) Synopsis() string {
|
||||
return "Install a gossip encryption key"
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringInstallCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Meta.AutocompleteFlags(FlagSetClient)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringInstallCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictAnything
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringInstallCommand) Name() string { return "operator gossip keyring install" }
|
||||
|
||||
func (c *OperatorGossipKeyringInstallCommand) Run(args []string) int {
|
||||
flags := c.Meta.FlagSet("operator-gossip-keyring-install", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui = &cli.PrefixedUi{
|
||||
OutputPrefix: "",
|
||||
InfoPrefix: "==> ",
|
||||
ErrorPrefix: "",
|
||||
Ui: c.Ui,
|
||||
}
|
||||
|
||||
args = flags.Args()
|
||||
if len(args) != 1 {
|
||||
c.Ui.Error("This command requires one argument: <key>")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
installKey := args[0]
|
||||
|
||||
client, err := c.Meta.Client()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error creating nomad cli client: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui.Output("Installing new gossip encryption key...")
|
||||
_, err = client.Agent().InstallKey(installKey)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("error: %s", err))
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/nomad/api"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// OperatorGossipKeyringListCommand is a Command implementation
|
||||
// that handles removing a gossip encryption key from a keyring
|
||||
type OperatorGossipKeyringListCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringListCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: nomad operator gossip keyring list [options]
|
||||
|
||||
List all gossip keys currently in use within the cluster.
|
||||
|
||||
This command can only be run against server nodes. It returns 0 if all nodes
|
||||
reply and there are no errors. If any node fails to reply or reports failure,
|
||||
the exit code will be 1.
|
||||
|
||||
If ACLs are enabled, this command requires a token with the 'agent:write'
|
||||
capability.
|
||||
|
||||
General Options:
|
||||
|
||||
` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace)
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringListCommand) Synopsis() string {
|
||||
return "List gossip encryption keys"
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringListCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Meta.AutocompleteFlags(FlagSetClient)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringListCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictAnything
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringListCommand) Name() string { return "operator gossip keyring list" }
|
||||
|
||||
func (c *OperatorGossipKeyringListCommand) Run(args []string) int {
|
||||
flags := c.Meta.FlagSet("operator-gossip-keyring-list", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui = &cli.PrefixedUi{
|
||||
OutputPrefix: "",
|
||||
InfoPrefix: "==> ",
|
||||
ErrorPrefix: "",
|
||||
Ui: c.Ui,
|
||||
}
|
||||
|
||||
args = flags.Args()
|
||||
if len(args) != 0 {
|
||||
c.Ui.Error("This command requires no arguments")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
|
||||
client, err := c.Meta.Client()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error creating nomad cli client: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui.Output("Gathering installed encryption keys...")
|
||||
r, err := client.Agent().ListKeys()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("error: %s", err))
|
||||
return 1
|
||||
}
|
||||
c.handleKeyResponse(r)
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringListCommand) handleKeyResponse(resp *api.KeyringResponse) {
|
||||
out := make([]string, len(resp.Keys)+1)
|
||||
out[0] = "Key"
|
||||
i := 1
|
||||
for k := range resp.Keys {
|
||||
out[i] = k
|
||||
i = i + 1
|
||||
}
|
||||
c.Ui.Output(formatList(out))
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// OperatorGossipKeyringRemoveCommand is a Command implementation
|
||||
// that handles removing a gossip encryption key from a keyring
|
||||
type OperatorGossipKeyringRemoveCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringRemoveCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: nomad operator gossip keyring remove [options] <key>
|
||||
|
||||
Remove the given key from the cluster. This operation may only be performed
|
||||
on keys which are not currently the primary key.
|
||||
|
||||
This command can only be run against server nodes. It returns 0 if all nodes
|
||||
reply and there are no errors. If any node fails to reply or reports failure,
|
||||
the exit code will be 1.
|
||||
|
||||
If ACLs are enabled, this command requires a token with the 'agent:write'
|
||||
capability.
|
||||
|
||||
General Options:
|
||||
|
||||
` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace)
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringRemoveCommand) Synopsis() string {
|
||||
return "Remove a gossip encryption key"
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringRemoveCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Meta.AutocompleteFlags(FlagSetClient)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringRemoveCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictAnything
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringRemoveCommand) Name() string { return "operator gossip keyring remove" }
|
||||
|
||||
func (c *OperatorGossipKeyringRemoveCommand) Run(args []string) int {
|
||||
flags := c.Meta.FlagSet("operator-gossip-keyring-remove", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui = &cli.PrefixedUi{
|
||||
OutputPrefix: "",
|
||||
InfoPrefix: "==> ",
|
||||
ErrorPrefix: "",
|
||||
Ui: c.Ui,
|
||||
}
|
||||
|
||||
args = flags.Args()
|
||||
if len(args) != 1 {
|
||||
c.Ui.Error("This command requires one argument: <key>")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
removeKey := args[0]
|
||||
|
||||
client, err := c.Meta.Client()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error creating nomad cli client: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui.Output("Removing gossip encryption key...")
|
||||
_, err = client.Agent().RemoveKey(removeKey)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("error: %s", err))
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
|
@ -8,11 +8,11 @@ import (
|
|||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func TestKeygenCommand(t *testing.T) {
|
||||
func TestGossipKeyringGenerateCommand(t *testing.T) {
|
||||
ci.Parallel(t)
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
c := &OperatorKeygenCommand{Meta: Meta{Ui: ui}}
|
||||
c := &OperatorGossipKeyringGenerateCommand{Meta: Meta{Ui: ui}}
|
||||
code := c.Run(nil)
|
||||
if code != 0 {
|
||||
t.Fatalf("bad: %d", code)
|
|
@ -0,0 +1,87 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// OperatorGossipKeyringUseCommand is a Command implementation that
|
||||
// handles setting the gossip encryption key from a keyring
|
||||
type OperatorGossipKeyringUseCommand struct {
|
||||
Meta
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringUseCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: nomad operator gossip keyring use [options] <key>
|
||||
|
||||
Change the encryption key used for gossip. The key must already be installed
|
||||
before this operator can succeed.
|
||||
|
||||
This command can only be run against server nodes. It returns 0 if all nodes
|
||||
reply and there are no errors. If any node fails to reply or reports failure,
|
||||
the exit code will be 1.
|
||||
|
||||
If ACLs are enabled, this command requires a token with the 'agent:write'
|
||||
capability.
|
||||
|
||||
General Options:
|
||||
|
||||
` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace)
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringUseCommand) Synopsis() string {
|
||||
return "Change the gossip encryption key"
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringUseCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Meta.AutocompleteFlags(FlagSetClient)
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringUseCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictAnything
|
||||
}
|
||||
|
||||
func (c *OperatorGossipKeyringUseCommand) Name() string { return "operator gossip keyring use" }
|
||||
|
||||
func (c *OperatorGossipKeyringUseCommand) Run(args []string) int {
|
||||
flags := c.Meta.FlagSet("operator-gossip-keyring-use", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui = &cli.PrefixedUi{
|
||||
OutputPrefix: "",
|
||||
InfoPrefix: "==> ",
|
||||
ErrorPrefix: "",
|
||||
Ui: c.Ui,
|
||||
}
|
||||
|
||||
args = flags.Args()
|
||||
if len(args) != 1 {
|
||||
c.Ui.Error("This command requires one argument: <key>")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
useKey := args[0]
|
||||
|
||||
client, err := c.Meta.Client()
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error creating nomad cli client: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
c.Ui.Output("Changing primary gossip encryption key...")
|
||||
_, err = client.Agent().UseKey(useKey)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("error: %s", err))
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
|
@ -88,6 +88,10 @@ func (c *OperatorKeyringCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
c.Ui.Warn(wrapAtLength("WARNING! The \"nomad operator keyring\" command " +
|
||||
"is deprecated. Please use \"nomad operator gossip keyring\" instead. " +
|
||||
"This command will be removed in Nomad 1.5.0."))
|
||||
c.Ui.Warn("")
|
||||
c.Ui = &cli.PrefixedUi{
|
||||
OutputPrefix: "",
|
||||
InfoPrefix: "==> ",
|
||||
|
|
Loading…
Reference in New Issue