Use a unified helper for seal output
This commit is contained in:
parent
e26625c909
commit
f5543844f3
|
@ -206,3 +206,50 @@ func (t TableFormatter) OutputSecret(ui cli.Ui, secret *api.Secret) error {
|
||||||
}))
|
}))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func OutputSealStatus(ui cli.Ui, client *api.Client, status *api.SealStatusResponse) int {
|
||||||
|
out := []string{}
|
||||||
|
out = append(out, "Key | Value")
|
||||||
|
out = append(out, fmt.Sprintf("Sealed | %t", status.Sealed))
|
||||||
|
out = append(out, fmt.Sprintf("Total Shares | %d", status.N))
|
||||||
|
|
||||||
|
if status.Sealed {
|
||||||
|
out = append(out, fmt.Sprintf("Unseal Progress | %d/%d", status.Progress, status.T))
|
||||||
|
out = append(out, fmt.Sprintf("Unseal Nonce | %s", status.Nonce))
|
||||||
|
}
|
||||||
|
|
||||||
|
out = append(out, fmt.Sprintf("Version | %s", status.Version))
|
||||||
|
|
||||||
|
if status.ClusterName != "" && status.ClusterID != "" {
|
||||||
|
out = append(out, fmt.Sprintf("Cluster Name | %s", status.ClusterName))
|
||||||
|
out = append(out, fmt.Sprintf("Cluster ID | %s", status.ClusterID))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask the 'Vault is sealed' error, since this means HA is enabled, but that
|
||||||
|
// we cannot query for the leader since we are sealed.
|
||||||
|
leaderStatus, err := client.Sys().Leader()
|
||||||
|
if err != nil && strings.Contains(err.Error(), "Vault is sealed") {
|
||||||
|
leaderStatus = &api.LeaderResponse{HAEnabled: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output if HA is enabled
|
||||||
|
out = append(out, fmt.Sprintf("HA Enabled | %t", leaderStatus.HAEnabled))
|
||||||
|
if leaderStatus.HAEnabled {
|
||||||
|
mode := "sealed"
|
||||||
|
if !status.Sealed {
|
||||||
|
mode = "standby"
|
||||||
|
if leaderStatus.IsSelf {
|
||||||
|
mode = "active"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out = append(out, fmt.Sprintf("HA Mode | %s", mode))
|
||||||
|
|
||||||
|
if !status.Sealed {
|
||||||
|
out = append(out, fmt.Sprintf("HA Cluster | %s", leaderStatus.LeaderClusterAddress))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.Output(tableOutput(out, nil))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/api"
|
|
||||||
"github.com/hashicorp/vault/helper/password"
|
"github.com/hashicorp/vault/helper/password"
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
"github.com/posener/complete"
|
"github.com/posener/complete"
|
||||||
|
@ -69,7 +68,7 @@ func (c *OperatorUnsealCommand) Flags() *FlagSets {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OperatorUnsealCommand) AutocompleteArgs() complete.Predictor {
|
func (c *OperatorUnsealCommand) AutocompleteArgs() complete.Predictor {
|
||||||
return c.PredictVaultFiles()
|
return complete.PredictAnything
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *OperatorUnsealCommand) AutocompleteFlags() complete.Flags {
|
func (c *OperatorUnsealCommand) AutocompleteFlags() complete.Flags {
|
||||||
|
@ -109,8 +108,7 @@ func (c *OperatorUnsealCommand) Run(args []string) int {
|
||||||
c.UI.Error(fmt.Sprintf("Error resetting unseal process: %s", err))
|
c.UI.Error(fmt.Sprintf("Error resetting unseal process: %s", err))
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
c.prettySealStatus(status)
|
return OutputSealStatus(c.UI, client, status)
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if unsealKey == "" {
|
if unsealKey == "" {
|
||||||
|
@ -120,7 +118,7 @@ func (c *OperatorUnsealCommand) Run(args []string) int {
|
||||||
writer = c.testOutput
|
writer = c.testOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(writer, "Key (will be hidden): ")
|
fmt.Fprintf(writer, "Unseal Key (will be hidden): ")
|
||||||
value, err := password.Read(os.Stdin)
|
value, err := password.Read(os.Stdin)
|
||||||
fmt.Fprintf(writer, "\n")
|
fmt.Fprintf(writer, "\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -143,16 +141,5 @@ func (c *OperatorUnsealCommand) Run(args []string) int {
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
c.prettySealStatus(status)
|
return OutputSealStatus(c.UI, client, status)
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OperatorUnsealCommand) prettySealStatus(status *api.SealStatusResponse) {
|
|
||||||
c.UI.Output(fmt.Sprintf("Sealed: %t", status.Sealed))
|
|
||||||
c.UI.Output(fmt.Sprintf("Key Shares: %d", status.N))
|
|
||||||
c.UI.Output(fmt.Sprintf("Key Threshold: %d", status.T))
|
|
||||||
c.UI.Output(fmt.Sprintf("Unseal Progress: %d", status.Progress))
|
|
||||||
if status.Nonce != "" {
|
|
||||||
c.UI.Output(fmt.Sprintf("Unseal Nonce: %s", status.Nonce))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/api"
|
|
||||||
"github.com/mitchellh/cli"
|
"github.com/mitchellh/cli"
|
||||||
"github.com/posener/complete"
|
"github.com/posener/complete"
|
||||||
)
|
)
|
||||||
|
@ -72,68 +71,17 @@ func (c *StatusCommand) Run(args []string) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
sealStatus, err := client.Sys().SealStatus()
|
status, err := client.Sys().SealStatus()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.UI.Error(fmt.Sprintf("Error checking seal status: %s", err))
|
c.UI.Error(fmt.Sprintf("Error checking seal status: %s", err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
outStr := fmt.Sprintf(
|
// Do not return the int here, since we want to return a custom error code
|
||||||
"Sealed: %v\n"+
|
// depending on the seal status.
|
||||||
"Key Shares: %d\n"+
|
OutputSealStatus(c.UI, client, status)
|
||||||
"Key Threshold: %d\n"+
|
|
||||||
"Unseal Progress: %d\n"+
|
|
||||||
"Unseal Nonce: %v\n"+
|
|
||||||
"Version: %s",
|
|
||||||
sealStatus.Sealed,
|
|
||||||
sealStatus.N,
|
|
||||||
sealStatus.T,
|
|
||||||
sealStatus.Progress,
|
|
||||||
sealStatus.Nonce,
|
|
||||||
sealStatus.Version)
|
|
||||||
|
|
||||||
if sealStatus.ClusterName != "" && sealStatus.ClusterID != "" {
|
if status.Sealed {
|
||||||
outStr = fmt.Sprintf("%s\nCluster Name: %s\nCluster ID: %s", outStr, sealStatus.ClusterName, sealStatus.ClusterID)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.UI.Output(outStr)
|
|
||||||
|
|
||||||
// Mask the 'Vault is sealed' error, since this means HA is enabled, but that
|
|
||||||
// we cannot query for the leader since we are sealed.
|
|
||||||
leaderStatus, err := client.Sys().Leader()
|
|
||||||
if err != nil && strings.Contains(err.Error(), "Vault is sealed") {
|
|
||||||
leaderStatus = &api.LeaderResponse{HAEnabled: true}
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
c.UI.Error(fmt.Sprintf("Error checking leader status: %s", err))
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output if HA is enabled
|
|
||||||
c.UI.Output("")
|
|
||||||
c.UI.Output(fmt.Sprintf("High-Availability Enabled: %v", leaderStatus.HAEnabled))
|
|
||||||
if leaderStatus.HAEnabled {
|
|
||||||
if sealStatus.Sealed {
|
|
||||||
c.UI.Output("\tMode: sealed")
|
|
||||||
} else {
|
|
||||||
mode := "standby"
|
|
||||||
if leaderStatus.IsSelf {
|
|
||||||
mode = "active"
|
|
||||||
}
|
|
||||||
c.UI.Output(fmt.Sprintf("\tMode: %s", mode))
|
|
||||||
|
|
||||||
if leaderStatus.LeaderAddress == "" {
|
|
||||||
leaderStatus.LeaderAddress = "<none>"
|
|
||||||
}
|
|
||||||
if leaderStatus.LeaderClusterAddress == "" {
|
|
||||||
leaderStatus.LeaderClusterAddress = "<none>"
|
|
||||||
}
|
|
||||||
c.UI.Output(fmt.Sprintf("\tLeader Cluster Address: %s", leaderStatus.LeaderClusterAddress))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if sealStatus.Sealed {
|
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue