/
system_view.go
287 lines (225 loc) · 10.3 KB
/
system_view.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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package logical
import (
"context"
"errors"
"fmt"
"io"
"time"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/license"
"github.com/hashicorp/vault/sdk/helper/pluginutil"
"github.com/hashicorp/vault/sdk/helper/wrapping"
)
// SystemView exposes system configuration information in a safe way
// for logical backends to consume
type SystemView interface {
// DefaultLeaseTTL returns the default lease TTL set in Vault configuration
DefaultLeaseTTL() time.Duration
// MaxLeaseTTL returns the max lease TTL set in Vault configuration; backend
// authors should take care not to issue credentials that last longer than
// this value, as Vault will revoke them
MaxLeaseTTL() time.Duration
// Returns true if the mount is tainted. A mount is tainted if it is in the
// process of being unmounted. This should only be used in special
// circumstances; a primary use-case is as a guard in revocation functions.
// If revocation of a backend's leases fails it can keep the unmounting
// process from being successful. If the reason for this failure is not
// relevant when the mount is tainted (for instance, saving a CRL to disk
// when the stored CRL will be removed during the unmounting process
// anyways), we can ignore the errors to allow unmounting to complete.
Tainted() bool
// Returns true if caching is disabled. If true, no caches should be used,
// despite known slowdowns.
CachingDisabled() bool
// When run from a system view attached to a request, indicates whether the
// request is affecting a local mount or not
LocalMount() bool
// ReplicationState indicates the state of cluster replication
ReplicationState() consts.ReplicationState
// HasFeature returns true if the feature is currently enabled
HasFeature(feature license.Features) bool
// ResponseWrapData wraps the given data in a cubbyhole and returns the
// token used to unwrap.
ResponseWrapData(ctx context.Context, data map[string]interface{}, ttl time.Duration, jwt bool) (*wrapping.ResponseWrapInfo, error)
// LookupPlugin looks into the plugin catalog for a plugin with the given
// name. Returns a PluginRunner or an error if a plugin can not be found.
LookupPlugin(ctx context.Context, pluginName string, pluginType consts.PluginType) (*pluginutil.PluginRunner, error)
// LookupPluginVersion looks into the plugin catalog for a plugin with the given
// name and version. Returns a PluginRunner or an error if a plugin can not be found.
LookupPluginVersion(ctx context.Context, pluginName string, pluginType consts.PluginType, version string) (*pluginutil.PluginRunner, error)
// ListVersionedPlugins returns information about all plugins of a certain
// type in the catalog, including any versioning information stored for them.
ListVersionedPlugins(ctx context.Context, pluginType consts.PluginType) ([]pluginutil.VersionedPlugin, error)
// NewPluginClient returns a client for managing the lifecycle of plugin
// processes
NewPluginClient(ctx context.Context, config pluginutil.PluginClientConfig) (pluginutil.PluginClient, error)
// MlockEnabled returns the configuration setting for enabling mlock on
// plugins.
MlockEnabled() bool
// EntityInfo returns a subset of information related to the identity entity
// for the given entity id
EntityInfo(entityID string) (*Entity, error)
// GroupsForEntity returns the group membership information for the provided
// entity id
GroupsForEntity(entityID string) ([]*Group, error)
// PluginEnv returns Vault environment information used by plugins
PluginEnv(context.Context) (*PluginEnvironment, error)
// VaultVersion returns the version string for the currently running Vault.
VaultVersion(context.Context) (string, error)
// GeneratePasswordFromPolicy generates a password from the policy referenced.
// If the policy does not exist, this will return an error.
GeneratePasswordFromPolicy(ctx context.Context, policyName string) (password string, err error)
// ClusterID returns the replication ClusterID, for use with path-based
// write forwarding (WriteForwardedPaths). This value will be templated
// in for the {{cluterId}} sentinel.
ClusterID(ctx context.Context) (string, error)
// GenerateIdentityToken returns an identity token for the requesting plugin.
GenerateIdentityToken(ctx context.Context, req *pluginutil.IdentityTokenRequest) (*pluginutil.IdentityTokenResponse, error)
}
type PasswordPolicy interface {
// Generate a random password
Generate(context.Context, io.Reader) (string, error)
}
type WellKnownSystemView interface {
// RequestWellKnownRedirect registers a redirect from .well-known/src
// to dest, where dest is a sub-path of the mount. An error
// is returned if that source path is already taken
RequestWellKnownRedirect(ctx context.Context, src, dest string) error
// DeregisterWellKnownRedirect unregisters a specific redirect. Returns
// true if that redirect source was found
DeregisterWellKnownRedirect(ctx context.Context, src string) bool
}
type ExtendedSystemView interface {
WellKnownSystemView
Auditor() Auditor
ForwardGenericRequest(context.Context, *Request) (*Response, error)
// APILockShouldBlockRequest returns whether a namespace for the requested
// mount is locked and should be blocked
APILockShouldBlockRequest() (bool, error)
// GetPinnedPluginVersion returns the pinned version for the given plugin, if any.
GetPinnedPluginVersion(ctx context.Context, pluginType consts.PluginType, pluginName string) (*pluginutil.PinnedVersion, error)
}
type PasswordGenerator func() (password string, err error)
type StaticSystemView struct {
DefaultLeaseTTLVal time.Duration
MaxLeaseTTLVal time.Duration
SudoPrivilegeVal bool
TaintedVal bool
CachingDisabledVal bool
Primary bool
EnableMlock bool
LocalMountVal bool
ReplicationStateVal consts.ReplicationState
EntityVal *Entity
GroupsVal []*Group
Features license.Features
PluginEnvironment *PluginEnvironment
PasswordPolicies map[string]PasswordGenerator
VersionString string
ClusterUUID string
APILockShouldBlockRequestVal bool
}
type noopAuditor struct{}
func (a noopAuditor) AuditRequest(ctx context.Context, input *LogInput) error {
return nil
}
func (a noopAuditor) AuditResponse(ctx context.Context, input *LogInput) error {
return nil
}
func (d StaticSystemView) Auditor() Auditor {
return noopAuditor{}
}
func (d StaticSystemView) ForwardGenericRequest(ctx context.Context, req *Request) (*Response, error) {
return nil, errors.New("ForwardGenericRequest is not implemented in StaticSystemView")
}
func (d StaticSystemView) DefaultLeaseTTL() time.Duration {
return d.DefaultLeaseTTLVal
}
func (d StaticSystemView) MaxLeaseTTL() time.Duration {
return d.MaxLeaseTTLVal
}
func (d StaticSystemView) SudoPrivilege(_ context.Context, path string, token string) bool {
return d.SudoPrivilegeVal
}
func (d StaticSystemView) Tainted() bool {
return d.TaintedVal
}
func (d StaticSystemView) CachingDisabled() bool {
return d.CachingDisabledVal
}
func (d StaticSystemView) LocalMount() bool {
return d.LocalMountVal
}
func (d StaticSystemView) ReplicationState() consts.ReplicationState {
return d.ReplicationStateVal
}
func (d StaticSystemView) NewPluginClient(ctx context.Context, config pluginutil.PluginClientConfig) (pluginutil.PluginClient, error) {
return nil, errors.New("NewPluginClient is not implemented in StaticSystemView")
}
func (d StaticSystemView) ResponseWrapData(_ context.Context, data map[string]interface{}, ttl time.Duration, jwt bool) (*wrapping.ResponseWrapInfo, error) {
return nil, errors.New("ResponseWrapData is not implemented in StaticSystemView")
}
func (d StaticSystemView) LookupPlugin(_ context.Context, _ string, _ consts.PluginType) (*pluginutil.PluginRunner, error) {
return nil, errors.New("LookupPlugin is not implemented in StaticSystemView")
}
func (d StaticSystemView) LookupPluginVersion(_ context.Context, _ string, _ consts.PluginType, _ string) (*pluginutil.PluginRunner, error) {
return nil, errors.New("LookupPluginVersion is not implemented in StaticSystemView")
}
func (d StaticSystemView) ListVersionedPlugins(_ context.Context, _ consts.PluginType) ([]pluginutil.VersionedPlugin, error) {
return nil, errors.New("ListVersionedPlugins is not implemented in StaticSystemView")
}
func (d StaticSystemView) MlockEnabled() bool {
return d.EnableMlock
}
func (d StaticSystemView) EntityInfo(entityID string) (*Entity, error) {
return d.EntityVal, nil
}
func (d StaticSystemView) GroupsForEntity(entityID string) ([]*Group, error) {
return d.GroupsVal, nil
}
func (d StaticSystemView) HasFeature(feature license.Features) bool {
return d.Features.HasFeature(feature)
}
func (d StaticSystemView) PluginEnv(_ context.Context) (*PluginEnvironment, error) {
return d.PluginEnvironment, nil
}
func (d StaticSystemView) VaultVersion(_ context.Context) (string, error) {
return d.VersionString, nil
}
func (d StaticSystemView) GeneratePasswordFromPolicy(ctx context.Context, policyName string) (password string, err error) {
select {
case <-ctx.Done():
return "", fmt.Errorf("context timed out")
default:
}
if d.PasswordPolicies == nil {
return "", fmt.Errorf("password policy not found")
}
policy, exists := d.PasswordPolicies[policyName]
if !exists {
return "", fmt.Errorf("password policy not found")
}
return policy()
}
func (d *StaticSystemView) SetPasswordPolicy(name string, generator PasswordGenerator) {
if d.PasswordPolicies == nil {
d.PasswordPolicies = map[string]PasswordGenerator{}
}
d.PasswordPolicies[name] = generator
}
func (d *StaticSystemView) DeletePasswordPolicy(name string) (existed bool) {
_, existed = d.PasswordPolicies[name]
delete(d.PasswordPolicies, name)
return existed
}
func (d StaticSystemView) ClusterID(ctx context.Context) (string, error) {
return d.ClusterUUID, nil
}
func (d StaticSystemView) GenerateIdentityToken(_ context.Context, _ *pluginutil.IdentityTokenRequest) (*pluginutil.IdentityTokenResponse, error) {
return nil, errors.New("GenerateIdentityToken is not implemented in StaticSystemView")
}
func (d StaticSystemView) APILockShouldBlockRequest() (bool, error) {
return d.APILockShouldBlockRequestVal, nil
}