forked from hashicorp/vault
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoperator_unseal.go
145 lines (114 loc) · 3.59 KB
/
operator_unseal.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package command
import (
"fmt"
"io"
"os"
"strings"
"github.com/hashicorp/vault/helper/password"
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
var _ cli.Command = (*OperatorUnsealCommand)(nil)
var _ cli.CommandAutocomplete = (*OperatorUnsealCommand)(nil)
type OperatorUnsealCommand struct {
*BaseCommand
flagReset bool
testOutput io.Writer // for tests
}
func (c *OperatorUnsealCommand) Synopsis() string {
return "Unseals the Vault server"
}
func (c *OperatorUnsealCommand) Help() string {
helpText := `
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
command accepts a portion of the master key (an "unseal 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 operator unseal IXyR0OJnSFobekZMMCKCoVEpT7wI6l+USMzE3IcyDyo=
Instead, run the command with no arguments and it will prompt for the key:
$ vault operator unseal
Key (will be hidden): IXyR0OJnSFobekZMMCKCoVEpT7wI6l+USMzE3IcyDyo=
` + c.Flags().Help()
return strings.TrimSpace(helpText)
}
func (c *OperatorUnsealCommand) Flags() *FlagSets {
set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
f := set.NewFlagSet("Command Options")
f.BoolVar(&BoolVar{
Name: "reset",
Aliases: []string{},
Target: &c.flagReset,
Default: false,
EnvVar: "",
Completion: complete.PredictNothing,
Usage: "Discard any previously entered keys to the unseal process.",
})
return set
}
func (c *OperatorUnsealCommand) AutocompleteArgs() complete.Predictor {
return complete.PredictAnything
}
func (c *OperatorUnsealCommand) AutocompleteFlags() complete.Flags {
return c.Flags().Completions()
}
func (c *OperatorUnsealCommand) Run(args []string) int {
f := c.Flags()
if err := f.Parse(args); err != nil {
c.UI.Error(err.Error())
return 1
}
unsealKey := ""
args = f.Args()
switch len(args) {
case 0:
// We will prompt for the unsealKey later
case 1:
unsealKey = strings.TrimSpace(args[0])
default:
c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args)))
return 1
}
client, err := c.Client()
if err != nil {
c.UI.Error(err.Error())
return 2
}
if c.flagReset {
status, err := client.Sys().ResetUnsealProcess()
if err != nil {
c.UI.Error(fmt.Sprintf("Error resetting unseal process: %s", err))
return 2
}
return OutputSealStatus(c.UI, client, status)
}
if unsealKey == "" {
// Override the output
writer := (io.Writer)(os.Stdout)
if c.testOutput != nil {
writer = c.testOutput
}
fmt.Fprintf(writer, "Unseal Key (will be hidden): ")
value, err := password.Read(os.Stdin)
fmt.Fprintf(writer, "\n")
if err != nil {
c.UI.Error(wrapAtLength(fmt.Sprintf("An error occurred attempting to "+
"ask for an unseal key. The raw error message is shown below, but "+
"usually this is because you attempted to pipe a value into the "+
"unseal command or you are executing outside of a terminal (tty). "+
"You should run the unseal command from a terminal for maximum "+
"security. If this is not an option, the unseal can be provided as "+
"the first argument to the unseal command. The raw error "+
"was:\n\n%s", err)))
return 1
}
unsealKey = strings.TrimSpace(value)
}
status, err := client.Sys().Unseal(unsealKey)
if err != nil {
c.UI.Error(fmt.Sprintf("Error unsealing: %s", err))
return 2
}
return OutputSealStatus(c.UI, client, status)
}