-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
meta.go
208 lines (175 loc) · 6.26 KB
/
meta.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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package meta
import (
"bufio"
"flag"
"io"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/command/token"
"github.com/mitchellh/cli"
)
// FlagSetFlags is an enum to define what flags are present in the
// default FlagSet returned by Meta.FlagSet.
type FlagSetFlags uint
type TokenHelperFunc func() (token.TokenHelper, error)
const (
FlagSetNone FlagSetFlags = 0
FlagSetServer FlagSetFlags = 1 << iota
FlagSetDefault = FlagSetServer
)
var (
additionalOptionsUsage = func() string {
return `
-wrap-ttl="" Indicates that the response should be wrapped in a
cubbyhole token with the requested TTL. The response
can be fetched by calling the "sys/wrapping/unwrap"
endpoint, passing in the wrapping token's ID. This
is a numeric string with an optional suffix
"s", "m", or "h"; if no suffix is specified it will
be parsed as seconds. May also be specified via
VAULT_WRAP_TTL.
`
}
)
// Meta contains the meta-options and functionality that nearly every
// Vault command inherits.
type Meta struct {
ClientToken string
Ui cli.Ui
// The things below can be set, but aren't common
ForceAddress string // Address to force for API clients
// These are set by the command line flags.
flagAddress string
flagCACert string
flagCAPath string
flagClientCert string
flagClientKey string
flagWrapTTL string
flagInsecure bool
// Queried if no token can be found
TokenHelper TokenHelperFunc
}
func (m *Meta) DefaultWrappingLookupFunc(operation, path string) string {
if m.flagWrapTTL != "" {
return m.flagWrapTTL
}
return api.DefaultWrappingLookupFunc(operation, path)
}
// Client returns the API client to a Vault server given the configured
// flag settings for this command.
func (m *Meta) Client() (*api.Client, error) {
config := api.DefaultConfig()
err := config.ReadEnvironment()
if err != nil {
return nil, errwrap.Wrapf("error reading environment: {{err}}", err)
}
if m.flagAddress != "" {
config.Address = m.flagAddress
}
if m.ForceAddress != "" {
config.Address = m.ForceAddress
}
// If we need custom TLS configuration, then set it
if m.flagCACert != "" || m.flagCAPath != "" || m.flagClientCert != "" || m.flagClientKey != "" || m.flagInsecure {
t := &api.TLSConfig{
CACert: m.flagCACert,
CAPath: m.flagCAPath,
ClientCert: m.flagClientCert,
ClientKey: m.flagClientKey,
TLSServerName: "",
Insecure: m.flagInsecure,
}
config.ConfigureTLS(t)
}
// Build the client
client, err := api.NewClient(config)
if err != nil {
return nil, err
}
client.SetWrappingLookupFunc(m.DefaultWrappingLookupFunc)
// If we have a token directly, then set that
token := m.ClientToken
// Try to set the token to what is already stored
if token == "" {
token = client.Token()
}
// If we don't have a token, check the token helper
if token == "" {
if m.TokenHelper != nil {
// If we have a token, then set that
tokenHelper, err := m.TokenHelper()
if err != nil {
return nil, err
}
token, err = tokenHelper.Get()
if err != nil {
return nil, err
}
}
}
// Set the token
if token != "" {
client.SetToken(token)
}
return client, nil
}
// FlagSet returns a FlagSet with the common flags that every
// command implements. The exact behavior of FlagSet can be configured
// using the flags as the second parameter, for example to disable
// server settings on the commands that don't talk to a server.
func (m *Meta) FlagSet(n string, fs FlagSetFlags) *flag.FlagSet {
f := flag.NewFlagSet(n, flag.ContinueOnError)
// FlagSetServer tells us to enable the settings for selecting
// the server information.
if fs&FlagSetServer != 0 {
f.StringVar(&m.flagAddress, "address", "", "")
f.StringVar(&m.flagCACert, "ca-cert", "", "")
f.StringVar(&m.flagCAPath, "ca-path", "", "")
f.StringVar(&m.flagClientCert, "client-cert", "", "")
f.StringVar(&m.flagClientKey, "client-key", "", "")
f.StringVar(&m.flagWrapTTL, "wrap-ttl", "", "")
f.BoolVar(&m.flagInsecure, "insecure", false, "")
f.BoolVar(&m.flagInsecure, "tls-skip-verify", false, "")
}
// Create an io.Writer that writes to our Ui properly for errors.
// This is kind of a hack, but it does the job. Basically: create
// a pipe, use a scanner to break it into lines, and output each line
// to the UI. Do this forever.
errR, errW := io.Pipe()
errScanner := bufio.NewScanner(errR)
go func() {
for errScanner.Scan() {
m.Ui.Error(errScanner.Text())
}
}()
f.SetOutput(errW)
return f
}
// GeneralOptionsUsage returns the usage documentation for commonly
// available options
func GeneralOptionsUsage() string {
general := `
-address=addr The address of the Vault server.
Overrides the VAULT_ADDR environment variable if set.
-ca-cert=path Path to a PEM encoded CA cert file to use to
verify the Vault server SSL certificate.
Overrides the VAULT_CACERT environment variable if set.
-ca-path=path Path to a directory of PEM encoded CA cert files
to verify the Vault server SSL certificate. If both
-ca-cert and -ca-path are specified, -ca-cert is used.
Overrides the VAULT_CAPATH environment variable if set.
-client-cert=path Path to a PEM encoded client certificate for TLS
authentication to the Vault server. Must also specify
-client-key. Overrides the VAULT_CLIENT_CERT
environment variable if set.
-client-key=path Path to an unencrypted PEM encoded private key
matching the client certificate from -client-cert.
Overrides the VAULT_CLIENT_KEY environment variable
if set.
-tls-skip-verify Do not verify TLS certificate. This is highly
not recommended. Verification will also be skipped
if VAULT_SKIP_VERIFY is set.
`
general += additionalOptionsUsage()
return general
}