mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
Normalize format output for vault status [VAULT-508] (#9976)
* normalize format output for vault status * interim commit * interim commit * make formatting idiomatic * clean up comments * added formatting test * updated comments in format test to match godocs Co-authored-by: HridoyRoy <hridoyroy@Hridoys-MBP.hitronhub.home> Co-authored-by: HridoyRoy <hridoyroy@Hridoys-MacBook-Pro.local>
This commit is contained in:
@@ -117,7 +117,8 @@ func (y YamlFormatter) Output(ui cli.Ui, secret *api.Secret, data interface{}) e
|
||||
// An output formatter for table output of an object
|
||||
type TableFormatter struct{}
|
||||
|
||||
// We don't use this
|
||||
// We don't use this due to the TableFormatter introducing a bug when the -field flag is supplied:
|
||||
// https://github.com/hashicorp/vault/commit/b24cf9a8af2190e96c614205b8cdf06d8c4b6718 .
|
||||
func (t TableFormatter) Format(data interface{}) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -132,11 +133,92 @@ func (t TableFormatter) Output(ui cli.Ui, secret *api.Secret, data interface{})
|
||||
return t.OutputList(ui, nil, data)
|
||||
case map[string]interface{}:
|
||||
return t.OutputMap(ui, data.(map[string]interface{}))
|
||||
case SealStatusOutput:
|
||||
return t.OutputSealStatusStruct(ui, nil, data)
|
||||
default:
|
||||
return errors.New("cannot use the table formatter for this type")
|
||||
}
|
||||
}
|
||||
|
||||
func (t TableFormatter) OutputSealStatusStruct(ui cli.Ui, secret *api.Secret, data interface{}) error {
|
||||
var status SealStatusOutput = data.(SealStatusOutput)
|
||||
var sealPrefix string
|
||||
if status.RecoverySeal {
|
||||
sealPrefix = "Recovery "
|
||||
}
|
||||
|
||||
out := []string{}
|
||||
out = append(out, "Key | Value")
|
||||
out = append(out, fmt.Sprintf("%sSeal Type | %s", sealPrefix, status.Type))
|
||||
out = append(out, fmt.Sprintf("Initialized | %t", status.Initialized))
|
||||
out = append(out, fmt.Sprintf("Sealed | %t", status.Sealed))
|
||||
out = append(out, fmt.Sprintf("Total %sShares | %d", sealPrefix, status.N))
|
||||
out = append(out, fmt.Sprintf("Threshold | %d", status.T))
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
if status.Migration {
|
||||
out = append(out, fmt.Sprintf("Seal Migration in Progress | %t", status.Migration))
|
||||
}
|
||||
|
||||
out = append(out, fmt.Sprintf("Version | %s", status.Version))
|
||||
out = append(out, fmt.Sprintf("Storage Type | %s", status.StorageType))
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
// Output if HA is enabled
|
||||
out = append(out, fmt.Sprintf("HA Enabled | %t", status.HAEnabled))
|
||||
|
||||
if status.HAEnabled {
|
||||
mode := "sealed"
|
||||
if !status.Sealed {
|
||||
out = append(out, fmt.Sprintf("HA Cluster | %s", status.LeaderClusterAddress))
|
||||
mode = "standby"
|
||||
showLeaderAddr := false
|
||||
if status.IsSelf {
|
||||
mode = "active"
|
||||
} else {
|
||||
if status.LeaderAddress == "" {
|
||||
status.LeaderAddress = "<none>"
|
||||
}
|
||||
showLeaderAddr = true
|
||||
}
|
||||
out = append(out, fmt.Sprintf("HA Mode | %s", mode))
|
||||
|
||||
// This is down here just to keep ordering consistent
|
||||
if showLeaderAddr {
|
||||
out = append(out, fmt.Sprintf("Active Node Address | %s", status.LeaderAddress))
|
||||
}
|
||||
|
||||
if status.PerfStandby {
|
||||
out = append(out, fmt.Sprintf("Performance Standby Node | %t", status.PerfStandby))
|
||||
out = append(out, fmt.Sprintf("Performance Standby Last Remote WAL | %d", status.PerfStandbyLastRemoteWAL))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if status.RaftCommittedIndex > 0 {
|
||||
out = append(out, fmt.Sprintf("Raft Committed Index | %d", status.RaftCommittedIndex))
|
||||
}
|
||||
if status.RaftAppliedIndex > 0 {
|
||||
out = append(out, fmt.Sprintf("Raft Applied Index | %d", status.RaftAppliedIndex))
|
||||
}
|
||||
if status.LastWAL != 0 {
|
||||
out = append(out, fmt.Sprintf("Last WAL | %d", status.LastWAL))
|
||||
}
|
||||
|
||||
ui.Output(tableOutput(out, &columnize.Config{
|
||||
Delim: "|",
|
||||
}))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t TableFormatter) OutputList(ui cli.Ui, secret *api.Secret, data interface{}) error {
|
||||
t.printWarnings(ui, secret)
|
||||
|
||||
@@ -306,41 +388,7 @@ func (t TableFormatter) OutputMap(ui cli.Ui, data map[string]interface{}) error
|
||||
|
||||
// OutputSealStatus will print *api.SealStatusResponse in the CLI according to the format provided
|
||||
func OutputSealStatus(ui cli.Ui, client *api.Client, status *api.SealStatusResponse) int {
|
||||
switch Format(ui) {
|
||||
case "table":
|
||||
default:
|
||||
return OutputData(ui, status)
|
||||
}
|
||||
|
||||
var sealPrefix string
|
||||
if status.RecoverySeal {
|
||||
sealPrefix = "Recovery "
|
||||
}
|
||||
|
||||
out := []string{}
|
||||
out = append(out, "Key | Value")
|
||||
out = append(out, fmt.Sprintf("%sSeal Type | %s", sealPrefix, status.Type))
|
||||
out = append(out, fmt.Sprintf("Initialized | %t", status.Initialized))
|
||||
out = append(out, fmt.Sprintf("Sealed | %t", status.Sealed))
|
||||
out = append(out, fmt.Sprintf("Total %sShares | %d", sealPrefix, status.N))
|
||||
out = append(out, fmt.Sprintf("Threshold | %d", status.T))
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
if status.Migration {
|
||||
out = append(out, fmt.Sprintf("Seal Migration in Progress | %t", status.Migration))
|
||||
}
|
||||
|
||||
out = append(out, fmt.Sprintf("Version | %s", status.Version))
|
||||
out = append(out, fmt.Sprintf("Storage Type | %s", status.StorageType))
|
||||
|
||||
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))
|
||||
}
|
||||
sealStatusOutput := SealStatusOutput{SealStatusResponse: *status}
|
||||
|
||||
// Mask the 'Vault is sealed' error, since this means HA is enabled, but that
|
||||
// we cannot query for the leader since we are sealed.
|
||||
@@ -354,48 +402,17 @@ func OutputSealStatus(ui cli.Ui, client *api.Client, status *api.SealStatusRespo
|
||||
return 1
|
||||
}
|
||||
|
||||
// Output if HA is enabled
|
||||
out = append(out, fmt.Sprintf("HA Enabled | %t", leaderStatus.HAEnabled))
|
||||
|
||||
if leaderStatus.HAEnabled {
|
||||
mode := "sealed"
|
||||
if !status.Sealed {
|
||||
out = append(out, fmt.Sprintf("HA Cluster | %s", leaderStatus.LeaderClusterAddress))
|
||||
mode = "standby"
|
||||
showLeaderAddr := false
|
||||
if leaderStatus.IsSelf {
|
||||
mode = "active"
|
||||
} else {
|
||||
if leaderStatus.LeaderAddress == "" {
|
||||
leaderStatus.LeaderAddress = "<none>"
|
||||
}
|
||||
showLeaderAddr = true
|
||||
}
|
||||
out = append(out, fmt.Sprintf("HA Mode | %s", mode))
|
||||
|
||||
// This is down here just to keep ordering consistent
|
||||
if showLeaderAddr {
|
||||
out = append(out, fmt.Sprintf("Active Node Address | %s", leaderStatus.LeaderAddress))
|
||||
}
|
||||
|
||||
if leaderStatus.PerfStandby {
|
||||
out = append(out, fmt.Sprintf("Performance Standby Node | %t", leaderStatus.PerfStandby))
|
||||
out = append(out, fmt.Sprintf("Performance Standby Last Remote WAL | %d", leaderStatus.PerfStandbyLastRemoteWAL))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if leaderStatus.RaftCommittedIndex > 0 {
|
||||
out = append(out, fmt.Sprintf("Raft Committed Index | %d", leaderStatus.RaftCommittedIndex))
|
||||
}
|
||||
if leaderStatus.RaftAppliedIndex > 0 {
|
||||
out = append(out, fmt.Sprintf("Raft Applied Index | %d", leaderStatus.RaftAppliedIndex))
|
||||
}
|
||||
if leaderStatus.LastWAL != 0 {
|
||||
out = append(out, fmt.Sprintf("Last WAL | %d", leaderStatus.LastWAL))
|
||||
}
|
||||
|
||||
ui.Output(tableOutput(out, nil))
|
||||
// copy leaderStatus fields into sealStatusOutput for display later
|
||||
sealStatusOutput.HAEnabled = leaderStatus.HAEnabled
|
||||
sealStatusOutput.IsSelf = leaderStatus.IsSelf
|
||||
sealStatusOutput.LeaderAddress = leaderStatus.LeaderAddress
|
||||
sealStatusOutput.LeaderClusterAddress = leaderStatus.LeaderClusterAddress
|
||||
sealStatusOutput.PerfStandby = leaderStatus.PerfStandby
|
||||
sealStatusOutput.PerfStandbyLastRemoteWAL = leaderStatus.PerfStandbyLastRemoteWAL
|
||||
sealStatusOutput.LastWAL = leaderStatus.LastWAL
|
||||
sealStatusOutput.RaftCommittedIndex = leaderStatus.RaftCommittedIndex
|
||||
sealStatusOutput.RaftAppliedIndex = leaderStatus.RaftAppliedIndex
|
||||
OutputData(ui, sealStatusOutput)
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -408,3 +425,19 @@ func looksLikeDuration(k string) bool {
|
||||
k == "duration" || strings.HasSuffix(k, "_duration") ||
|
||||
k == "lease_max" || k == "ttl_max"
|
||||
}
|
||||
|
||||
// This struct is responsible for capturing all the fields to be output by a
|
||||
// vault status command, including fields that do not come from the status API.
|
||||
// Currently we are adding the fields from api.LeaderResponse
|
||||
type SealStatusOutput struct {
|
||||
api.SealStatusResponse
|
||||
HAEnabled bool `json:"ha_enabled"`
|
||||
IsSelf bool `json:"is_self,omitempty""`
|
||||
LeaderAddress string `json:"leader_address,omitempty"`
|
||||
LeaderClusterAddress string `json:"leader_cluster_address,omitempty"`
|
||||
PerfStandby bool `json:"performance_standby,omitempty"`
|
||||
PerfStandbyLastRemoteWAL uint64 `json:"performance_standby_last_remote_wal,omitempty"`
|
||||
LastWAL uint64 `json:"last_wal,omitempty"`
|
||||
RaftCommittedIndex uint64 `json:"raft_committed_index,omitempty"`
|
||||
RaftAppliedIndex uint64 `json:"raft_applied_index,omitempty"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user