open-vault/command/format.go

726 lines
24 KiB
Go
Raw Normal View History

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package command
import (
Autopilot: Server Stabilization, State and Dead Server Cleanup (#10856) * k8s doc: update for 0.9.1 and 0.8.0 releases (#10825) * k8s doc: update for 0.9.1 and 0.8.0 releases * Update website/content/docs/platform/k8s/helm/configuration.mdx Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> * Autopilot initial commit * Move autopilot related backend implementations to its own file * Abstract promoter creation * Add nil check for health * Add server state oss no-ops * Config ext stub for oss * Make way for non-voters * s/health/state * s/ReadReplica/NonVoter * Add synopsis and description * Remove struct tags from AutopilotConfig * Use var for config storage path * Handle nin-config when reading * Enable testing autopilot by using inmem cluster * First passing test * Only report the server as known if it is present in raft config * Autopilot defaults to on for all existing and new clusters * Add locking to some functions * Persist initial config * Clarify the command usage doc * Add health metric for each node * Fix audit logging issue * Don't set DisablePerformanceStandby to true in test * Use node id label for health metric * Log updates to autopilot config * Less aggressively consume config loading failures * Return a mutable config * Return early from known servers if raft config is unable to be pulled * Update metrics name * Reduce log level for potentially noisy log * Add knob to disable autopilot * Don't persist if default config is in use * Autopilot: Dead server cleanup (#10857) * Dead server cleanup * Initialize channel in any case * Fix a bunch of tests * Fix panic * Add follower locking in heartbeat tracker * Add LastContactFailureThreshold to config * Add log when marking node as dead * Update follower state locking in heartbeat tracker * Avoid follower states being nil * Pull test to its own file * Add execution status to state response * Optionally enable autopilot in some tests * Updates * Added API function to fetch autopilot configuration * Add test for default autopilot configuration * Configuration tests * Add State API test * Update test * Added TestClusterOptions.PhysicalFactoryConfig * Update locking * Adjust locking in heartbeat tracker * s/last_contact_failure_threshold/left_server_last_contact_threshold * Add disabling autopilot as a core config option * Disable autopilot in some tests * s/left_server_last_contact_threshold/dead_server_last_contact_threshold * Set the lastheartbeat of followers to now when setting up active node * Don't use config defaults from CLI command * Remove config file support * Remove HCL test as well * Persist only supplied config; merge supplied config with default to operate * Use pointer to structs for storing follower information * Test update * Retrieve non voter status from configbucket and set it up when a node comes up * Manage desired suffrage * Consider bucket being created already * Move desired suffrage to its own entry * s/DesiredSuffrageKey/LocalNodeConfigKey * s/witnessSuffrage/recordSuffrage * Fix test compilation * Handle local node config post a snapshot install * Commit to storage first; then record suffrage in fsm * No need of local node config being nili case, post snapshot restore * Reconcile autopilot config when a new leader takes over duty * Grab fsm lock when recording suffrage * s/Suffrage/DesiredSuffrage in FollowerState * Instantiate autopilot only in leader * Default to old ways in more scenarios * Make API gracefully handle 404 * Address some feedback * Make IsDead an atomic.Value * Simplify follower hearbeat tracking * Use uber.atomic * Don't have multiple causes for having autopilot disabled * Don't remove node from follower states if we fail to remove the dead server * Autopilot server removals map (#11019) * Don't remove node from follower states if we fail to remove the dead server * Use map to track dead server removals * Use lock and map * Use delegate lock * Adjust when to remove entry from map * Only hold the lock while accessing map * Fix race * Don't set default min_quorum * Fix test * Ensure follower states is not nil before starting autopilot * Fix race Co-authored-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com>
2021-03-03 18:59:50 +00:00
"bytes"
"encoding/json"
"errors"
"fmt"
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
"os"
"sort"
"strings"
"time"
"github.com/ghodss/yaml"
"github.com/hashicorp/vault/api"
"github.com/mitchellh/cli"
"github.com/ryanuber/columnize"
)
2017-09-08 02:04:48 +00:00
const (
// hopeDelim is the delimiter to use when splitting columns. We call it a
// hopeDelim because we hope that it's never contained in a secret.
hopeDelim = "♨"
)
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
type FormatOptions struct {
Format string
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
func OutputSecret(ui cli.Ui, secret *api.Secret) int {
return outputWithFormat(ui, secret, secret)
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
func OutputList(ui cli.Ui, data interface{}) int {
switch data := data.(type) {
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
case *api.Secret:
secret := data
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
return outputWithFormat(ui, secret, secret.Data["keys"])
default:
return outputWithFormat(ui, nil, data)
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
}
func OutputData(ui cli.Ui, data interface{}) int {
return outputWithFormat(ui, nil, data)
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
func outputWithFormat(ui cli.Ui, secret *api.Secret, data interface{}) int {
format := Format(ui)
formatter, ok := Formatters[format]
if !ok {
2016-01-14 19:18:27 +00:00
ui.Error(fmt.Sprintf("Invalid output format: %s", format))
return 1
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
if err := formatter.Output(ui, secret, data); err != nil {
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
ui.Error(fmt.Sprintf("Could not parse output: %s", err.Error()))
return 1
}
return 0
}
type Formatter interface {
Output(ui cli.Ui, secret *api.Secret, data interface{}) error
Format(data interface{}) ([]byte, error)
}
var Formatters = map[string]Formatter{
Autopilot: Server Stabilization, State and Dead Server Cleanup (#10856) * k8s doc: update for 0.9.1 and 0.8.0 releases (#10825) * k8s doc: update for 0.9.1 and 0.8.0 releases * Update website/content/docs/platform/k8s/helm/configuration.mdx Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> * Autopilot initial commit * Move autopilot related backend implementations to its own file * Abstract promoter creation * Add nil check for health * Add server state oss no-ops * Config ext stub for oss * Make way for non-voters * s/health/state * s/ReadReplica/NonVoter * Add synopsis and description * Remove struct tags from AutopilotConfig * Use var for config storage path * Handle nin-config when reading * Enable testing autopilot by using inmem cluster * First passing test * Only report the server as known if it is present in raft config * Autopilot defaults to on for all existing and new clusters * Add locking to some functions * Persist initial config * Clarify the command usage doc * Add health metric for each node * Fix audit logging issue * Don't set DisablePerformanceStandby to true in test * Use node id label for health metric * Log updates to autopilot config * Less aggressively consume config loading failures * Return a mutable config * Return early from known servers if raft config is unable to be pulled * Update metrics name * Reduce log level for potentially noisy log * Add knob to disable autopilot * Don't persist if default config is in use * Autopilot: Dead server cleanup (#10857) * Dead server cleanup * Initialize channel in any case * Fix a bunch of tests * Fix panic * Add follower locking in heartbeat tracker * Add LastContactFailureThreshold to config * Add log when marking node as dead * Update follower state locking in heartbeat tracker * Avoid follower states being nil * Pull test to its own file * Add execution status to state response * Optionally enable autopilot in some tests * Updates * Added API function to fetch autopilot configuration * Add test for default autopilot configuration * Configuration tests * Add State API test * Update test * Added TestClusterOptions.PhysicalFactoryConfig * Update locking * Adjust locking in heartbeat tracker * s/last_contact_failure_threshold/left_server_last_contact_threshold * Add disabling autopilot as a core config option * Disable autopilot in some tests * s/left_server_last_contact_threshold/dead_server_last_contact_threshold * Set the lastheartbeat of followers to now when setting up active node * Don't use config defaults from CLI command * Remove config file support * Remove HCL test as well * Persist only supplied config; merge supplied config with default to operate * Use pointer to structs for storing follower information * Test update * Retrieve non voter status from configbucket and set it up when a node comes up * Manage desired suffrage * Consider bucket being created already * Move desired suffrage to its own entry * s/DesiredSuffrageKey/LocalNodeConfigKey * s/witnessSuffrage/recordSuffrage * Fix test compilation * Handle local node config post a snapshot install * Commit to storage first; then record suffrage in fsm * No need of local node config being nili case, post snapshot restore * Reconcile autopilot config when a new leader takes over duty * Grab fsm lock when recording suffrage * s/Suffrage/DesiredSuffrage in FollowerState * Instantiate autopilot only in leader * Default to old ways in more scenarios * Make API gracefully handle 404 * Address some feedback * Make IsDead an atomic.Value * Simplify follower hearbeat tracking * Use uber.atomic * Don't have multiple causes for having autopilot disabled * Don't remove node from follower states if we fail to remove the dead server * Autopilot server removals map (#11019) * Don't remove node from follower states if we fail to remove the dead server * Use map to track dead server removals * Use lock and map * Use delegate lock * Adjust when to remove entry from map * Only hold the lock while accessing map * Fix race * Don't set default min_quorum * Fix test * Ensure follower states is not nil before starting autopilot * Fix race Co-authored-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com>
2021-03-03 18:59:50 +00:00
"json": JsonFormatter{},
"table": TableFormatter{},
"yaml": YamlFormatter{},
"yml": YamlFormatter{},
"pretty": PrettyFormatter{},
Vault Raw Read Support (CLI & Client) (#14945) * Expose raw request from client.Logical() Not all Vault API endpoints return well-formatted JSON objects. Sometimes, in the case of the PKI secrets engine, they're not even printable (/pki/ca returns a binary (DER-encoded) certificate). While this endpoint isn't authenticated, in general the API caller would either need to use Client.RawRequestWithContext(...) directly (which the docs advise against), or setup their own net/http client and re-create much of Client and/or Client.Logical. Instead, exposing the raw Request (via the new ReadRawWithData(...)) allows callers to directly consume these non-JSON endpoints like they would nearly any other endpoint. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add raw formatter for direct []byte data As mentioned in the previous commit, some API endpoints return non-JSON data. We get as far as fetching this data (via client.Logical().Read), but parsing it as an api.Secret fails (as in this case, it is non-JSON). Given that we intend to update `vault read` to support such endpoints, we'll need a "raw" formatter that accepts []byte-encoded data and simply writes it to the UI. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add support for reading raw API endpoints Some endpoints, such as `pki/ca` and `pki/ca/pem` return non-JSON objects. When calling `vault read` on these endpoints, an error is returned because they cannot be parsed as api.Secret instances: > Error reading pki/ca/pem: invalid character '-' in numeric literal Indeed, we go to all the trouble of (successfully) fetching this value, only to be unable to Unmarshal into a Secrets value. Instead, add support for a new -format=raw option, allowing these endpoints to be consumed by callers of `vault read` directly. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog entry Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Remove panic Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-10-28 13:45:32 +00:00
"raw": RawFormatter{},
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
func Format(ui cli.Ui) string {
switch ui := ui.(type) {
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
case *VaultUI:
return ui.format
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
}
format := os.Getenv(EnvVaultFormat)
if format == "" {
format = "table"
}
return format
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
}
Vault CLI: show detailed information with ListResponseWithInfo (#15417) * CLI: Add ability to display ListResponseWithInfos The Vault Server API includes a ListResponseWithInfo call, allowing LIST responses to contain additional information about their keys. This is in a key=value mapping format (both for each key, to get the additional metadata, as well as within each metadata). Expand the `vault list` CLI command with a `-detailed` flag (and env var VAULT_DETAILED_LISTS) to print this additional metadata. This looks roughly like the following: $ vault list -detailed pki/issuers Keys issuer_name ---- ----------- 0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7 n/a 35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0 n/a 382fad1e-e99c-9c54-e147-bb1faa8033d3 n/a 8bb4a793-2ad9-460c-9fa8-574c84a981f7 n/a 8bd231d7-20e2-f21f-ae1a-7aa3319715e7 n/a 9425d51f-cb81-426d-d6ad-5147d092094e n/a ae679732-b497-ab0d-3220-806a2b9d81ed n/a c5a44a1f-2ae4-2140-3acf-74b2609448cc utf8 d41d2419-efce-0e36-c96b-e91179a24dc1 something Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Allow detailed printing of LIST responses in JSON When using the JSON formatter, only the absolute list of keys were returned. Reuse the `-detailed` flag value for the `-format=json` list response printer, allowing us to show the complete API response returned by Vault. This returns something like the following: { "request_id": "e9a25dcd-b67a-97d7-0f08-3670918ef3ff", "lease_id": "", "lease_duration": 0, "renewable": false, "data": { "key_info": { "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7": { "issuer_name": "" }, "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0": { "issuer_name": "" }, "382fad1e-e99c-9c54-e147-bb1faa8033d3": { "issuer_name": "" }, "8bb4a793-2ad9-460c-9fa8-574c84a981f7": { "issuer_name": "" }, "8bd231d7-20e2-f21f-ae1a-7aa3319715e7": { "issuer_name": "" }, "9425d51f-cb81-426d-d6ad-5147d092094e": { "issuer_name": "" }, "ae679732-b497-ab0d-3220-806a2b9d81ed": { "issuer_name": "" }, "c5a44a1f-2ae4-2140-3acf-74b2609448cc": { "issuer_name": "utf8" }, "d41d2419-efce-0e36-c96b-e91179a24dc1": { "issuer_name": "something" } }, "keys": [ "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7", "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0", "382fad1e-e99c-9c54-e147-bb1faa8033d3", "8bb4a793-2ad9-460c-9fa8-574c84a981f7", "8bd231d7-20e2-f21f-ae1a-7aa3319715e7", "9425d51f-cb81-426d-d6ad-5147d092094e", "ae679732-b497-ab0d-3220-806a2b9d81ed", "c5a44a1f-2ae4-2140-3acf-74b2609448cc", "d41d2419-efce-0e36-c96b-e91179a24dc1" ] }, "warnings": null } Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use field on UI rather than secret.Data Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Only include headers from visitable key_infos Certain API endpoints return data from non-visitable key_infos, by virtue of using a hand-rolled response. Limit our headers to those from visitable key_infos. This means we won't return entire columns with n/a entries, if no key matches the key_info key that includes that header. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use setupEnv sourced detailed info Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix changelog environment variable Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix broken tests using setupEnv Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-05-18 17:00:50 +00:00
func Detailed(ui cli.Ui) bool {
switch ui := ui.(type) {
case *VaultUI:
return ui.detailed
}
return false
}
// An output formatter for json output of an object
2017-08-28 20:45:04 +00:00
type JsonFormatter struct{}
func (j JsonFormatter) Format(data interface{}) ([]byte, error) {
return json.MarshalIndent(data, "", " ")
}
func (j JsonFormatter) Output(ui cli.Ui, secret *api.Secret, data interface{}) error {
b, err := j.Format(data)
2017-08-28 20:45:04 +00:00
if err != nil {
return err
2016-01-14 19:18:27 +00:00
}
Vault CLI: show detailed information with ListResponseWithInfo (#15417) * CLI: Add ability to display ListResponseWithInfos The Vault Server API includes a ListResponseWithInfo call, allowing LIST responses to contain additional information about their keys. This is in a key=value mapping format (both for each key, to get the additional metadata, as well as within each metadata). Expand the `vault list` CLI command with a `-detailed` flag (and env var VAULT_DETAILED_LISTS) to print this additional metadata. This looks roughly like the following: $ vault list -detailed pki/issuers Keys issuer_name ---- ----------- 0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7 n/a 35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0 n/a 382fad1e-e99c-9c54-e147-bb1faa8033d3 n/a 8bb4a793-2ad9-460c-9fa8-574c84a981f7 n/a 8bd231d7-20e2-f21f-ae1a-7aa3319715e7 n/a 9425d51f-cb81-426d-d6ad-5147d092094e n/a ae679732-b497-ab0d-3220-806a2b9d81ed n/a c5a44a1f-2ae4-2140-3acf-74b2609448cc utf8 d41d2419-efce-0e36-c96b-e91179a24dc1 something Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Allow detailed printing of LIST responses in JSON When using the JSON formatter, only the absolute list of keys were returned. Reuse the `-detailed` flag value for the `-format=json` list response printer, allowing us to show the complete API response returned by Vault. This returns something like the following: { "request_id": "e9a25dcd-b67a-97d7-0f08-3670918ef3ff", "lease_id": "", "lease_duration": 0, "renewable": false, "data": { "key_info": { "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7": { "issuer_name": "" }, "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0": { "issuer_name": "" }, "382fad1e-e99c-9c54-e147-bb1faa8033d3": { "issuer_name": "" }, "8bb4a793-2ad9-460c-9fa8-574c84a981f7": { "issuer_name": "" }, "8bd231d7-20e2-f21f-ae1a-7aa3319715e7": { "issuer_name": "" }, "9425d51f-cb81-426d-d6ad-5147d092094e": { "issuer_name": "" }, "ae679732-b497-ab0d-3220-806a2b9d81ed": { "issuer_name": "" }, "c5a44a1f-2ae4-2140-3acf-74b2609448cc": { "issuer_name": "utf8" }, "d41d2419-efce-0e36-c96b-e91179a24dc1": { "issuer_name": "something" } }, "keys": [ "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7", "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0", "382fad1e-e99c-9c54-e147-bb1faa8033d3", "8bb4a793-2ad9-460c-9fa8-574c84a981f7", "8bd231d7-20e2-f21f-ae1a-7aa3319715e7", "9425d51f-cb81-426d-d6ad-5147d092094e", "ae679732-b497-ab0d-3220-806a2b9d81ed", "c5a44a1f-2ae4-2140-3acf-74b2609448cc", "d41d2419-efce-0e36-c96b-e91179a24dc1" ] }, "warnings": null } Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use field on UI rather than secret.Data Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Only include headers from visitable key_infos Certain API endpoints return data from non-visitable key_infos, by virtue of using a hand-rolled response. Limit our headers to those from visitable key_infos. This means we won't return entire columns with n/a entries, if no key matches the key_info key that includes that header. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use setupEnv sourced detailed info Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix changelog environment variable Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix broken tests using setupEnv Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-05-18 17:00:50 +00:00
if secret != nil {
shouldListWithInfo := Detailed(ui)
// Show the raw JSON of the LIST call, rather than only the
// list of keys.
if shouldListWithInfo {
b, err = j.Format(secret)
if err != nil {
return err
}
}
}
2017-08-28 20:45:04 +00:00
ui.Output(string(b))
return nil
}
2016-01-14 19:18:27 +00:00
Vault Raw Read Support (CLI & Client) (#14945) * Expose raw request from client.Logical() Not all Vault API endpoints return well-formatted JSON objects. Sometimes, in the case of the PKI secrets engine, they're not even printable (/pki/ca returns a binary (DER-encoded) certificate). While this endpoint isn't authenticated, in general the API caller would either need to use Client.RawRequestWithContext(...) directly (which the docs advise against), or setup their own net/http client and re-create much of Client and/or Client.Logical. Instead, exposing the raw Request (via the new ReadRawWithData(...)) allows callers to directly consume these non-JSON endpoints like they would nearly any other endpoint. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add raw formatter for direct []byte data As mentioned in the previous commit, some API endpoints return non-JSON data. We get as far as fetching this data (via client.Logical().Read), but parsing it as an api.Secret fails (as in this case, it is non-JSON). Given that we intend to update `vault read` to support such endpoints, we'll need a "raw" formatter that accepts []byte-encoded data and simply writes it to the UI. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add support for reading raw API endpoints Some endpoints, such as `pki/ca` and `pki/ca/pem` return non-JSON objects. When calling `vault read` on these endpoints, an error is returned because they cannot be parsed as api.Secret instances: > Error reading pki/ca/pem: invalid character '-' in numeric literal Indeed, we go to all the trouble of (successfully) fetching this value, only to be unable to Unmarshal into a Secrets value. Instead, add support for a new -format=raw option, allowing these endpoints to be consumed by callers of `vault read` directly. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog entry Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Remove panic Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-10-28 13:45:32 +00:00
// An output formatter for raw output of the original request object
type RawFormatter struct{}
func (r RawFormatter) Format(data interface{}) ([]byte, error) {
byte_data, ok := data.([]byte)
if !ok {
return nil, fmt.Errorf("This command does not support the -format=raw option; only `vault read` does.")
Vault Raw Read Support (CLI & Client) (#14945) * Expose raw request from client.Logical() Not all Vault API endpoints return well-formatted JSON objects. Sometimes, in the case of the PKI secrets engine, they're not even printable (/pki/ca returns a binary (DER-encoded) certificate). While this endpoint isn't authenticated, in general the API caller would either need to use Client.RawRequestWithContext(...) directly (which the docs advise against), or setup their own net/http client and re-create much of Client and/or Client.Logical. Instead, exposing the raw Request (via the new ReadRawWithData(...)) allows callers to directly consume these non-JSON endpoints like they would nearly any other endpoint. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add raw formatter for direct []byte data As mentioned in the previous commit, some API endpoints return non-JSON data. We get as far as fetching this data (via client.Logical().Read), but parsing it as an api.Secret fails (as in this case, it is non-JSON). Given that we intend to update `vault read` to support such endpoints, we'll need a "raw" formatter that accepts []byte-encoded data and simply writes it to the UI. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add support for reading raw API endpoints Some endpoints, such as `pki/ca` and `pki/ca/pem` return non-JSON objects. When calling `vault read` on these endpoints, an error is returned because they cannot be parsed as api.Secret instances: > Error reading pki/ca/pem: invalid character '-' in numeric literal Indeed, we go to all the trouble of (successfully) fetching this value, only to be unable to Unmarshal into a Secrets value. Instead, add support for a new -format=raw option, allowing these endpoints to be consumed by callers of `vault read` directly. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog entry Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Remove panic Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-10-28 13:45:32 +00:00
}
return byte_data, nil
}
func (r RawFormatter) Output(ui cli.Ui, secret *api.Secret, data interface{}) error {
b, err := r.Format(data)
if err != nil {
return err
}
ui.Output(string(b))
return nil
}
// An output formatter for yaml output format of an object
type YamlFormatter struct{}
2016-01-14 19:18:27 +00:00
func (y YamlFormatter) Format(data interface{}) ([]byte, error) {
return yaml.Marshal(data)
}
func (y YamlFormatter) Output(ui cli.Ui, secret *api.Secret, data interface{}) error {
b, err := y.Format(data)
if err == nil {
ui.Output(strings.TrimSpace(string(b)))
}
return err
}
Autopilot: Server Stabilization, State and Dead Server Cleanup (#10856) * k8s doc: update for 0.9.1 and 0.8.0 releases (#10825) * k8s doc: update for 0.9.1 and 0.8.0 releases * Update website/content/docs/platform/k8s/helm/configuration.mdx Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> * Autopilot initial commit * Move autopilot related backend implementations to its own file * Abstract promoter creation * Add nil check for health * Add server state oss no-ops * Config ext stub for oss * Make way for non-voters * s/health/state * s/ReadReplica/NonVoter * Add synopsis and description * Remove struct tags from AutopilotConfig * Use var for config storage path * Handle nin-config when reading * Enable testing autopilot by using inmem cluster * First passing test * Only report the server as known if it is present in raft config * Autopilot defaults to on for all existing and new clusters * Add locking to some functions * Persist initial config * Clarify the command usage doc * Add health metric for each node * Fix audit logging issue * Don't set DisablePerformanceStandby to true in test * Use node id label for health metric * Log updates to autopilot config * Less aggressively consume config loading failures * Return a mutable config * Return early from known servers if raft config is unable to be pulled * Update metrics name * Reduce log level for potentially noisy log * Add knob to disable autopilot * Don't persist if default config is in use * Autopilot: Dead server cleanup (#10857) * Dead server cleanup * Initialize channel in any case * Fix a bunch of tests * Fix panic * Add follower locking in heartbeat tracker * Add LastContactFailureThreshold to config * Add log when marking node as dead * Update follower state locking in heartbeat tracker * Avoid follower states being nil * Pull test to its own file * Add execution status to state response * Optionally enable autopilot in some tests * Updates * Added API function to fetch autopilot configuration * Add test for default autopilot configuration * Configuration tests * Add State API test * Update test * Added TestClusterOptions.PhysicalFactoryConfig * Update locking * Adjust locking in heartbeat tracker * s/last_contact_failure_threshold/left_server_last_contact_threshold * Add disabling autopilot as a core config option * Disable autopilot in some tests * s/left_server_last_contact_threshold/dead_server_last_contact_threshold * Set the lastheartbeat of followers to now when setting up active node * Don't use config defaults from CLI command * Remove config file support * Remove HCL test as well * Persist only supplied config; merge supplied config with default to operate * Use pointer to structs for storing follower information * Test update * Retrieve non voter status from configbucket and set it up when a node comes up * Manage desired suffrage * Consider bucket being created already * Move desired suffrage to its own entry * s/DesiredSuffrageKey/LocalNodeConfigKey * s/witnessSuffrage/recordSuffrage * Fix test compilation * Handle local node config post a snapshot install * Commit to storage first; then record suffrage in fsm * No need of local node config being nili case, post snapshot restore * Reconcile autopilot config when a new leader takes over duty * Grab fsm lock when recording suffrage * s/Suffrage/DesiredSuffrage in FollowerState * Instantiate autopilot only in leader * Default to old ways in more scenarios * Make API gracefully handle 404 * Address some feedback * Make IsDead an atomic.Value * Simplify follower hearbeat tracking * Use uber.atomic * Don't have multiple causes for having autopilot disabled * Don't remove node from follower states if we fail to remove the dead server * Autopilot server removals map (#11019) * Don't remove node from follower states if we fail to remove the dead server * Use map to track dead server removals * Use lock and map * Use delegate lock * Adjust when to remove entry from map * Only hold the lock while accessing map * Fix race * Don't set default min_quorum * Fix test * Ensure follower states is not nil before starting autopilot * Fix race Co-authored-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com>
2021-03-03 18:59:50 +00:00
type PrettyFormatter struct{}
func (p PrettyFormatter) Format(data interface{}) ([]byte, error) {
return nil, nil
}
func (p PrettyFormatter) Output(ui cli.Ui, secret *api.Secret, data interface{}) error {
switch data.(type) {
case *api.AutopilotState:
p.OutputAutopilotState(ui, data)
default:
return errors.New("cannot use the pretty formatter for this type")
}
return nil
}
func outputStringSlice(buffer *bytes.Buffer, indent string, values []string) {
for _, val := range values {
buffer.WriteString(fmt.Sprintf("%s%s\n", indent, val))
}
}
type mapOutput struct {
key string
value string
}
func formatServer(srv *api.AutopilotServer) string {
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf(" %s\n", srv.ID))
buffer.WriteString(fmt.Sprintf(" Name: %s\n", srv.Name))
buffer.WriteString(fmt.Sprintf(" Address: %s\n", srv.Address))
buffer.WriteString(fmt.Sprintf(" Status: %s\n", srv.Status))
buffer.WriteString(fmt.Sprintf(" Node Status: %s\n", srv.NodeStatus))
buffer.WriteString(fmt.Sprintf(" Healthy: %t\n", srv.Healthy))
buffer.WriteString(fmt.Sprintf(" Last Contact: %s\n", srv.LastContact))
buffer.WriteString(fmt.Sprintf(" Last Term: %d\n", srv.LastTerm))
buffer.WriteString(fmt.Sprintf(" Last Index: %d\n", srv.LastIndex))
buffer.WriteString(fmt.Sprintf(" Version: %s\n", srv.Version))
if srv.UpgradeVersion != "" {
buffer.WriteString(fmt.Sprintf(" Upgrade Version: %s\n", srv.UpgradeVersion))
}
if srv.RedundancyZone != "" {
buffer.WriteString(fmt.Sprintf(" Redundancy Zone: %s\n", srv.RedundancyZone))
}
if srv.NodeType != "" {
buffer.WriteString(fmt.Sprintf(" Node Type: %s\n", srv.NodeType))
Autopilot: Server Stabilization, State and Dead Server Cleanup (#10856) * k8s doc: update for 0.9.1 and 0.8.0 releases (#10825) * k8s doc: update for 0.9.1 and 0.8.0 releases * Update website/content/docs/platform/k8s/helm/configuration.mdx Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> * Autopilot initial commit * Move autopilot related backend implementations to its own file * Abstract promoter creation * Add nil check for health * Add server state oss no-ops * Config ext stub for oss * Make way for non-voters * s/health/state * s/ReadReplica/NonVoter * Add synopsis and description * Remove struct tags from AutopilotConfig * Use var for config storage path * Handle nin-config when reading * Enable testing autopilot by using inmem cluster * First passing test * Only report the server as known if it is present in raft config * Autopilot defaults to on for all existing and new clusters * Add locking to some functions * Persist initial config * Clarify the command usage doc * Add health metric for each node * Fix audit logging issue * Don't set DisablePerformanceStandby to true in test * Use node id label for health metric * Log updates to autopilot config * Less aggressively consume config loading failures * Return a mutable config * Return early from known servers if raft config is unable to be pulled * Update metrics name * Reduce log level for potentially noisy log * Add knob to disable autopilot * Don't persist if default config is in use * Autopilot: Dead server cleanup (#10857) * Dead server cleanup * Initialize channel in any case * Fix a bunch of tests * Fix panic * Add follower locking in heartbeat tracker * Add LastContactFailureThreshold to config * Add log when marking node as dead * Update follower state locking in heartbeat tracker * Avoid follower states being nil * Pull test to its own file * Add execution status to state response * Optionally enable autopilot in some tests * Updates * Added API function to fetch autopilot configuration * Add test for default autopilot configuration * Configuration tests * Add State API test * Update test * Added TestClusterOptions.PhysicalFactoryConfig * Update locking * Adjust locking in heartbeat tracker * s/last_contact_failure_threshold/left_server_last_contact_threshold * Add disabling autopilot as a core config option * Disable autopilot in some tests * s/left_server_last_contact_threshold/dead_server_last_contact_threshold * Set the lastheartbeat of followers to now when setting up active node * Don't use config defaults from CLI command * Remove config file support * Remove HCL test as well * Persist only supplied config; merge supplied config with default to operate * Use pointer to structs for storing follower information * Test update * Retrieve non voter status from configbucket and set it up when a node comes up * Manage desired suffrage * Consider bucket being created already * Move desired suffrage to its own entry * s/DesiredSuffrageKey/LocalNodeConfigKey * s/witnessSuffrage/recordSuffrage * Fix test compilation * Handle local node config post a snapshot install * Commit to storage first; then record suffrage in fsm * No need of local node config being nili case, post snapshot restore * Reconcile autopilot config when a new leader takes over duty * Grab fsm lock when recording suffrage * s/Suffrage/DesiredSuffrage in FollowerState * Instantiate autopilot only in leader * Default to old ways in more scenarios * Make API gracefully handle 404 * Address some feedback * Make IsDead an atomic.Value * Simplify follower hearbeat tracking * Use uber.atomic * Don't have multiple causes for having autopilot disabled * Don't remove node from follower states if we fail to remove the dead server * Autopilot server removals map (#11019) * Don't remove node from follower states if we fail to remove the dead server * Use map to track dead server removals * Use lock and map * Use delegate lock * Adjust when to remove entry from map * Only hold the lock while accessing map * Fix race * Don't set default min_quorum * Fix test * Ensure follower states is not nil before starting autopilot * Fix race Co-authored-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com>
2021-03-03 18:59:50 +00:00
}
return buffer.String()
}
func (p PrettyFormatter) OutputAutopilotState(ui cli.Ui, data interface{}) {
state := data.(*api.AutopilotState)
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf("Healthy: %t\n", state.Healthy))
buffer.WriteString(fmt.Sprintf("Failure Tolerance: %d\n", state.FailureTolerance))
buffer.WriteString(fmt.Sprintf("Leader: %s\n", state.Leader))
Autopilot: Server Stabilization, State and Dead Server Cleanup (#10856) * k8s doc: update for 0.9.1 and 0.8.0 releases (#10825) * k8s doc: update for 0.9.1 and 0.8.0 releases * Update website/content/docs/platform/k8s/helm/configuration.mdx Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> * Autopilot initial commit * Move autopilot related backend implementations to its own file * Abstract promoter creation * Add nil check for health * Add server state oss no-ops * Config ext stub for oss * Make way for non-voters * s/health/state * s/ReadReplica/NonVoter * Add synopsis and description * Remove struct tags from AutopilotConfig * Use var for config storage path * Handle nin-config when reading * Enable testing autopilot by using inmem cluster * First passing test * Only report the server as known if it is present in raft config * Autopilot defaults to on for all existing and new clusters * Add locking to some functions * Persist initial config * Clarify the command usage doc * Add health metric for each node * Fix audit logging issue * Don't set DisablePerformanceStandby to true in test * Use node id label for health metric * Log updates to autopilot config * Less aggressively consume config loading failures * Return a mutable config * Return early from known servers if raft config is unable to be pulled * Update metrics name * Reduce log level for potentially noisy log * Add knob to disable autopilot * Don't persist if default config is in use * Autopilot: Dead server cleanup (#10857) * Dead server cleanup * Initialize channel in any case * Fix a bunch of tests * Fix panic * Add follower locking in heartbeat tracker * Add LastContactFailureThreshold to config * Add log when marking node as dead * Update follower state locking in heartbeat tracker * Avoid follower states being nil * Pull test to its own file * Add execution status to state response * Optionally enable autopilot in some tests * Updates * Added API function to fetch autopilot configuration * Add test for default autopilot configuration * Configuration tests * Add State API test * Update test * Added TestClusterOptions.PhysicalFactoryConfig * Update locking * Adjust locking in heartbeat tracker * s/last_contact_failure_threshold/left_server_last_contact_threshold * Add disabling autopilot as a core config option * Disable autopilot in some tests * s/left_server_last_contact_threshold/dead_server_last_contact_threshold * Set the lastheartbeat of followers to now when setting up active node * Don't use config defaults from CLI command * Remove config file support * Remove HCL test as well * Persist only supplied config; merge supplied config with default to operate * Use pointer to structs for storing follower information * Test update * Retrieve non voter status from configbucket and set it up when a node comes up * Manage desired suffrage * Consider bucket being created already * Move desired suffrage to its own entry * s/DesiredSuffrageKey/LocalNodeConfigKey * s/witnessSuffrage/recordSuffrage * Fix test compilation * Handle local node config post a snapshot install * Commit to storage first; then record suffrage in fsm * No need of local node config being nili case, post snapshot restore * Reconcile autopilot config when a new leader takes over duty * Grab fsm lock when recording suffrage * s/Suffrage/DesiredSuffrage in FollowerState * Instantiate autopilot only in leader * Default to old ways in more scenarios * Make API gracefully handle 404 * Address some feedback * Make IsDead an atomic.Value * Simplify follower hearbeat tracking * Use uber.atomic * Don't have multiple causes for having autopilot disabled * Don't remove node from follower states if we fail to remove the dead server * Autopilot server removals map (#11019) * Don't remove node from follower states if we fail to remove the dead server * Use map to track dead server removals * Use lock and map * Use delegate lock * Adjust when to remove entry from map * Only hold the lock while accessing map * Fix race * Don't set default min_quorum * Fix test * Ensure follower states is not nil before starting autopilot * Fix race Co-authored-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com>
2021-03-03 18:59:50 +00:00
buffer.WriteString("Voters:\n")
outputStringSlice(&buffer, " ", state.Voters)
if len(state.NonVoters) > 0 {
buffer.WriteString("Non Voters:\n")
outputStringSlice(&buffer, " ", state.NonVoters)
}
if state.OptimisticFailureTolerance > 0 {
buffer.WriteString(fmt.Sprintf("Optimistic Failure Tolerance: %d\n", state.OptimisticFailureTolerance))
}
// Servers
Autopilot: Server Stabilization, State and Dead Server Cleanup (#10856) * k8s doc: update for 0.9.1 and 0.8.0 releases (#10825) * k8s doc: update for 0.9.1 and 0.8.0 releases * Update website/content/docs/platform/k8s/helm/configuration.mdx Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> * Autopilot initial commit * Move autopilot related backend implementations to its own file * Abstract promoter creation * Add nil check for health * Add server state oss no-ops * Config ext stub for oss * Make way for non-voters * s/health/state * s/ReadReplica/NonVoter * Add synopsis and description * Remove struct tags from AutopilotConfig * Use var for config storage path * Handle nin-config when reading * Enable testing autopilot by using inmem cluster * First passing test * Only report the server as known if it is present in raft config * Autopilot defaults to on for all existing and new clusters * Add locking to some functions * Persist initial config * Clarify the command usage doc * Add health metric for each node * Fix audit logging issue * Don't set DisablePerformanceStandby to true in test * Use node id label for health metric * Log updates to autopilot config * Less aggressively consume config loading failures * Return a mutable config * Return early from known servers if raft config is unable to be pulled * Update metrics name * Reduce log level for potentially noisy log * Add knob to disable autopilot * Don't persist if default config is in use * Autopilot: Dead server cleanup (#10857) * Dead server cleanup * Initialize channel in any case * Fix a bunch of tests * Fix panic * Add follower locking in heartbeat tracker * Add LastContactFailureThreshold to config * Add log when marking node as dead * Update follower state locking in heartbeat tracker * Avoid follower states being nil * Pull test to its own file * Add execution status to state response * Optionally enable autopilot in some tests * Updates * Added API function to fetch autopilot configuration * Add test for default autopilot configuration * Configuration tests * Add State API test * Update test * Added TestClusterOptions.PhysicalFactoryConfig * Update locking * Adjust locking in heartbeat tracker * s/last_contact_failure_threshold/left_server_last_contact_threshold * Add disabling autopilot as a core config option * Disable autopilot in some tests * s/left_server_last_contact_threshold/dead_server_last_contact_threshold * Set the lastheartbeat of followers to now when setting up active node * Don't use config defaults from CLI command * Remove config file support * Remove HCL test as well * Persist only supplied config; merge supplied config with default to operate * Use pointer to structs for storing follower information * Test update * Retrieve non voter status from configbucket and set it up when a node comes up * Manage desired suffrage * Consider bucket being created already * Move desired suffrage to its own entry * s/DesiredSuffrageKey/LocalNodeConfigKey * s/witnessSuffrage/recordSuffrage * Fix test compilation * Handle local node config post a snapshot install * Commit to storage first; then record suffrage in fsm * No need of local node config being nili case, post snapshot restore * Reconcile autopilot config when a new leader takes over duty * Grab fsm lock when recording suffrage * s/Suffrage/DesiredSuffrage in FollowerState * Instantiate autopilot only in leader * Default to old ways in more scenarios * Make API gracefully handle 404 * Address some feedback * Make IsDead an atomic.Value * Simplify follower hearbeat tracking * Use uber.atomic * Don't have multiple causes for having autopilot disabled * Don't remove node from follower states if we fail to remove the dead server * Autopilot server removals map (#11019) * Don't remove node from follower states if we fail to remove the dead server * Use map to track dead server removals * Use lock and map * Use delegate lock * Adjust when to remove entry from map * Only hold the lock while accessing map * Fix race * Don't set default min_quorum * Fix test * Ensure follower states is not nil before starting autopilot * Fix race Co-authored-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com>
2021-03-03 18:59:50 +00:00
buffer.WriteString("Servers:\n")
var outputs []mapOutput
for id, srv := range state.Servers {
outputs = append(outputs, mapOutput{key: id, value: formatServer(srv)})
}
sort.Slice(outputs, func(i, j int) bool {
return outputs[i].key < outputs[j].key
})
for _, output := range outputs {
buffer.WriteString(output.value)
}
// Redundancy Zones
if len(state.RedundancyZones) > 0 {
buffer.WriteString("Redundancy Zones:\n")
zoneList := make([]string, 0, len(state.RedundancyZones))
for z := range state.RedundancyZones {
zoneList = append(zoneList, z)
}
sort.Strings(zoneList)
for _, zoneName := range zoneList {
zone := state.RedundancyZones[zoneName]
servers := zone.Servers
voters := zone.Voters
sort.Strings(servers)
sort.Strings(voters)
buffer.WriteString(fmt.Sprintf(" %s\n", zoneName))
buffer.WriteString(fmt.Sprintf(" Servers: %s\n", strings.Join(servers, ", ")))
buffer.WriteString(fmt.Sprintf(" Voters: %s\n", strings.Join(voters, ", ")))
buffer.WriteString(fmt.Sprintf(" Failure Tolerance: %d\n", zone.FailureTolerance))
}
}
// Upgrade Info
if state.Upgrade != nil {
buffer.WriteString("Upgrade Info:\n")
buffer.WriteString(fmt.Sprintf(" Status: %s\n", state.Upgrade.Status))
buffer.WriteString(fmt.Sprintf(" Target Version: %s\n", state.Upgrade.TargetVersion))
buffer.WriteString(fmt.Sprintf(" Target Version Voters: %s\n", strings.Join(state.Upgrade.TargetVersionVoters, ", ")))
buffer.WriteString(fmt.Sprintf(" Target Version Non-Voters: %s\n", strings.Join(state.Upgrade.TargetVersionNonVoters, ", ")))
buffer.WriteString(fmt.Sprintf(" Other Version Voters: %s\n", strings.Join(state.Upgrade.OtherVersionVoters, ", ")))
buffer.WriteString(fmt.Sprintf(" Other Version Non-Voters: %s\n", strings.Join(state.Upgrade.OtherVersionNonVoters, ", ")))
if len(state.Upgrade.RedundancyZones) > 0 {
buffer.WriteString(" Redundancy Zones:\n")
for zoneName, zoneVersion := range state.Upgrade.RedundancyZones {
buffer.WriteString(fmt.Sprintf(" %s\n", zoneName))
buffer.WriteString(fmt.Sprintf(" Target Version Voters: %s\n", strings.Join(zoneVersion.TargetVersionVoters, ", ")))
buffer.WriteString(fmt.Sprintf(" Target Version Non-Voters: %s\n", strings.Join(zoneVersion.TargetVersionNonVoters, ", ")))
buffer.WriteString(fmt.Sprintf(" Other Version Voters: %s\n", strings.Join(zoneVersion.OtherVersionVoters, ", ")))
buffer.WriteString(fmt.Sprintf(" Other Version Non-Voters: %s\n", strings.Join(zoneVersion.OtherVersionNonVoters, ", ")))
}
}
}
Autopilot: Server Stabilization, State and Dead Server Cleanup (#10856) * k8s doc: update for 0.9.1 and 0.8.0 releases (#10825) * k8s doc: update for 0.9.1 and 0.8.0 releases * Update website/content/docs/platform/k8s/helm/configuration.mdx Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com> * Autopilot initial commit * Move autopilot related backend implementations to its own file * Abstract promoter creation * Add nil check for health * Add server state oss no-ops * Config ext stub for oss * Make way for non-voters * s/health/state * s/ReadReplica/NonVoter * Add synopsis and description * Remove struct tags from AutopilotConfig * Use var for config storage path * Handle nin-config when reading * Enable testing autopilot by using inmem cluster * First passing test * Only report the server as known if it is present in raft config * Autopilot defaults to on for all existing and new clusters * Add locking to some functions * Persist initial config * Clarify the command usage doc * Add health metric for each node * Fix audit logging issue * Don't set DisablePerformanceStandby to true in test * Use node id label for health metric * Log updates to autopilot config * Less aggressively consume config loading failures * Return a mutable config * Return early from known servers if raft config is unable to be pulled * Update metrics name * Reduce log level for potentially noisy log * Add knob to disable autopilot * Don't persist if default config is in use * Autopilot: Dead server cleanup (#10857) * Dead server cleanup * Initialize channel in any case * Fix a bunch of tests * Fix panic * Add follower locking in heartbeat tracker * Add LastContactFailureThreshold to config * Add log when marking node as dead * Update follower state locking in heartbeat tracker * Avoid follower states being nil * Pull test to its own file * Add execution status to state response * Optionally enable autopilot in some tests * Updates * Added API function to fetch autopilot configuration * Add test for default autopilot configuration * Configuration tests * Add State API test * Update test * Added TestClusterOptions.PhysicalFactoryConfig * Update locking * Adjust locking in heartbeat tracker * s/last_contact_failure_threshold/left_server_last_contact_threshold * Add disabling autopilot as a core config option * Disable autopilot in some tests * s/left_server_last_contact_threshold/dead_server_last_contact_threshold * Set the lastheartbeat of followers to now when setting up active node * Don't use config defaults from CLI command * Remove config file support * Remove HCL test as well * Persist only supplied config; merge supplied config with default to operate * Use pointer to structs for storing follower information * Test update * Retrieve non voter status from configbucket and set it up when a node comes up * Manage desired suffrage * Consider bucket being created already * Move desired suffrage to its own entry * s/DesiredSuffrageKey/LocalNodeConfigKey * s/witnessSuffrage/recordSuffrage * Fix test compilation * Handle local node config post a snapshot install * Commit to storage first; then record suffrage in fsm * No need of local node config being nili case, post snapshot restore * Reconcile autopilot config when a new leader takes over duty * Grab fsm lock when recording suffrage * s/Suffrage/DesiredSuffrage in FollowerState * Instantiate autopilot only in leader * Default to old ways in more scenarios * Make API gracefully handle 404 * Address some feedback * Make IsDead an atomic.Value * Simplify follower hearbeat tracking * Use uber.atomic * Don't have multiple causes for having autopilot disabled * Don't remove node from follower states if we fail to remove the dead server * Autopilot server removals map (#11019) * Don't remove node from follower states if we fail to remove the dead server * Use map to track dead server removals * Use lock and map * Use delegate lock * Adjust when to remove entry from map * Only hold the lock while accessing map * Fix race * Don't set default min_quorum * Fix test * Ensure follower states is not nil before starting autopilot * Fix race Co-authored-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com>
2021-03-03 18:59:50 +00:00
ui.Output(buffer.String())
}
// An output formatter for table output of an object
type TableFormatter struct{}
// 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
}
func (t TableFormatter) Output(ui cli.Ui, secret *api.Secret, data interface{}) error {
switch data := data.(type) {
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
case *api.Secret:
return t.OutputSecret(ui, secret)
case []interface{}:
return t.OutputList(ui, secret, data)
case []string:
return t.OutputList(ui, nil, data)
case map[string]interface{}:
return t.OutputMap(ui, data)
case SealStatusOutput:
return t.OutputSealStatusStruct(ui, nil, data)
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
default:
return errors.New("cannot use the table formatter for this type")
}
}
2016-01-14 19:18:27 +00:00
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("Build Date | %s", status.BuildDate))
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 HCP link is configured
if status.HCPLinkStatus != "" {
out = append(out, fmt.Sprintf("HCP Link Status | %s", status.HCPLinkStatus))
out = append(out, fmt.Sprintf("HCP Link Resource ID | %s", status.HCPLinkResourceID))
}
// 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))
if status.IsSelf && !status.ActiveTime.IsZero() {
out = append(out, fmt.Sprintf("Active Since | %s", status.ActiveTime.Format(time.RFC3339Nano)))
}
// 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))
}
if len(status.Warnings) > 0 {
out = append(out, fmt.Sprintf("Warnings | %v", status.Warnings))
}
ui.Output(tableOutput(out, &columnize.Config{
Delim: "|",
}))
return nil
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
func (t TableFormatter) OutputList(ui cli.Ui, secret *api.Secret, data interface{}) error {
2017-09-08 02:04:48 +00:00
t.printWarnings(ui, secret)
Vault CLI: show detailed information with ListResponseWithInfo (#15417) * CLI: Add ability to display ListResponseWithInfos The Vault Server API includes a ListResponseWithInfo call, allowing LIST responses to contain additional information about their keys. This is in a key=value mapping format (both for each key, to get the additional metadata, as well as within each metadata). Expand the `vault list` CLI command with a `-detailed` flag (and env var VAULT_DETAILED_LISTS) to print this additional metadata. This looks roughly like the following: $ vault list -detailed pki/issuers Keys issuer_name ---- ----------- 0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7 n/a 35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0 n/a 382fad1e-e99c-9c54-e147-bb1faa8033d3 n/a 8bb4a793-2ad9-460c-9fa8-574c84a981f7 n/a 8bd231d7-20e2-f21f-ae1a-7aa3319715e7 n/a 9425d51f-cb81-426d-d6ad-5147d092094e n/a ae679732-b497-ab0d-3220-806a2b9d81ed n/a c5a44a1f-2ae4-2140-3acf-74b2609448cc utf8 d41d2419-efce-0e36-c96b-e91179a24dc1 something Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Allow detailed printing of LIST responses in JSON When using the JSON formatter, only the absolute list of keys were returned. Reuse the `-detailed` flag value for the `-format=json` list response printer, allowing us to show the complete API response returned by Vault. This returns something like the following: { "request_id": "e9a25dcd-b67a-97d7-0f08-3670918ef3ff", "lease_id": "", "lease_duration": 0, "renewable": false, "data": { "key_info": { "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7": { "issuer_name": "" }, "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0": { "issuer_name": "" }, "382fad1e-e99c-9c54-e147-bb1faa8033d3": { "issuer_name": "" }, "8bb4a793-2ad9-460c-9fa8-574c84a981f7": { "issuer_name": "" }, "8bd231d7-20e2-f21f-ae1a-7aa3319715e7": { "issuer_name": "" }, "9425d51f-cb81-426d-d6ad-5147d092094e": { "issuer_name": "" }, "ae679732-b497-ab0d-3220-806a2b9d81ed": { "issuer_name": "" }, "c5a44a1f-2ae4-2140-3acf-74b2609448cc": { "issuer_name": "utf8" }, "d41d2419-efce-0e36-c96b-e91179a24dc1": { "issuer_name": "something" } }, "keys": [ "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7", "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0", "382fad1e-e99c-9c54-e147-bb1faa8033d3", "8bb4a793-2ad9-460c-9fa8-574c84a981f7", "8bd231d7-20e2-f21f-ae1a-7aa3319715e7", "9425d51f-cb81-426d-d6ad-5147d092094e", "ae679732-b497-ab0d-3220-806a2b9d81ed", "c5a44a1f-2ae4-2140-3acf-74b2609448cc", "d41d2419-efce-0e36-c96b-e91179a24dc1" ] }, "warnings": null } Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use field on UI rather than secret.Data Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Only include headers from visitable key_infos Certain API endpoints return data from non-visitable key_infos, by virtue of using a hand-rolled response. Limit our headers to those from visitable key_infos. This means we won't return entire columns with n/a entries, if no key matches the key_info key that includes that header. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use setupEnv sourced detailed info Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix changelog environment variable Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix broken tests using setupEnv Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-05-18 17:00:50 +00:00
// Determine if we have additional information from a ListResponseWithInfo endpoint.
var additionalInfo map[string]interface{}
if secret != nil {
shouldListWithInfo := Detailed(ui)
if additional, ok := secret.Data["key_info"]; shouldListWithInfo && ok && len(additional.(map[string]interface{})) > 0 {
additionalInfo = additional.(map[string]interface{})
}
}
switch data := data.(type) {
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
case []interface{}:
case []string:
ui.Output(tableOutput(data, nil))
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
return nil
default:
return errors.New("error: table formatter cannot output list for this data type")
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
}
list := data.([]interface{})
if len(list) > 0 {
2017-09-08 02:04:48 +00:00
keys := make([]string, len(list))
for i, v := range list {
typed, ok := v.(string)
if !ok {
return fmt.Errorf("%v is not a string", v)
2017-09-08 02:04:48 +00:00
}
keys[i] = typed
}
sort.Strings(keys)
Vault CLI: show detailed information with ListResponseWithInfo (#15417) * CLI: Add ability to display ListResponseWithInfos The Vault Server API includes a ListResponseWithInfo call, allowing LIST responses to contain additional information about their keys. This is in a key=value mapping format (both for each key, to get the additional metadata, as well as within each metadata). Expand the `vault list` CLI command with a `-detailed` flag (and env var VAULT_DETAILED_LISTS) to print this additional metadata. This looks roughly like the following: $ vault list -detailed pki/issuers Keys issuer_name ---- ----------- 0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7 n/a 35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0 n/a 382fad1e-e99c-9c54-e147-bb1faa8033d3 n/a 8bb4a793-2ad9-460c-9fa8-574c84a981f7 n/a 8bd231d7-20e2-f21f-ae1a-7aa3319715e7 n/a 9425d51f-cb81-426d-d6ad-5147d092094e n/a ae679732-b497-ab0d-3220-806a2b9d81ed n/a c5a44a1f-2ae4-2140-3acf-74b2609448cc utf8 d41d2419-efce-0e36-c96b-e91179a24dc1 something Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Allow detailed printing of LIST responses in JSON When using the JSON formatter, only the absolute list of keys were returned. Reuse the `-detailed` flag value for the `-format=json` list response printer, allowing us to show the complete API response returned by Vault. This returns something like the following: { "request_id": "e9a25dcd-b67a-97d7-0f08-3670918ef3ff", "lease_id": "", "lease_duration": 0, "renewable": false, "data": { "key_info": { "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7": { "issuer_name": "" }, "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0": { "issuer_name": "" }, "382fad1e-e99c-9c54-e147-bb1faa8033d3": { "issuer_name": "" }, "8bb4a793-2ad9-460c-9fa8-574c84a981f7": { "issuer_name": "" }, "8bd231d7-20e2-f21f-ae1a-7aa3319715e7": { "issuer_name": "" }, "9425d51f-cb81-426d-d6ad-5147d092094e": { "issuer_name": "" }, "ae679732-b497-ab0d-3220-806a2b9d81ed": { "issuer_name": "" }, "c5a44a1f-2ae4-2140-3acf-74b2609448cc": { "issuer_name": "utf8" }, "d41d2419-efce-0e36-c96b-e91179a24dc1": { "issuer_name": "something" } }, "keys": [ "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7", "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0", "382fad1e-e99c-9c54-e147-bb1faa8033d3", "8bb4a793-2ad9-460c-9fa8-574c84a981f7", "8bd231d7-20e2-f21f-ae1a-7aa3319715e7", "9425d51f-cb81-426d-d6ad-5147d092094e", "ae679732-b497-ab0d-3220-806a2b9d81ed", "c5a44a1f-2ae4-2140-3acf-74b2609448cc", "d41d2419-efce-0e36-c96b-e91179a24dc1" ] }, "warnings": null } Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use field on UI rather than secret.Data Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Only include headers from visitable key_infos Certain API endpoints return data from non-visitable key_infos, by virtue of using a hand-rolled response. Limit our headers to those from visitable key_infos. This means we won't return entire columns with n/a entries, if no key matches the key_info key that includes that header. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use setupEnv sourced detailed info Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix changelog environment variable Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix broken tests using setupEnv Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-05-18 17:00:50 +00:00
// If we have a ListResponseWithInfo endpoint, we'll need to show
// additional headers. To satisfy the table outputter, we'll need
// to concat them with the deliminator.
var headers []string
header := "Keys"
if len(additionalInfo) > 0 {
seenHeaders := make(map[string]bool)
for key, rawValues := range additionalInfo {
// Most endpoints use the well-behaved ListResponseWithInfo.
// However, some use a hand-rolled equivalent, where the
// returned "keys" doesn't match the key of the "key_info"
// member (namely, /sys/policies/egp). We seek to exclude
// headers only visible from "non-visitable" key_info rows,
// to make table output less confusing. These non-visitable
// rows will still be visible in the JSON output.
index := sort.SearchStrings(keys, key)
if index < len(keys) && keys[index] != key {
continue
}
values := rawValues.(map[string]interface{})
for key := range values {
seenHeaders[key] = true
}
}
for key := range seenHeaders {
headers = append(headers, key)
}
sort.Strings(headers)
header = header + hopeDelim + strings.Join(headers, hopeDelim)
}
// Finally, if we have a ListResponseWithInfo, we'll need to update
// the returned rows to not just have the keys (in the sorted order),
// but also have the values for each header (in their sorted order).
rows := keys
if len(additionalInfo) > 0 && len(headers) > 0 {
for index, row := range rows {
formatted := []string{row}
if rawValues, ok := additionalInfo[row]; ok {
values := rawValues.(map[string]interface{})
for _, header := range headers {
if rawValue, ok := values[header]; ok {
if looksLikeDuration(header) {
rawValue = humanDurationInt(rawValue)
}
formatted = append(formatted, fmt.Sprintf("%v", rawValue))
} else {
// Show a default empty n/a when this field is
// missing from the additional information.
formatted = append(formatted, "n/a")
}
}
}
rows[index] = strings.Join(formatted, hopeDelim)
}
}
2017-09-08 02:04:48 +00:00
Vault CLI: show detailed information with ListResponseWithInfo (#15417) * CLI: Add ability to display ListResponseWithInfos The Vault Server API includes a ListResponseWithInfo call, allowing LIST responses to contain additional information about their keys. This is in a key=value mapping format (both for each key, to get the additional metadata, as well as within each metadata). Expand the `vault list` CLI command with a `-detailed` flag (and env var VAULT_DETAILED_LISTS) to print this additional metadata. This looks roughly like the following: $ vault list -detailed pki/issuers Keys issuer_name ---- ----------- 0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7 n/a 35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0 n/a 382fad1e-e99c-9c54-e147-bb1faa8033d3 n/a 8bb4a793-2ad9-460c-9fa8-574c84a981f7 n/a 8bd231d7-20e2-f21f-ae1a-7aa3319715e7 n/a 9425d51f-cb81-426d-d6ad-5147d092094e n/a ae679732-b497-ab0d-3220-806a2b9d81ed n/a c5a44a1f-2ae4-2140-3acf-74b2609448cc utf8 d41d2419-efce-0e36-c96b-e91179a24dc1 something Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Allow detailed printing of LIST responses in JSON When using the JSON formatter, only the absolute list of keys were returned. Reuse the `-detailed` flag value for the `-format=json` list response printer, allowing us to show the complete API response returned by Vault. This returns something like the following: { "request_id": "e9a25dcd-b67a-97d7-0f08-3670918ef3ff", "lease_id": "", "lease_duration": 0, "renewable": false, "data": { "key_info": { "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7": { "issuer_name": "" }, "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0": { "issuer_name": "" }, "382fad1e-e99c-9c54-e147-bb1faa8033d3": { "issuer_name": "" }, "8bb4a793-2ad9-460c-9fa8-574c84a981f7": { "issuer_name": "" }, "8bd231d7-20e2-f21f-ae1a-7aa3319715e7": { "issuer_name": "" }, "9425d51f-cb81-426d-d6ad-5147d092094e": { "issuer_name": "" }, "ae679732-b497-ab0d-3220-806a2b9d81ed": { "issuer_name": "" }, "c5a44a1f-2ae4-2140-3acf-74b2609448cc": { "issuer_name": "utf8" }, "d41d2419-efce-0e36-c96b-e91179a24dc1": { "issuer_name": "something" } }, "keys": [ "0cba84d7-bbbe-836a-4ff6-a11b31dc0fb7", "35dfb02d-0cdb-3d35-ee64-d0cd6568c6b0", "382fad1e-e99c-9c54-e147-bb1faa8033d3", "8bb4a793-2ad9-460c-9fa8-574c84a981f7", "8bd231d7-20e2-f21f-ae1a-7aa3319715e7", "9425d51f-cb81-426d-d6ad-5147d092094e", "ae679732-b497-ab0d-3220-806a2b9d81ed", "c5a44a1f-2ae4-2140-3acf-74b2609448cc", "d41d2419-efce-0e36-c96b-e91179a24dc1" ] }, "warnings": null } Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use field on UI rather than secret.Data Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Only include headers from visitable key_infos Certain API endpoints return data from non-visitable key_infos, by virtue of using a hand-rolled response. Limit our headers to those from visitable key_infos. This means we won't return entire columns with n/a entries, if no key matches the key_info key that includes that header. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Use setupEnv sourced detailed info Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix changelog environment variable Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Fix broken tests using setupEnv Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
2022-05-18 17:00:50 +00:00
// Prepend the header to the formatted rows.
output := append([]string{header}, rows...)
ui.Output(tableOutput(output, &columnize.Config{
2017-09-08 02:04:48 +00:00
Delim: hopeDelim,
}))
}
2017-09-08 02:04:48 +00:00
return nil
}
2017-09-08 02:04:48 +00:00
// printWarnings prints any warnings in the secret.
func (t TableFormatter) printWarnings(ui cli.Ui, secret *api.Secret) {
if secret != nil && len(secret.Warnings) > 0 {
ui.Warn("WARNING! The following warnings were returned from Vault:\n")
for _, warning := range secret.Warnings {
2017-09-08 02:04:48 +00:00
ui.Warn(wrapAtLengthWithPadding(fmt.Sprintf("* %s", warning), 2))
ui.Warn("")
}
}
2016-01-14 19:18:27 +00:00
}
2017-09-08 02:04:48 +00:00
func (t TableFormatter) OutputSecret(ui cli.Ui, secret *api.Secret) error {
if secret == nil {
return nil
}
2017-09-08 02:04:48 +00:00
t.printWarnings(ui, secret)
out := make([]string, 0, 8)
if secret.LeaseDuration > 0 {
if secret.LeaseID != "" {
out = append(out, fmt.Sprintf("lease_id %s %s", hopeDelim, secret.LeaseID))
out = append(out, fmt.Sprintf("lease_duration %s %v", hopeDelim, humanDurationInt(secret.LeaseDuration)))
2017-09-08 02:04:48 +00:00
out = append(out, fmt.Sprintf("lease_renewable %s %t", hopeDelim, secret.Renewable))
} else {
2017-09-08 02:04:48 +00:00
// This is probably the generic secret backend which has leases, but we
// print them as refresh_interval to reduce confusion.
out = append(out, fmt.Sprintf("refresh_interval %s %v", hopeDelim, humanDurationInt(secret.LeaseDuration)))
}
}
2017-09-08 02:04:48 +00:00
if secret.Auth != nil {
if secret.Auth.MFARequirement != nil {
out = append(out, fmt.Sprintf("mfa_request_id %s %s", hopeDelim, secret.Auth.MFARequirement.MFARequestID))
for k, constraintSet := range secret.Auth.MFARequirement.MFAConstraints {
for _, constraint := range constraintSet.Any {
out = append(out, fmt.Sprintf("mfa_constraint_%s_%s_id %s %s", k, constraint.Type, hopeDelim, constraint.ID))
out = append(out, fmt.Sprintf("mfa_constraint_%s_%s_uses_passcode %s %t", k, constraint.Type, hopeDelim, constraint.UsesPasscode))
if constraint.Name != "" {
out = append(out, fmt.Sprintf("mfa_constraint_%s_%s_name %s %s", k, constraint.Type, hopeDelim, constraint.Name))
}
}
}
} else { // Token information only makes sense if no further MFA requirement (i.e. if we actually have a token)
out = append(out, fmt.Sprintf("token %s %s", hopeDelim, secret.Auth.ClientToken))
out = append(out, fmt.Sprintf("token_accessor %s %s", hopeDelim, secret.Auth.Accessor))
// If the lease duration is 0, it's likely a root token, so output the
// duration as "infinity" to clear things up.
if secret.Auth.LeaseDuration == 0 {
out = append(out, fmt.Sprintf("token_duration %s %s", hopeDelim, "∞"))
} else {
out = append(out, fmt.Sprintf("token_duration %s %v", hopeDelim, humanDurationInt(secret.Auth.LeaseDuration)))
}
out = append(out, fmt.Sprintf("token_renewable %s %t", hopeDelim, secret.Auth.Renewable))
out = append(out, fmt.Sprintf("token_policies %s %q", hopeDelim, secret.Auth.TokenPolicies))
out = append(out, fmt.Sprintf("identity_policies %s %q", hopeDelim, secret.Auth.IdentityPolicies))
out = append(out, fmt.Sprintf("policies %s %q", hopeDelim, secret.Auth.Policies))
for k, v := range secret.Auth.Metadata {
out = append(out, fmt.Sprintf("token_meta_%s %s %v", k, hopeDelim, v))
}
}
}
2017-09-08 02:04:48 +00:00
if secret.WrapInfo != nil {
out = append(out, fmt.Sprintf("wrapping_token: %s %s", hopeDelim, secret.WrapInfo.Token))
out = append(out, fmt.Sprintf("wrapping_accessor: %s %s", hopeDelim, secret.WrapInfo.Accessor))
out = append(out, fmt.Sprintf("wrapping_token_ttl: %s %v", hopeDelim, humanDurationInt(secret.WrapInfo.TTL)))
2017-09-08 02:04:48 +00:00
out = append(out, fmt.Sprintf("wrapping_token_creation_time: %s %s", hopeDelim, secret.WrapInfo.CreationTime.String()))
out = append(out, fmt.Sprintf("wrapping_token_creation_path: %s %s", hopeDelim, secret.WrapInfo.CreationPath))
if secret.WrapInfo.WrappedAccessor != "" {
out = append(out, fmt.Sprintf("wrapped_accessor: %s %s", hopeDelim, secret.WrapInfo.WrappedAccessor))
}
2016-05-02 05:58:58 +00:00
}
2017-09-08 02:04:48 +00:00
if len(secret.Data) > 0 {
keys := make([]string, 0, len(secret.Data))
for k := range secret.Data {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := secret.Data[k]
// If the field "looks" like a TTL, print it as a time duration instead.
if looksLikeDuration(k) {
v = humanDurationInt(v)
}
out = append(out, fmt.Sprintf("%s %s %v", k, hopeDelim, v))
}
}
2017-09-08 02:04:48 +00:00
// If we got this far and still don't have any data, there's nothing to print,
// sorry.
if len(out) == 0 {
return nil
}
2017-09-08 02:04:48 +00:00
// Prepend the header
out = append([]string{"Key" + hopeDelim + "Value"}, out...)
2017-09-08 02:04:48 +00:00
ui.Output(tableOutput(out, &columnize.Config{
Delim: hopeDelim,
}))
return nil
2016-01-14 19:18:27 +00:00
}
2017-09-21 17:38:39 +00:00
func (t TableFormatter) OutputMap(ui cli.Ui, data map[string]interface{}) error {
out := make([]string, 0, len(data)+1)
if len(data) > 0 {
keys := make([]string, 0, len(data))
for k := range data {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := data[k]
// If the field "looks" like a TTL, print it as a time duration instead.
if looksLikeDuration(k) {
v = humanDurationInt(v)
}
out = append(out, fmt.Sprintf("%s %s %v", k, hopeDelim, v))
}
}
// If we got this far and still don't have any data, there's nothing to print,
// sorry.
if len(out) == 0 {
return nil
}
// Prepend the header
out = append([]string{"Key" + hopeDelim + "Value"}, out...)
ui.Output(tableOutput(out, &columnize.Config{
Delim: hopeDelim,
}))
return nil
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
// OutputSealStatus will print *api.SealStatusResponse in the CLI according to the format provided
2017-09-21 17:38:39 +00:00
func OutputSealStatus(ui cli.Ui, client *api.Client, status *api.SealStatusResponse) int {
sealStatusOutput := SealStatusOutput{SealStatusResponse: *status}
2017-09-21 17:38:39 +00:00
// 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 {
ui.Error(fmt.Sprintf("Error checking leader status: %s", err))
return 1
2017-09-21 17:38:39 +00:00
}
// copy leaderStatus fields into sealStatusOutput for display later
sealStatusOutput.HAEnabled = leaderStatus.HAEnabled
sealStatusOutput.IsSelf = leaderStatus.IsSelf
sealStatusOutput.ActiveTime = leaderStatus.ActiveTime
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)
2017-09-21 17:38:39 +00:00
return 0
}
// looksLikeDuration checks if the given key "k" looks like a duration value.
// This is used to pretty-format duration values in responses, especially from
// plugins.
func looksLikeDuration(k string) bool {
return k == "period" || strings.HasSuffix(k, "_period") ||
k == "ttl" || strings.HasSuffix(k, "_ttl") ||
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"`
ActiveTime time.Time `json:"active_time,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"`
}