Add "operator" subcommand
This commit is contained in:
parent
387cce957e
commit
ef86e95eff
47
command/operator.go
Normal file
47
command/operator.go
Normal file
@ -0,0 +1,47 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
var _ cli.Command = (*OperatorCommand)(nil)
|
||||
|
||||
type OperatorCommand struct {
|
||||
*BaseCommand
|
||||
}
|
||||
|
||||
func (c *OperatorCommand) Synopsis() string {
|
||||
return "Perform operator-specific tasks"
|
||||
}
|
||||
|
||||
func (c *OperatorCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault operator <subcommand> [options] [args]
|
||||
|
||||
This command groups subcommands for operators interacting with Vault. Most
|
||||
users will not need to interact with these commands. Here are a few examples
|
||||
of the operator commands:
|
||||
|
||||
Initialize a new Vault cluster:
|
||||
|
||||
$ vault operator init
|
||||
|
||||
Force a Vault to resign leadership in a cluster:
|
||||
|
||||
$ vault operator step-down
|
||||
|
||||
Rotate Vault's underlying encryption key:
|
||||
|
||||
$ vault operator rotate
|
||||
|
||||
Please see the individual subcommand help for detailed usage information.
|
||||
`
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *OperatorCommand) Run(args []string) int {
|
||||
return cli.RunResultHelp
|
||||
}
|
@ -18,12 +18,10 @@ import (
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// Ensure we are implementing the right interfaces.
|
||||
var _ cli.Command = (*GenerateRootCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*GenerateRootCommand)(nil)
|
||||
var _ cli.Command = (*OperatorGenerateRootCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*OperatorGenerateRootCommand)(nil)
|
||||
|
||||
// GenerateRootCommand is a Command that generates a new root token.
|
||||
type GenerateRootCommand struct {
|
||||
type OperatorGenerateRootCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagInit bool
|
||||
@ -36,26 +34,26 @@ type GenerateRootCommand struct {
|
||||
flagGenerateOTP bool
|
||||
|
||||
// Deprecation
|
||||
// TODO: remove in 0.9.9
|
||||
// TODO: remove in 0.9.0
|
||||
flagGenOTP bool
|
||||
|
||||
testStdin io.Reader // for tests
|
||||
}
|
||||
|
||||
func (c *GenerateRootCommand) Synopsis() string {
|
||||
func (c *OperatorGenerateRootCommand) Synopsis() string {
|
||||
return "Generates a new root token"
|
||||
}
|
||||
|
||||
func (c *GenerateRootCommand) Help() string {
|
||||
func (c *OperatorGenerateRootCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault generate-root [options] [KEY]
|
||||
Usage: vault operator generate-root [options] [KEY]
|
||||
|
||||
Generates a new root token by combining a quorum of share holders. One of
|
||||
the following must be provided to start the root token generation:
|
||||
|
||||
- A base64-encoded one-time-password (OTP) provided via the "-otp" flag.
|
||||
Use the "-generate-otp" flag to generate a usable value. The resulting
|
||||
token is XORed with this value when it is returend. Use the "-decode"
|
||||
token is XORed with this value when it is returned. Use the "-decode"
|
||||
flag to output the final value.
|
||||
|
||||
- A file containing a PGP key or a keybase username in the "-pgp-key"
|
||||
@ -67,24 +65,22 @@ Usage: vault generate-root [options] [KEY]
|
||||
|
||||
Generate an OTP code for the final token:
|
||||
|
||||
$ vault generate-root -generate-otp
|
||||
$ vault operator generate-root -generate-otp
|
||||
|
||||
Start a root token generation:
|
||||
|
||||
$ vault generate-root -init -otp="..."
|
||||
$ vault generate-root -init -pgp-key="..."
|
||||
$ vault operator generate-root -init -otp="..."
|
||||
$ vault operator generate-root -init -pgp-key="..."
|
||||
|
||||
Enter an unseal key to progress root token generation:
|
||||
|
||||
$ vault generate-root -otp="..."
|
||||
|
||||
For a full list of examples, please see the documentation.
|
||||
$ vault operator generate-root -otp="..."
|
||||
|
||||
` + c.Flags().Help()
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *GenerateRootCommand) Flags() *FlagSets {
|
||||
func (c *OperatorGenerateRootCommand) Flags() *FlagSets {
|
||||
set := c.flagSet(FlagSetHTTP)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
@ -115,7 +111,7 @@ func (c *GenerateRootCommand) Flags() *FlagSets {
|
||||
Default: false,
|
||||
EnvVar: "",
|
||||
Completion: complete.PredictNothing,
|
||||
Usage: "Print the status of the current attempt without provding an " +
|
||||
Usage: "Print the status of the current attempt without providing an " +
|
||||
"unseal key.",
|
||||
})
|
||||
|
||||
@ -183,15 +179,15 @@ func (c *GenerateRootCommand) Flags() *FlagSets {
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *GenerateRootCommand) AutocompleteArgs() complete.Predictor {
|
||||
func (c *OperatorGenerateRootCommand) AutocompleteArgs() complete.Predictor {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *GenerateRootCommand) AutocompleteFlags() complete.Flags {
|
||||
func (c *OperatorGenerateRootCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *GenerateRootCommand) Run(args []string) int {
|
||||
func (c *OperatorGenerateRootCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
@ -243,7 +239,7 @@ func (c *GenerateRootCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// verifyOTP verifies the given OTP code is exactly 16 bytes.
|
||||
func (c *GenerateRootCommand) verifyOTP(otp string) error {
|
||||
func (c *OperatorGenerateRootCommand) verifyOTP(otp string) error {
|
||||
if len(otp) == 0 {
|
||||
return fmt.Errorf("No OTP passed in")
|
||||
}
|
||||
@ -259,7 +255,7 @@ func (c *GenerateRootCommand) verifyOTP(otp string) error {
|
||||
}
|
||||
|
||||
// generateOTP generates a suitable OTP code for generating a root token.
|
||||
func (c *GenerateRootCommand) generateOTP() int {
|
||||
func (c *OperatorGenerateRootCommand) generateOTP() int {
|
||||
buf := make([]byte, 16)
|
||||
readLen, err := rand.Read(buf)
|
||||
if err != nil {
|
||||
@ -276,7 +272,7 @@ func (c *GenerateRootCommand) generateOTP() int {
|
||||
}
|
||||
|
||||
// decode decodes the given value using the otp.
|
||||
func (c *GenerateRootCommand) decode(encoded, otp string) int {
|
||||
func (c *OperatorGenerateRootCommand) decode(encoded, otp string) int {
|
||||
if encoded == "" {
|
||||
c.UI.Error("Missing encoded value: use -decode=<string> to supply it")
|
||||
return 1
|
||||
@ -302,7 +298,7 @@ func (c *GenerateRootCommand) decode(encoded, otp string) int {
|
||||
}
|
||||
|
||||
// init is used to start the generation process
|
||||
func (c *GenerateRootCommand) init(client *api.Client, otp string, pgpKey string) int {
|
||||
func (c *OperatorGenerateRootCommand) init(client *api.Client, otp string, pgpKey string) int {
|
||||
// Validate incoming fields. Either OTP OR PGP keys must be supplied.
|
||||
switch {
|
||||
case otp == "" && pgpKey == "":
|
||||
@ -331,7 +327,7 @@ func (c *GenerateRootCommand) init(client *api.Client, otp string, pgpKey string
|
||||
|
||||
// provide prompts the user for the seal key and posts it to the update root
|
||||
// endpoint. If this is the last unseal, this function outputs it.
|
||||
func (c *GenerateRootCommand) provide(client *api.Client, key string) int {
|
||||
func (c *OperatorGenerateRootCommand) provide(client *api.Client, key string) int {
|
||||
status, err := client.Sys().GenerateRootStatus()
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error getting root generation status: %s", err))
|
||||
@ -413,7 +409,7 @@ func (c *GenerateRootCommand) provide(client *api.Client, key string) int {
|
||||
}
|
||||
|
||||
// cancel cancels the root token generation
|
||||
func (c *GenerateRootCommand) cancel(client *api.Client) int {
|
||||
func (c *OperatorGenerateRootCommand) cancel(client *api.Client) int {
|
||||
if err := client.Sys().GenerateRootCancel(); err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error canceling root token generation: %s", err))
|
||||
return 2
|
||||
@ -423,7 +419,7 @@ func (c *GenerateRootCommand) cancel(client *api.Client) int {
|
||||
}
|
||||
|
||||
// status is used just to fetch and dump the status
|
||||
func (c *GenerateRootCommand) status(client *api.Client) int {
|
||||
func (c *OperatorGenerateRootCommand) status(client *api.Client) int {
|
||||
status, err := client.Sys().GenerateRootStatus()
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error getting root generation status: %s", err))
|
||||
@ -433,7 +429,7 @@ func (c *GenerateRootCommand) status(client *api.Client) int {
|
||||
}
|
||||
|
||||
// printStatus dumps the status to output
|
||||
func (c *GenerateRootCommand) printStatus(status *api.GenerateRootStatusResponse) int {
|
||||
func (c *OperatorGenerateRootCommand) printStatus(status *api.GenerateRootStatusResponse) int {
|
||||
out := []string{}
|
||||
out = append(out, fmt.Sprintf("Nonce | %s", status.Nonce))
|
||||
out = append(out, fmt.Sprintf("Started | %t", status.Started))
|
||||
@ -446,7 +442,7 @@ func (c *GenerateRootCommand) printStatus(status *api.GenerateRootStatusResponse
|
||||
out = append(out, fmt.Sprintf("Root Token | %s", status.EncodedRootToken))
|
||||
}
|
||||
|
||||
output := columnOutput(out)
|
||||
output := columnOutput(out, nil)
|
||||
c.UI.Output(output)
|
||||
return 0
|
||||
}
|
@ -11,18 +11,18 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testGenerateRootCommand(tb testing.TB) (*cli.MockUi, *GenerateRootCommand) {
|
||||
func testOperatorGenerateRootCommand(tb testing.TB) (*cli.MockUi, *OperatorGenerateRootCommand) {
|
||||
tb.Helper()
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
return ui, &GenerateRootCommand{
|
||||
return ui, &OperatorGenerateRootCommand{
|
||||
BaseCommand: &BaseCommand{
|
||||
UI: ui,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
func TestOperatorGenerateRootCommand_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
@ -88,7 +88,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
|
||||
code := cmd.Run(tc.args)
|
||||
if code != tc.code {
|
||||
@ -106,7 +106,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
t.Run("generate_otp", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
|
||||
code := cmd.Run([]string{
|
||||
"-generate-otp",
|
||||
@ -127,7 +127,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
encoded := "L9MaZ/4mQanpOV6QeWd84g=="
|
||||
otp := "dIeeezkjpDUv3fy7MYPOLQ=="
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
|
||||
code := cmd.Run([]string{
|
||||
"-decode", encoded,
|
||||
@ -157,7 +157,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -191,7 +191,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -227,7 +227,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -263,7 +263,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -297,7 +297,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
|
||||
// Supply the first n-1 unseal keys
|
||||
for _, key := range keys[:len(keys)-1] {
|
||||
_, cmd := testGenerateRootCommand(t)
|
||||
_, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -309,7 +309,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -364,7 +364,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
stdinW.Close()
|
||||
}()
|
||||
|
||||
_, cmd := testGenerateRootCommand(t)
|
||||
_, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
cmd.testStdin = stdinR
|
||||
|
||||
@ -383,7 +383,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
stdinW.Close()
|
||||
}()
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
cmd.testStdin = stdinR
|
||||
|
||||
@ -422,7 +422,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerBad(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testGenerateRootCommand(t)
|
||||
ui, cmd := testOperatorGenerateRootCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -442,7 +442,7 @@ func TestGenerateRootCommand_Run(t *testing.T) {
|
||||
t.Run("no_tabs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, cmd := testGenerateRootCommand(t)
|
||||
_, cmd := testOperatorGenerateRootCommand(t)
|
||||
assertNoTabs(t, cmd)
|
||||
})
|
||||
}
|
@ -16,12 +16,10 @@ import (
|
||||
consulapi "github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
// Ensure we are implementing the right interfaces.
|
||||
var _ cli.Command = (*InitCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*InitCommand)(nil)
|
||||
var _ cli.Command = (*OperatorInitCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*OperatorInitCommand)(nil)
|
||||
|
||||
// InitCommand is a Command that initializes a new Vault server.
|
||||
type InitCommand struct {
|
||||
type OperatorInitCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagStatus bool
|
||||
@ -46,13 +44,13 @@ type InitCommand struct {
|
||||
flagCheck bool
|
||||
}
|
||||
|
||||
func (c *InitCommand) Synopsis() string {
|
||||
func (c *OperatorInitCommand) Synopsis() string {
|
||||
return "Initializes a server"
|
||||
}
|
||||
|
||||
func (c *InitCommand) Help() string {
|
||||
func (c *OperatorInitCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault init [options]
|
||||
Usage: vault operator init [options]
|
||||
|
||||
Initializes a Vault server. Initialization is the process by which Vault's
|
||||
storage backend is prepared to receive data. Since Vault server's share the
|
||||
@ -69,26 +67,24 @@ Usage: vault init [options]
|
||||
|
||||
Start initialization with the default options:
|
||||
|
||||
$ vault init
|
||||
$ vault operator init
|
||||
|
||||
Initialize, but encrypt the unseal keys with pgp keys:
|
||||
|
||||
$ vault init \
|
||||
$ vault operator init \
|
||||
-key-shares=3 \
|
||||
-key-threshold=2 \
|
||||
-pgp-keys="keybase:hashicorp,keybase:jefferai,keybase:sethvargo"
|
||||
|
||||
Encrypt the initial root token using a pgp key:
|
||||
|
||||
$ vault init -root-token-pgp-key="keybase:hashicorp"
|
||||
|
||||
For a complete list of examples, please see the documentation.
|
||||
$ vault operator init -root-token-pgp-key="keybase:hashicorp"
|
||||
|
||||
` + c.Flags().Help()
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *InitCommand) Flags() *FlagSets {
|
||||
func (c *OperatorInitCommand) Flags() *FlagSets {
|
||||
set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
|
||||
|
||||
// Common Options
|
||||
@ -231,15 +227,15 @@ func (c *InitCommand) Flags() *FlagSets {
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *InitCommand) AutocompleteArgs() complete.Predictor {
|
||||
func (c *OperatorInitCommand) AutocompleteArgs() complete.Predictor {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *InitCommand) AutocompleteFlags() complete.Flags {
|
||||
func (c *OperatorInitCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *InitCommand) Run(args []string) int {
|
||||
func (c *OperatorInitCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
@ -293,7 +289,7 @@ func (c *InitCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// consulAuto enables auto-joining via Consul.
|
||||
func (c *InitCommand) consulAuto(client *api.Client, req *api.InitRequest) int {
|
||||
func (c *OperatorInitCommand) consulAuto(client *api.Client, req *api.InitRequest) int {
|
||||
// Capture the client original address and reset it
|
||||
originalAddr := client.Address()
|
||||
defer client.SetAddress(originalAddr)
|
||||
@ -432,7 +428,7 @@ func (c *InitCommand) consulAuto(client *api.Client, req *api.InitRequest) int {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *InitCommand) init(client *api.Client, req *api.InitRequest) int {
|
||||
func (c *OperatorInitCommand) init(client *api.Client, req *api.InitRequest) int {
|
||||
resp, err := client.Sys().Init(req)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error initializing: %s", err))
|
||||
@ -509,7 +505,7 @@ func (c *InitCommand) init(client *api.Client, req *api.InitRequest) int {
|
||||
}
|
||||
|
||||
// initOutputYAML outputs the init output as YAML.
|
||||
func (c *InitCommand) initOutputYAML(req *api.InitRequest, resp *api.InitResponse) int {
|
||||
func (c *OperatorInitCommand) initOutputYAML(req *api.InitRequest, resp *api.InitResponse) int {
|
||||
b, err := yaml.Marshal(newMachineInit(req, resp))
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error marshaling YAML: %s", err))
|
||||
@ -519,7 +515,7 @@ func (c *InitCommand) initOutputYAML(req *api.InitRequest, resp *api.InitRespons
|
||||
}
|
||||
|
||||
// initOutputJSON outputs the init output as JSON.
|
||||
func (c *InitCommand) initOutputJSON(req *api.InitRequest, resp *api.InitResponse) int {
|
||||
func (c *OperatorInitCommand) initOutputJSON(req *api.InitRequest, resp *api.InitResponse) int {
|
||||
b, err := json.Marshal(newMachineInit(req, resp))
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error marshaling JSON: %s", err))
|
||||
@ -530,7 +526,7 @@ func (c *InitCommand) initOutputJSON(req *api.InitRequest, resp *api.InitRespons
|
||||
|
||||
// status inspects the init status of vault and returns an appropriate error
|
||||
// code and message.
|
||||
func (c *InitCommand) status(client *api.Client) int {
|
||||
func (c *OperatorInitCommand) status(client *api.Client) int {
|
||||
inited, err := client.Sys().InitStatus()
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error checking init status: %s", err))
|
@ -13,18 +13,18 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testInitCommand(tb testing.TB) (*cli.MockUi, *InitCommand) {
|
||||
func testOperatorInitCommand(tb testing.TB) (*cli.MockUi, *OperatorInitCommand) {
|
||||
tb.Helper()
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
return ui, &InitCommand{
|
||||
return ui, &OperatorInitCommand{
|
||||
BaseCommand: &BaseCommand{
|
||||
UI: ui,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitCommand_Run(t *testing.T) {
|
||||
func TestOperatorInitCommand_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
@ -100,7 +100,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testInitCommand(t)
|
||||
ui, cmd := testOperatorInitCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run(tc.args)
|
||||
@ -122,7 +122,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerUninit(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testInitCommand(t)
|
||||
ui, cmd := testOperatorInitCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
// Verify the non-init response code
|
||||
@ -142,7 +142,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
}
|
||||
|
||||
// Verify the init response code
|
||||
ui, cmd = testInitCommand(t)
|
||||
ui, cmd = testOperatorInitCommand(t)
|
||||
cmd.client = client
|
||||
code = cmd.Run([]string{
|
||||
"-status",
|
||||
@ -158,7 +158,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerUninit(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testInitCommand(t)
|
||||
ui, cmd := testOperatorInitCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{})
|
||||
@ -217,7 +217,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerUninit(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testInitCommand(t)
|
||||
ui, cmd := testOperatorInitCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -283,7 +283,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerUninit(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testInitCommand(t)
|
||||
ui, cmd := testOperatorInitCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -335,7 +335,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerBad(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testInitCommand(t)
|
||||
ui, cmd := testOperatorInitCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -355,7 +355,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
t.Run("no_tabs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, cmd := testInitCommand(t)
|
||||
_, cmd := testOperatorInitCommand(t)
|
||||
assertNoTabs(t, cmd)
|
||||
})
|
||||
}
|
@ -8,22 +8,20 @@ import (
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// Ensure we are implementing the right interfaces.
|
||||
var _ cli.Command = (*KeyStatusCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*KeyStatusCommand)(nil)
|
||||
var _ cli.Command = (*OperatorKeyStatusCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*OperatorKeyStatusCommand)(nil)
|
||||
|
||||
// KeyStatusCommand is a Command that provides information about the key status
|
||||
type KeyStatusCommand struct {
|
||||
type OperatorKeyStatusCommand struct {
|
||||
*BaseCommand
|
||||
}
|
||||
|
||||
func (c *KeyStatusCommand) Synopsis() string {
|
||||
func (c *OperatorKeyStatusCommand) Synopsis() string {
|
||||
return "Provides information about the active encryption key"
|
||||
}
|
||||
|
||||
func (c *KeyStatusCommand) Help() string {
|
||||
func (c *OperatorKeyStatusCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault key-status [options]
|
||||
Usage: vault operator key-status [options]
|
||||
|
||||
Provides information about the active encryption key. Specifically,
|
||||
the current key term and the key installation time.
|
||||
@ -33,19 +31,19 @@ Usage: vault key-status [options]
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *KeyStatusCommand) Flags() *FlagSets {
|
||||
func (c *OperatorKeyStatusCommand) Flags() *FlagSets {
|
||||
return c.flagSet(FlagSetHTTP)
|
||||
}
|
||||
|
||||
func (c *KeyStatusCommand) AutocompleteArgs() complete.Predictor {
|
||||
func (c *OperatorKeyStatusCommand) AutocompleteArgs() complete.Predictor {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *KeyStatusCommand) AutocompleteFlags() complete.Flags {
|
||||
func (c *OperatorKeyStatusCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *KeyStatusCommand) Run(args []string) int {
|
||||
func (c *OperatorKeyStatusCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
@ -7,18 +7,18 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testKeyStatusCommand(tb testing.TB) (*cli.MockUi, *KeyStatusCommand) {
|
||||
func testOperatorKeyStatusCommand(tb testing.TB) (*cli.MockUi, *OperatorKeyStatusCommand) {
|
||||
tb.Helper()
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
return ui, &KeyStatusCommand{
|
||||
return ui, &OperatorKeyStatusCommand{
|
||||
BaseCommand: &BaseCommand{
|
||||
UI: ui,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestKeyStatusCommand_Run(t *testing.T) {
|
||||
func TestOperatorKeyStatusCommand_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
@ -44,7 +44,7 @@ func TestKeyStatusCommand_Run(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ui, cmd := testKeyStatusCommand(t)
|
||||
ui, cmd := testOperatorKeyStatusCommand(t)
|
||||
|
||||
code := cmd.Run(tc.args)
|
||||
if code != tc.code {
|
||||
@ -65,7 +65,7 @@ func TestKeyStatusCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testKeyStatusCommand(t)
|
||||
ui, cmd := testOperatorKeyStatusCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{})
|
||||
@ -86,7 +86,7 @@ func TestKeyStatusCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerBad(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testKeyStatusCommand(t)
|
||||
ui, cmd := testOperatorKeyStatusCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{})
|
||||
@ -104,7 +104,7 @@ func TestKeyStatusCommand_Run(t *testing.T) {
|
||||
t.Run("no_tabs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, cmd := testKeyStatusCommand(t)
|
||||
_, cmd := testOperatorKeyStatusCommand(t)
|
||||
assertNoTabs(t, cmd)
|
||||
})
|
||||
}
|
@ -15,24 +15,12 @@ import (
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// Ensure we are implementing the right interfaces.
|
||||
var _ cli.Command = (*RekeyCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*RekeyCommand)(nil)
|
||||
var _ cli.Command = (*OperatorRekeyCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*OperatorRekeyCommand)(nil)
|
||||
|
||||
// RekeyCommand is a Command that rekeys the vault.
|
||||
type RekeyCommand struct {
|
||||
type OperatorRekeyCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
// Key can be used to pre-seed the key. If it is set, it will not
|
||||
// be asked with the `password` helper.
|
||||
Key string
|
||||
|
||||
// The nonce for the rekey request to send along
|
||||
Nonce string
|
||||
|
||||
// Whether to use the recovery key instead of barrier key, if available
|
||||
RecoveryKey bool
|
||||
|
||||
flagCancel bool
|
||||
flagInit bool
|
||||
flagKeyShares int
|
||||
@ -56,11 +44,11 @@ type RekeyCommand struct {
|
||||
testStdin io.Reader // for tests
|
||||
}
|
||||
|
||||
func (c *RekeyCommand) Synopsis() string {
|
||||
func (c *OperatorRekeyCommand) Synopsis() string {
|
||||
return "Generates new unseal keys"
|
||||
}
|
||||
|
||||
func (c *RekeyCommand) Help() string {
|
||||
func (c *OperatorRekeyCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault rekey [options] [KEY]
|
||||
|
||||
@ -75,14 +63,14 @@ Usage: vault rekey [options] [KEY]
|
||||
|
||||
Initialize a rekey:
|
||||
|
||||
$ vault rekey \
|
||||
$ vault operator rekey \
|
||||
-init \
|
||||
-key-shares=15 \
|
||||
-key-threshold=9
|
||||
|
||||
Rekey and encrypt the resulting unseal keys with PGP:
|
||||
|
||||
$ vault rekey \
|
||||
$ vault operator rekey \
|
||||
-init \
|
||||
-key-shares=3 \
|
||||
-key-threshold=2 \
|
||||
@ -90,29 +78,27 @@ Usage: vault rekey [options] [KEY]
|
||||
|
||||
Store encrypted PGP keys in Vault's core:
|
||||
|
||||
$ vault rekey \
|
||||
$ vault operator rekey \
|
||||
-init \
|
||||
-pgp-keys="..." \
|
||||
-backup
|
||||
|
||||
Retrieve backed-up unseal keys:
|
||||
|
||||
$ vault rekey -backup-retrieve
|
||||
$ vault operator rekey -backup-retrieve
|
||||
|
||||
Delete backed-up unseal keys:
|
||||
|
||||
$ vault rekey -backup-delete
|
||||
|
||||
For a full list of examples, please see the documentation.
|
||||
$ vault operator rekey -backup-delete
|
||||
|
||||
` + c.Flags().Help()
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *RekeyCommand) Flags() *FlagSets {
|
||||
func (c *OperatorRekeyCommand) Flags() *FlagSets {
|
||||
set := c.flagSet(FlagSetHTTP)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
f := set.NewFlagSet("Common Options")
|
||||
|
||||
f.BoolVar(&BoolVar{
|
||||
Name: "init",
|
||||
@ -136,7 +122,7 @@ func (c *RekeyCommand) Flags() *FlagSets {
|
||||
Name: "status",
|
||||
Target: &c.flagStatus,
|
||||
Default: false,
|
||||
Usage: "Print the status of the current attempt without provding an " +
|
||||
Usage: "Print the status of the current attempt without providing an " +
|
||||
"unseal key.",
|
||||
})
|
||||
|
||||
@ -188,8 +174,7 @@ func (c *RekeyCommand) Flags() *FlagSets {
|
||||
"public GPG keys OR a comma-separated list of Keybase usernames using " +
|
||||
"the format \"keybase:<username>\". When supplied, the generated " +
|
||||
"unseal keys will be encrypted and base64-encoded in the order " +
|
||||
"specified in this list. The number of entires must match -key-shares, " +
|
||||
"unless -store-shares are used.",
|
||||
"specified in this list.",
|
||||
})
|
||||
|
||||
f = set.NewFlagSet("Backup Options")
|
||||
@ -216,7 +201,7 @@ func (c *RekeyCommand) Flags() *FlagSets {
|
||||
Name: "backup-retrieve",
|
||||
Target: &c.flagBackupRetrieve,
|
||||
Default: false,
|
||||
Usage: "Retrieve the backed-up unseal keys. This option is only avaiable " +
|
||||
Usage: "Retrieve the backed-up unseal keys. This option is only available " +
|
||||
"if the PGP keys were provided and the backup has not been deleted.",
|
||||
})
|
||||
|
||||
@ -249,15 +234,15 @@ func (c *RekeyCommand) Flags() *FlagSets {
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *RekeyCommand) AutocompleteArgs() complete.Predictor {
|
||||
func (c *OperatorRekeyCommand) AutocompleteArgs() complete.Predictor {
|
||||
return complete.PredictAnything
|
||||
}
|
||||
|
||||
func (c *RekeyCommand) AutocompleteFlags() complete.Flags {
|
||||
func (c *OperatorRekeyCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *RekeyCommand) Run(args []string) int {
|
||||
func (c *OperatorRekeyCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
@ -324,7 +309,7 @@ func (c *RekeyCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
// init starts the rekey process.
|
||||
func (c *RekeyCommand) init(client *api.Client) int {
|
||||
func (c *OperatorRekeyCommand) init(client *api.Client) int {
|
||||
// Handle the different API requests
|
||||
var fn func(*api.RekeyInitRequest) (*api.RekeyStatusResponse, error)
|
||||
switch strings.ToLower(strings.TrimSpace(c.flagTarget)) {
|
||||
@ -377,7 +362,7 @@ func (c *RekeyCommand) init(client *api.Client) int {
|
||||
}
|
||||
|
||||
// cancel is used to abort the rekey process.
|
||||
func (c *RekeyCommand) cancel(client *api.Client) int {
|
||||
func (c *OperatorRekeyCommand) cancel(client *api.Client) int {
|
||||
// Handle the different API requests
|
||||
var fn func() error
|
||||
switch strings.ToLower(strings.TrimSpace(c.flagTarget)) {
|
||||
@ -402,7 +387,7 @@ func (c *RekeyCommand) cancel(client *api.Client) int {
|
||||
|
||||
// provide prompts the user for the seal key and posts it to the update root
|
||||
// endpoint. If this is the last unseal, this function outputs it.
|
||||
func (c *RekeyCommand) provide(client *api.Client, key string) int {
|
||||
func (c *OperatorRekeyCommand) provide(client *api.Client, key string) int {
|
||||
var statusFn func() (*api.RekeyStatusResponse, error)
|
||||
var updateFn func(string, string) (*api.RekeyUpdateResponse, error)
|
||||
|
||||
@ -504,7 +489,7 @@ func (c *RekeyCommand) provide(client *api.Client, key string) int {
|
||||
}
|
||||
|
||||
// status is used just to fetch and dump the status.
|
||||
func (c *RekeyCommand) status(client *api.Client) int {
|
||||
func (c *OperatorRekeyCommand) status(client *api.Client) int {
|
||||
// Handle the different API requests
|
||||
var fn func() (*api.RekeyStatusResponse, error)
|
||||
switch strings.ToLower(strings.TrimSpace(c.flagTarget)) {
|
||||
@ -528,7 +513,7 @@ func (c *RekeyCommand) status(client *api.Client) int {
|
||||
}
|
||||
|
||||
// backupRetrieve retrieves the stored backup keys.
|
||||
func (c *RekeyCommand) backupRetrieve(client *api.Client) int {
|
||||
func (c *OperatorRekeyCommand) backupRetrieve(client *api.Client) int {
|
||||
// Handle the different API requests
|
||||
var fn func() (*api.RekeyRetrieveResponse, error)
|
||||
switch strings.ToLower(strings.TrimSpace(c.flagTarget)) {
|
||||
@ -556,7 +541,7 @@ func (c *RekeyCommand) backupRetrieve(client *api.Client) int {
|
||||
}
|
||||
|
||||
// backupDelete deletes the stored backup keys.
|
||||
func (c *RekeyCommand) backupDelete(client *api.Client) int {
|
||||
func (c *OperatorRekeyCommand) backupDelete(client *api.Client) int {
|
||||
// Handle the different API requests
|
||||
var fn func() error
|
||||
switch strings.ToLower(strings.TrimSpace(c.flagTarget)) {
|
||||
@ -580,7 +565,7 @@ func (c *RekeyCommand) backupDelete(client *api.Client) int {
|
||||
}
|
||||
|
||||
// printStatus dumps the status to output
|
||||
func (c *RekeyCommand) printStatus(status *api.RekeyStatusResponse) int {
|
||||
func (c *OperatorRekeyCommand) printStatus(status *api.RekeyStatusResponse) int {
|
||||
out := []string{}
|
||||
out = append(out, fmt.Sprintf("Nonce | %s", status.Nonce))
|
||||
out = append(out, fmt.Sprintf("Started | %t", status.Started))
|
||||
@ -596,12 +581,12 @@ func (c *RekeyCommand) printStatus(status *api.RekeyStatusResponse) int {
|
||||
out = append(out, fmt.Sprintf("Backup | %t", status.Backup))
|
||||
}
|
||||
|
||||
output := columnOutput(out)
|
||||
output := columnOutput(out, nil)
|
||||
c.UI.Output(output)
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *RekeyCommand) printUnsealKeys(status *api.RekeyStatusResponse, resp *api.RekeyUpdateResponse) int {
|
||||
func (c *OperatorRekeyCommand) printUnsealKeys(status *api.RekeyStatusResponse, resp *api.RekeyUpdateResponse) int {
|
||||
// Space between the key prompt, if any, and the output
|
||||
c.UI.Output("")
|
||||
|
||||
@ -633,7 +618,7 @@ func (c *RekeyCommand) printUnsealKeys(status *api.RekeyStatusResponse, resp *ap
|
||||
c.UI.Output("")
|
||||
c.UI.Output(wrapAtLength(fmt.Sprintf(
|
||||
"The encrypted unseal keys are backed up to \"core/unseal-keys-backup\"" +
|
||||
"in the physical backend. Remove these keys at any time using " +
|
||||
"in the storage backend. Remove these keys at any time using " +
|
||||
"\"vault rekey -delete-backup\". Vault does not automatically remove " +
|
||||
"these keys.",
|
||||
)))
|
@ -11,18 +11,18 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testRekeyCommand(tb testing.TB) (*cli.MockUi, *RekeyCommand) {
|
||||
func testOperatorRekeyCommand(tb testing.TB) (*cli.MockUi, *OperatorRekeyCommand) {
|
||||
tb.Helper()
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
return ui, &RekeyCommand{
|
||||
return ui, &OperatorRekeyCommand{
|
||||
BaseCommand: &BaseCommand{
|
||||
UI: ui,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestRekeyCommand_Run(t *testing.T) {
|
||||
func TestOperatorRekeyCommand_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
@ -75,7 +75,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run(tc.args)
|
||||
@ -97,7 +97,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
// Verify the non-init response
|
||||
@ -123,7 +123,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
}
|
||||
|
||||
// Verify the init response
|
||||
ui, cmd = testRekeyCommand(t)
|
||||
ui, cmd = testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
code = cmd.Run([]string{
|
||||
"-status",
|
||||
@ -153,7 +153,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -185,7 +185,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -221,7 +221,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -270,7 +270,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
|
||||
// Supply the first n-1 unseal keys
|
||||
for _, key := range keys[:len(keys)-1] {
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -282,7 +282,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -338,7 +338,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
stdinW.Close()
|
||||
}()
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
cmd.testStdin = stdinR
|
||||
|
||||
@ -357,7 +357,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
stdinW.Close()
|
||||
}()
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
cmd.testStdin = stdinR
|
||||
|
||||
@ -399,7 +399,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
client, keys, closer := testVaultServerUnseal(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -423,7 +423,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
var combined string
|
||||
// Supply the unseal keys
|
||||
for _, key := range keys {
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -448,7 +448,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
fingerprint, encryptedKey := match[0][1], match[0][2]
|
||||
|
||||
// Get the backup
|
||||
ui, cmd = testRekeyCommand(t)
|
||||
ui, cmd = testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code = cmd.Run([]string{
|
||||
@ -467,7 +467,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
}
|
||||
|
||||
// Delete the backup
|
||||
ui, cmd = testRekeyCommand(t)
|
||||
ui, cmd = testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code = cmd.Run([]string{
|
||||
@ -489,7 +489,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerBad(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testRekeyCommand(t)
|
||||
ui, cmd := testOperatorRekeyCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -509,7 +509,7 @@ func TestRekeyCommand_Run(t *testing.T) {
|
||||
t.Run("no_tabs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, cmd := testRekeyCommand(t)
|
||||
_, cmd := testOperatorRekeyCommand(t)
|
||||
assertNoTabs(t, cmd)
|
||||
})
|
||||
}
|
@ -8,20 +8,18 @@ import (
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// Ensure we are implementing the right interfaces.
|
||||
var _ cli.Command = (*SealCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*SealCommand)(nil)
|
||||
var _ cli.Command = (*OperatorSealCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*OperatorSealCommand)(nil)
|
||||
|
||||
// SealCommand is a Command that seals the vault.
|
||||
type SealCommand struct {
|
||||
type OperatorSealCommand struct {
|
||||
*BaseCommand
|
||||
}
|
||||
|
||||
func (c *SealCommand) Synopsis() string {
|
||||
func (c *OperatorSealCommand) Synopsis() string {
|
||||
return "Seals the Vault server"
|
||||
}
|
||||
|
||||
func (c *SealCommand) Help() string {
|
||||
func (c *OperatorSealCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault seal [options]
|
||||
|
||||
@ -37,29 +35,26 @@ Usage: vault seal [options]
|
||||
|
||||
Seal the Vault server:
|
||||
|
||||
$ vault seal
|
||||
|
||||
For a full list of examples and why you might want to seal the Vault, please
|
||||
see the documentation.
|
||||
$ vault operator seal
|
||||
|
||||
` + c.Flags().Help()
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *SealCommand) Flags() *FlagSets {
|
||||
func (c *OperatorSealCommand) Flags() *FlagSets {
|
||||
return c.flagSet(FlagSetHTTP)
|
||||
}
|
||||
|
||||
func (c *SealCommand) AutocompleteArgs() complete.Predictor {
|
||||
func (c *OperatorSealCommand) AutocompleteArgs() complete.Predictor {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *SealCommand) AutocompleteFlags() complete.Flags {
|
||||
func (c *OperatorSealCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *SealCommand) Run(args []string) int {
|
||||
func (c *OperatorSealCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
@ -7,18 +7,18 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testSealCommand(tb testing.TB) (*cli.MockUi, *SealCommand) {
|
||||
func testOperatorSealCommand(tb testing.TB) (*cli.MockUi, *OperatorSealCommand) {
|
||||
tb.Helper()
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
return ui, &SealCommand{
|
||||
return ui, &OperatorSealCommand{
|
||||
BaseCommand: &BaseCommand{
|
||||
UI: ui,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSealCommand_Run(t *testing.T) {
|
||||
func TestOperatorSealCommand_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
@ -47,7 +47,7 @@ func TestSealCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testSealCommand(t)
|
||||
ui, cmd := testOperatorSealCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run(tc.args)
|
||||
@ -69,7 +69,7 @@ func TestSealCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testSealCommand(t)
|
||||
ui, cmd := testOperatorSealCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{})
|
||||
@ -98,7 +98,7 @@ func TestSealCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerBad(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testSealCommand(t)
|
||||
ui, cmd := testOperatorSealCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{})
|
||||
@ -116,7 +116,7 @@ func TestSealCommand_Run(t *testing.T) {
|
||||
t.Run("no_tabs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, cmd := testSealCommand(t)
|
||||
_, cmd := testOperatorSealCommand(t)
|
||||
assertNoTabs(t, cmd)
|
||||
})
|
||||
}
|
@ -8,23 +8,20 @@ import (
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// Ensure we are implementing the right interfaces.
|
||||
var _ cli.Command = (*StepDownCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*StepDownCommand)(nil)
|
||||
var _ cli.Command = (*OperatorStepDownCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*OperatorStepDownCommand)(nil)
|
||||
|
||||
// StepDownCommand is a Command that tells the Vault server to give up its
|
||||
// leadership
|
||||
type StepDownCommand struct {
|
||||
type OperatorStepDownCommand struct {
|
||||
*BaseCommand
|
||||
}
|
||||
|
||||
func (c *StepDownCommand) Synopsis() string {
|
||||
func (c *OperatorStepDownCommand) Synopsis() string {
|
||||
return "Forces Vault to resign active duty"
|
||||
}
|
||||
|
||||
func (c *StepDownCommand) Help() string {
|
||||
func (c *OperatorStepDownCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault step-down [options]
|
||||
Usage: vault operator step-down [options]
|
||||
|
||||
Forces the Vault server at the given address to step down from active duty.
|
||||
While the affected node will have a delay before attempting to acquire the
|
||||
@ -34,28 +31,26 @@ Usage: vault step-down [options]
|
||||
|
||||
Force Vault to step down as the leader:
|
||||
|
||||
$ vault step-down
|
||||
|
||||
For a full list of examples, please see the documentation.
|
||||
$ vault operator step-down
|
||||
|
||||
` + c.Flags().Help()
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *StepDownCommand) Flags() *FlagSets {
|
||||
func (c *OperatorStepDownCommand) Flags() *FlagSets {
|
||||
return c.flagSet(FlagSetHTTP)
|
||||
}
|
||||
|
||||
func (c *StepDownCommand) AutocompleteArgs() complete.Predictor {
|
||||
func (c *OperatorStepDownCommand) AutocompleteArgs() complete.Predictor {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *StepDownCommand) AutocompleteFlags() complete.Flags {
|
||||
func (c *OperatorStepDownCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *StepDownCommand) Run(args []string) int {
|
||||
func (c *OperatorStepDownCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
@ -7,18 +7,18 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testStepDownCommand(tb testing.TB) (*cli.MockUi, *StepDownCommand) {
|
||||
func testOperatorStepDownCommand(tb testing.TB) (*cli.MockUi, *OperatorStepDownCommand) {
|
||||
tb.Helper()
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
return ui, &StepDownCommand{
|
||||
return ui, &OperatorStepDownCommand{
|
||||
BaseCommand: &BaseCommand{
|
||||
UI: ui,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestStepDownCommand_Run(t *testing.T) {
|
||||
func TestOperatorStepDownCommand_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
@ -53,7 +53,7 @@ func TestStepDownCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testStepDownCommand(t)
|
||||
ui, cmd := testOperatorStepDownCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run(tc.args)
|
||||
@ -75,7 +75,7 @@ func TestStepDownCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerBad(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testStepDownCommand(t)
|
||||
ui, cmd := testOperatorStepDownCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{})
|
||||
@ -93,7 +93,7 @@ func TestStepDownCommand_Run(t *testing.T) {
|
||||
t.Run("no_tabs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, cmd := testStepDownCommand(t)
|
||||
_, cmd := testOperatorStepDownCommand(t)
|
||||
assertNoTabs(t, cmd)
|
||||
})
|
||||
}
|
@ -12,12 +12,10 @@ import (
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// Ensure we are implementing the right interfaces.
|
||||
var _ cli.Command = (*UnsealCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*UnsealCommand)(nil)
|
||||
var _ cli.Command = (*OperatorUnsealCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*OperatorUnsealCommand)(nil)
|
||||
|
||||
// UnsealCommand is a Command that unseals the vault.
|
||||
type UnsealCommand struct {
|
||||
type OperatorUnsealCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagReset bool
|
||||
@ -25,13 +23,13 @@ type UnsealCommand struct {
|
||||
testOutput io.Writer // for tests
|
||||
}
|
||||
|
||||
func (c *UnsealCommand) Synopsis() string {
|
||||
func (c *OperatorUnsealCommand) Synopsis() string {
|
||||
return "Unseals the Vault server"
|
||||
}
|
||||
|
||||
func (c *UnsealCommand) Help() string {
|
||||
func (c *OperatorUnsealCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault unseal [options] [KEY]
|
||||
Usage: vault operator unseal [options] [KEY]
|
||||
|
||||
Provide a portion of the master key to unseal a Vault server. Vault starts
|
||||
in a sealed state. It cannot perform operations until it is unsealed. This
|
||||
@ -40,21 +38,19 @@ Usage: vault unseal [options] [KEY]
|
||||
The unseal key can be supplied as an argument to the command, but this is
|
||||
not recommended as the unseal key will be available in your history:
|
||||
|
||||
$ vault unseal IXyR0OJnSFobekZMMCKCoVEpT7wI6l+USMzE3IcyDyo=
|
||||
$ vault operator unseal IXyR0OJnSFobekZMMCKCoVEpT7wI6l+USMzE3IcyDyo=
|
||||
|
||||
Instead, run the command with no arguments and it will prompt for the key:
|
||||
|
||||
$ vault unseal
|
||||
$ vault operator unseal
|
||||
Key (will be hidden): IXyR0OJnSFobekZMMCKCoVEpT7wI6l+USMzE3IcyDyo=
|
||||
|
||||
For a full list of examples, please see the documentation.
|
||||
|
||||
` + c.Flags().Help()
|
||||
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *UnsealCommand) Flags() *FlagSets {
|
||||
func (c *OperatorUnsealCommand) Flags() *FlagSets {
|
||||
set := c.flagSet(FlagSetHTTP)
|
||||
|
||||
f := set.NewFlagSet("Command Options")
|
||||
@ -72,15 +68,15 @@ func (c *UnsealCommand) Flags() *FlagSets {
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *UnsealCommand) AutocompleteArgs() complete.Predictor {
|
||||
func (c *OperatorUnsealCommand) AutocompleteArgs() complete.Predictor {
|
||||
return c.PredictVaultFiles()
|
||||
}
|
||||
|
||||
func (c *UnsealCommand) AutocompleteFlags() complete.Flags {
|
||||
func (c *OperatorUnsealCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *UnsealCommand) Run(args []string) int {
|
||||
func (c *OperatorUnsealCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
@ -151,7 +147,7 @@ func (c *UnsealCommand) Run(args []string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *UnsealCommand) prettySealStatus(status *api.SealStatusResponse) {
|
||||
func (c *OperatorUnsealCommand) prettySealStatus(status *api.SealStatusResponse) {
|
||||
c.UI.Output(fmt.Sprintf("Sealed: %t", status.Sealed))
|
||||
c.UI.Output(fmt.Sprintf("Key Shares: %d", status.N))
|
||||
c.UI.Output(fmt.Sprintf("Key Threshold: %d", status.T))
|
@ -9,24 +9,24 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testUnsealCommand(tb testing.TB) (*cli.MockUi, *UnsealCommand) {
|
||||
func testOperatorUnsealCommand(tb testing.TB) (*cli.MockUi, *OperatorUnsealCommand) {
|
||||
tb.Helper()
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
return ui, &UnsealCommand{
|
||||
return ui, &OperatorUnsealCommand{
|
||||
BaseCommand: &BaseCommand{
|
||||
UI: ui,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnsealCommand_Run(t *testing.T) {
|
||||
func TestOperatorUnsealCommand_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("error_non_terminal", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ui, cmd := testUnsealCommand(t)
|
||||
ui, cmd := testOperatorUnsealCommand(t)
|
||||
cmd.testOutput = ioutil.Discard
|
||||
|
||||
code := cmd.Run(nil)
|
||||
@ -57,7 +57,7 @@ func TestUnsealCommand_Run(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ui, cmd := testUnsealCommand(t)
|
||||
ui, cmd := testOperatorUnsealCommand(t)
|
||||
cmd.client = client
|
||||
cmd.testOutput = ioutil.Discard
|
||||
|
||||
@ -87,7 +87,7 @@ func TestUnsealCommand_Run(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, key := range keys {
|
||||
ui, cmd := testUnsealCommand(t)
|
||||
ui, cmd := testOperatorUnsealCommand(t)
|
||||
cmd.client = client
|
||||
cmd.testOutput = ioutil.Discard
|
||||
|
||||
@ -112,7 +112,7 @@ func TestUnsealCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerBad(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testUnsealCommand(t)
|
||||
ui, cmd := testOperatorUnsealCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{
|
||||
@ -132,7 +132,7 @@ func TestUnsealCommand_Run(t *testing.T) {
|
||||
t.Run("no_tabs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, cmd := testUnsealCommand(t)
|
||||
_, cmd := testOperatorUnsealCommand(t)
|
||||
assertNoTabs(t, cmd)
|
||||
})
|
||||
}
|
@ -8,20 +8,18 @@ import (
|
||||
"github.com/posener/complete"
|
||||
)
|
||||
|
||||
// Ensure we are implementing the right interfaces.
|
||||
var _ cli.Command = (*RotateCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*RotateCommand)(nil)
|
||||
var _ cli.Command = (*OperatorRotateCommand)(nil)
|
||||
var _ cli.CommandAutocomplete = (*OperatorRotateCommand)(nil)
|
||||
|
||||
// RotateCommand is a Command that rotates the encryption key being used
|
||||
type RotateCommand struct {
|
||||
type OperatorRotateCommand struct {
|
||||
*BaseCommand
|
||||
}
|
||||
|
||||
func (c *RotateCommand) Synopsis() string {
|
||||
func (c *OperatorRotateCommand) Synopsis() string {
|
||||
return "Rotates the underlying encryption key"
|
||||
}
|
||||
|
||||
func (c *RotateCommand) Help() string {
|
||||
func (c *OperatorRotateCommand) Help() string {
|
||||
helpText := `
|
||||
Usage: vault rotate [options]
|
||||
|
||||
@ -31,8 +29,8 @@ Usage: vault rotate [options]
|
||||
decrypt older data.
|
||||
|
||||
This is an online operation and does not cause downtime. This command is run
|
||||
per-cluser (not per-server), since Vault servers in HA mode share the same
|
||||
storeage backend.
|
||||
per-cluster (not per-server), since Vault servers in HA mode share the same
|
||||
storage backend.
|
||||
|
||||
Rotate Vault's encryption key:
|
||||
|
||||
@ -45,19 +43,19 @@ Usage: vault rotate [options]
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
||||
func (c *RotateCommand) Flags() *FlagSets {
|
||||
func (c *OperatorRotateCommand) Flags() *FlagSets {
|
||||
return c.flagSet(FlagSetHTTP)
|
||||
}
|
||||
|
||||
func (c *RotateCommand) AutocompleteArgs() complete.Predictor {
|
||||
func (c *OperatorRotateCommand) AutocompleteArgs() complete.Predictor {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *RotateCommand) AutocompleteFlags() complete.Flags {
|
||||
func (c *OperatorRotateCommand) AutocompleteFlags() complete.Flags {
|
||||
return c.Flags().Completions()
|
||||
}
|
||||
|
||||
func (c *RotateCommand) Run(args []string) int {
|
||||
func (c *OperatorRotateCommand) Run(args []string) int {
|
||||
f := c.Flags()
|
||||
|
||||
if err := f.Parse(args); err != nil {
|
||||
|
@ -7,18 +7,18 @@ import (
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func testRotateCommand(tb testing.TB) (*cli.MockUi, *RotateCommand) {
|
||||
func testOperatorRotateCommand(tb testing.TB) (*cli.MockUi, *OperatorRotateCommand) {
|
||||
tb.Helper()
|
||||
|
||||
ui := cli.NewMockUi()
|
||||
return ui, &RotateCommand{
|
||||
return ui, &OperatorRotateCommand{
|
||||
BaseCommand: &BaseCommand{
|
||||
UI: ui,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestRotateCommand_Run(t *testing.T) {
|
||||
func TestOperatorRotateCommand_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
@ -44,7 +44,7 @@ func TestRotateCommand_Run(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ui, cmd := testRotateCommand(t)
|
||||
ui, cmd := testOperatorRotateCommand(t)
|
||||
|
||||
code := cmd.Run(tc.args)
|
||||
if code != tc.code {
|
||||
@ -65,7 +65,7 @@ func TestRotateCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServer(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testRotateCommand(t)
|
||||
ui, cmd := testOperatorRotateCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{})
|
||||
@ -94,7 +94,7 @@ func TestRotateCommand_Run(t *testing.T) {
|
||||
client, closer := testVaultServerBad(t)
|
||||
defer closer()
|
||||
|
||||
ui, cmd := testRotateCommand(t)
|
||||
ui, cmd := testOperatorRotateCommand(t)
|
||||
cmd.client = client
|
||||
|
||||
code := cmd.Run([]string{})
|
||||
@ -112,7 +112,7 @@ func TestRotateCommand_Run(t *testing.T) {
|
||||
t.Run("no_tabs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, cmd := testRotateCommand(t)
|
||||
_, cmd := testOperatorRotateCommand(t)
|
||||
assertNoTabs(t, cmd)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user