From fe90e0a9e08c3bbe06f74d31c853bd463f788b2c Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Fri, 6 Mar 2020 14:40:50 -0800 Subject: [PATCH] Rename raft configuration command to list-peers and make output easier to read (#8484) * Make the output of raft configuration easier to read * Rename raft configuration sub command to list-peers * Update command/operator_raft_listpeers.go Co-Authored-By: Calvin Leung Huang Co-authored-by: Calvin Leung Huang --- CHANGELOG.md | 5 ++ command/commands.go | 4 +- command/operator_raft.go | 8 ++- command/operator_raft_configuration.go | 72 -------------------- command/operator_raft_listpeers.go | 93 ++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 76 deletions(-) delete mode 100644 command/operator_raft_configuration.go create mode 100644 command/operator_raft_listpeers.go diff --git a/CHANGELOG.md b/CHANGELOG.md index f2de40c6b..458bd07cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## Next +CHANGES: + +* cli: The raft configuration command has been renamed to list-peers to avoid + confusion. + IMPROVEMENTS: * auth/azure: subscription ID, resource group, vm and vmss names are now stored in alias metadata [[GH-30](https://github.com/hashicorp/vault-plugin-auth-azure/pull/30)] diff --git a/command/commands.go b/command/commands.go index 49d9c2339..24f47dd22 100644 --- a/command/commands.go +++ b/command/commands.go @@ -357,8 +357,8 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) { BaseCommand: getBaseCommand(), }, nil }, - "operator raft configuration": func() (cli.Command, error) { - return &OperatorRaftConfigurationCommand{ + "operator raft list-peers": func() (cli.Command, error) { + return &OperatorRaftListPeersCommand{ BaseCommand: getBaseCommand(), }, nil }, diff --git a/command/operator_raft.go b/command/operator_raft.go index 5af096fb5..cb5f7eecb 100644 --- a/command/operator_raft.go +++ b/command/operator_raft.go @@ -28,14 +28,18 @@ Usage: vault operator raft [options] [args] $ vault operator raft join https://127.0.0.1:8200 - Returns the raft cluster configuration: + Returns the set of raft peers: - $ vault operator raft configuration + $ vault operator raft list-peers Removes a node from the raft cluster: $ vault operator raft remove-peer + Restores and saves snapshots from the raft cluster: + + $ vault operator raft snapshot take out.snap + Please see the individual subcommand help for detailed usage information. ` diff --git a/command/operator_raft_configuration.go b/command/operator_raft_configuration.go deleted file mode 100644 index 7fe4e0b9b..000000000 --- a/command/operator_raft_configuration.go +++ /dev/null @@ -1,72 +0,0 @@ -package command - -import ( - "fmt" - "strings" - - "github.com/mitchellh/cli" - "github.com/posener/complete" -) - -var _ cli.Command = (*OperatorRaftConfigurationCommand)(nil) -var _ cli.CommandAutocomplete = (*OperatorRaftConfigurationCommand)(nil) - -type OperatorRaftConfigurationCommand struct { - *BaseCommand -} - -func (c *OperatorRaftConfigurationCommand) Synopsis() string { - return "Returns the raft cluster configuration" -} - -func (c *OperatorRaftConfigurationCommand) Help() string { - helpText := ` -Usage: vault operator raft configuration - - Provides the details of all the peers in the raft cluster. - - $ vault operator raft configuration - -` + c.Flags().Help() - - return strings.TrimSpace(helpText) -} - -func (c *OperatorRaftConfigurationCommand) Flags() *FlagSets { - set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat) - - return set -} - -func (c *OperatorRaftConfigurationCommand) AutocompleteArgs() complete.Predictor { - return complete.PredictAnything -} - -func (c *OperatorRaftConfigurationCommand) AutocompleteFlags() complete.Flags { - return c.Flags().Completions() -} - -func (c *OperatorRaftConfigurationCommand) Run(args []string) int { - f := c.Flags() - - if err := f.Parse(args); err != nil { - c.UI.Error(err.Error()) - return 1 - } - - client, err := c.Client() - if err != nil { - c.UI.Error(err.Error()) - return 2 - } - - secret, err := client.Logical().Read("sys/storage/raft/configuration") - if err != nil { - c.UI.Error(fmt.Sprintf("Error reading the raft cluster configuration: %s", err)) - return 2 - } - - OutputSecret(c.UI, secret) - - return 0 -} diff --git a/command/operator_raft_listpeers.go b/command/operator_raft_listpeers.go new file mode 100644 index 000000000..b9cbd2eb4 --- /dev/null +++ b/command/operator_raft_listpeers.go @@ -0,0 +1,93 @@ +package command + +import ( + "fmt" + "strings" + + "github.com/mitchellh/cli" + "github.com/posener/complete" +) + +var _ cli.Command = (*OperatorRaftListPeersCommand)(nil) +var _ cli.CommandAutocomplete = (*OperatorRaftListPeersCommand)(nil) + +type OperatorRaftListPeersCommand struct { + *BaseCommand +} + +func (c *OperatorRaftListPeersCommand) Synopsis() string { + return "Returns the raft peer set" +} + +func (c *OperatorRaftListPeersCommand) Help() string { + helpText := ` +Usage: vault operator raft list-peers + + Provides the details of all the peers in the raft cluster. + + $ vault operator raft list-peers + +` + c.Flags().Help() + + return strings.TrimSpace(helpText) +} + +func (c *OperatorRaftListPeersCommand) Flags() *FlagSets { + set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat) + + return set +} + +func (c *OperatorRaftListPeersCommand) AutocompleteArgs() complete.Predictor { + return complete.PredictAnything +} + +func (c *OperatorRaftListPeersCommand) AutocompleteFlags() complete.Flags { + return c.Flags().Completions() +} + +func (c *OperatorRaftListPeersCommand) Run(args []string) int { + f := c.Flags() + + if err := f.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + client, err := c.Client() + if err != nil { + c.UI.Error(err.Error()) + return 2 + } + + secret, err := client.Logical().Read("sys/storage/raft/configuration") + if err != nil { + c.UI.Error(fmt.Sprintf("Error reading the raft cluster configuration: %s", err)) + return 2 + } + if secret == nil { + c.UI.Error("No raft cluster configuration found") + return 2 + } + + if Format(c.UI) != "table" { + return OutputSecret(c.UI, secret) + } + + config := secret.Data["config"].(map[string]interface{}) + + servers := config["servers"].([]interface{}) + out := []string{"Node | Address | State | Voter"} + for _, serverRaw := range servers { + server := serverRaw.(map[string]interface{}) + state := "follower" + if server["leader"].(bool) { + state = "leader" + } + + out = append(out, fmt.Sprintf("%s | %s | %s | %t", server["node_id"].(string), server["address"].(string), state, server["voter"].(bool))) + } + + c.UI.Output(tableOutput(out, nil)) + return 0 +}