forked from hashicorp/vault
-
Notifications
You must be signed in to change notification settings - Fork 0
/
secret-engine.js
205 lines (189 loc) · 6.57 KB
/
secret-engine.js
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
import Model, { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import { fragment } from 'ember-data-model-fragments/attributes';
import fieldToAttrs, { expandAttributeMeta } from 'vault/utils/field-to-attrs';
import { validator, buildValidations } from 'ember-cp-validations';
//identity will be managed separately and the inclusion
//of the system backend is an implementation detail
const LIST_EXCLUDED_BACKENDS = ['system', 'identity'];
const Validations = buildValidations({
path: validator('presence', {
presence: true,
message: "Path can't be blank.",
}),
maxVersions: [
validator('number', {
allowString: true,
integer: true,
message: 'Maximum versions must be a number.',
}),
validator('length', {
min: 1,
max: 16,
message: 'You cannot go over 16 characters.',
}),
],
});
export default Model.extend(Validations, {
path: attr('string'),
accessor: attr('string'),
name: attr('string'),
type: attr('string', {
label: 'Secret engine type',
}),
description: attr('string', {
editType: 'textarea',
}),
config: fragment('mount-config', { defaultValue: {} }),
options: fragment('mount-options', { defaultValue: {} }),
local: attr('boolean', {
helpText:
'When Replication is enabled, a local mount will not be replicated across clusters. This can only be specified at mount time.',
}),
sealWrap: attr('boolean', {
helpText:
'When enabled - if a seal supporting seal wrapping is specified in the configuration, all critical security parameters (CSPs) in this backend will be seal wrapped. (For K/V mounts, all values will be seal wrapped.) This can only be specified at mount time.',
}),
// KV 2 additional config default options
maxVersions: attr('number', {
defaultValue: 0,
label: 'Maximum number of versions',
subText:
'The number of versions to keep per key. Once the number of keys exceeds the maximum number set here, the oldest version will be permanently deleted. This value applies to all keys, but a key’s metadata settings can overwrite this value. When 0 is used or the value is unset, Vault will keep 10 versions.',
}),
casRequired: attr('boolean', {
defaultValue: false,
label: 'Require Check and Set',
subText:
'If checked, all keys will require the cas parameter to be set on all write requests. A key’s metadata settings can overwrite this value.',
}),
deleteVersionAfter: attr({
defaultValue: 0,
editType: 'ttl',
label: 'Automate secret deletion',
helperTextDisabled: 'A secret’s version must be manually deleted.',
helperTextEnabled: 'Delete all new versions of this secret after',
}),
modelTypeForKV: computed('engineType', 'options.version', function() {
let type = this.engineType;
let version = this.options?.version;
let modelType = 'secret';
if ((type === 'kv' || type === 'generic') && version === 2) {
modelType = 'secret-v2';
}
return modelType;
}),
isV2KV: computed.equal('modelTypeForKV', 'secret-v2'),
formFields: computed('engineType', 'options.version', function() {
let type = this.engineType;
let version = this.options?.version;
let fields = [
'type',
'path',
'description',
'accessor',
'local',
'sealWrap',
'config.{defaultLeaseTtl,maxLeaseTtl,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
];
if (type === 'kv' || type === 'generic') {
fields.push('options.{version}');
}
// version comes in as number not string
if (type === 'kv' && version === 2) {
fields.push('casRequired', 'deleteVersionAfter', 'maxVersions');
}
return fields;
}),
formFieldGroups: computed('engineType', function() {
let type = this.engineType;
let defaultGroup;
// KV has specific config options it adds on the enable engine. https://www.vaultproject.io/api/secret/kv/kv-v2#configure-the-kv-engine
if (type === 'kv') {
defaultGroup = { default: ['path', 'maxVersions', 'casRequired', 'deleteVersionAfter'] };
} else {
defaultGroup = { default: ['path'] };
}
let optionsGroup = {
'Method Options': [
'description',
'config.listingVisibility',
'local',
'sealWrap',
'config.{defaultLeaseTtl,maxLeaseTtl,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
],
};
if (type === 'kv' || type === 'generic') {
optionsGroup['Method Options'].unshift('options.{version}');
}
if (type === 'database') {
// For the Database Secret Engine we want to highlight the defaultLeaseTtl and maxLeaseTtl, removing them from the options object
defaultGroup.default.push('config.{defaultLeaseTtl}', 'config.{maxLeaseTtl}');
return [
defaultGroup,
{
'Method Options': [
'description',
'config.listingVisibility',
'local',
'sealWrap',
'config.{auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
],
},
];
}
return [defaultGroup, optionsGroup];
}),
attrs: computed('formFields', function() {
return expandAttributeMeta(this, this.formFields);
}),
fieldGroups: computed('formFieldGroups', function() {
return fieldToAttrs(this, this.formFieldGroups);
}),
// namespaces introduced types with a `ns_` prefix for built-in engines
// so we need to strip that to normalize the type
engineType: computed('type', function() {
return (this.type || '').replace(/^ns_/, '');
}),
shouldIncludeInList: computed('engineType', function() {
return !LIST_EXCLUDED_BACKENDS.includes(this.engineType);
}),
localDisplay: computed('local', function() {
return this.local ? 'local' : 'replicated';
}),
// ssh specific ones
privateKey: attr('string'),
publicKey: attr('string'),
generateSigningKey: attr('boolean', {
defaultValue: true,
}),
saveCA(options) {
if (this.type !== 'ssh') {
return;
}
if (options.isDelete) {
this.setProperties({
privateKey: null,
publicKey: null,
generateSigningKey: false,
});
}
return this.save({
adapterOptions: {
options: options,
apiPath: 'config/ca',
attrsToSend: ['privateKey', 'publicKey', 'generateSigningKey'],
},
});
},
saveZeroAddressConfig() {
return this.save({
adapterOptions: {
adapterMethod: 'saveZeroAddressConfig',
},
});
},
// aws backend attrs
lease: attr('string'),
leaseMax: attr('string'),
});