node-vault-client 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +200 -200
- package/README.md +153 -153
- package/package.json +44 -42
- package/src/Lease.js +57 -57
- package/src/VaultApiClient.js +55 -55
- package/src/VaultClient.js +263 -266
- package/src/VaultNodeConfig.js +105 -105
- package/src/auth/AuthToken.js +94 -94
- package/src/auth/VaultAppRoleAuth.js +40 -40
- package/src/auth/VaultBaseAuth.js +140 -140
- package/src/auth/VaultIAMAuth.js +187 -187
- package/src/auth/VaultKubernetesAuth.js +48 -48
- package/src/auth/VaultTokenAuth.js +34 -34
- package/src/errors.js +21 -21
package/src/VaultClient.js
CHANGED
|
@@ -1,266 +1,263 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const _ = require('lodash');
|
|
4
|
-
const Lease = require('./Lease');
|
|
5
|
-
const errors = require('./errors');
|
|
6
|
-
const VaultApiClient = require('./VaultApiClient');
|
|
7
|
-
const VaultAppRoleAuth = require('./auth/VaultAppRoleAuth');
|
|
8
|
-
const VaultTokenAuth = require('./auth/VaultTokenAuth');
|
|
9
|
-
const VaultIAMAuth = require('./auth/VaultIAMAuth');
|
|
10
|
-
const VaultNodeConfig = require('./VaultNodeConfig');
|
|
11
|
-
const VaultKubernetesAuth = require('./auth/VaultKubernetesAuth');
|
|
12
|
-
const vaultInstances = {};
|
|
13
|
-
|
|
14
|
-
class VaultClient {
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Client constructor function.
|
|
18
|
-
*
|
|
19
|
-
* @param {Object} options
|
|
20
|
-
* @param {Object} options.api
|
|
21
|
-
* @param {String} options.api.url - the url of the vault server
|
|
22
|
-
* @param {String} [options.api.apiVersion='v1']
|
|
23
|
-
* @param {Object} options.auth
|
|
24
|
-
* @param {String} options.auth.type
|
|
25
|
-
* @param {Object} options.auth.config - auth configuration variables
|
|
26
|
-
* @param {Object|false} options.logger - Logger that supports "error", "info", "warn", "trace", "debug" methods. Uses `console` by default. Pass `false` to disable logging.
|
|
27
|
-
*/
|
|
28
|
-
constructor(options) {
|
|
29
|
-
this.__log = this.__setupLogger(options.logger);
|
|
30
|
-
|
|
31
|
-
this.__api = new VaultApiClient(
|
|
32
|
-
options.api,
|
|
33
|
-
this.__log
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @type {VaultBaseAuth}
|
|
38
|
-
* @private
|
|
39
|
-
*/
|
|
40
|
-
this.__auth = this.__getAuthProvider(
|
|
41
|
-
options.auth,
|
|
42
|
-
this.__api
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
this.__namespace = options.auth.config.namespace;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Boot an instance of Vault
|
|
50
|
-
*
|
|
51
|
-
* The instance will be stored in a local hash. Calling Vault.boot multiple
|
|
52
|
-
* times with the same name will return the same instance.
|
|
53
|
-
*
|
|
54
|
-
* @param {String} name - Vault instance name
|
|
55
|
-
* @param {Object} [options] - options for {@link Vault#constructor}.
|
|
56
|
-
* @return Vault
|
|
57
|
-
*/
|
|
58
|
-
static boot(name, options) {
|
|
59
|
-
if (options === undefined) {
|
|
60
|
-
throw new errors.InvalidArgumentsError('Options should be provided');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
let instance = vaultInstances[name];
|
|
64
|
-
if (instance === undefined) {
|
|
65
|
-
vaultInstances[name] = instance = new VaultClient(options);
|
|
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
|
-
* @param {Object} authConfig
|
|
115
|
-
* @param {
|
|
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
|
-
module.exports = VaultClient;
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const Lease = require('./Lease');
|
|
5
|
+
const errors = require('./errors');
|
|
6
|
+
const VaultApiClient = require('./VaultApiClient');
|
|
7
|
+
const VaultAppRoleAuth = require('./auth/VaultAppRoleAuth');
|
|
8
|
+
const VaultTokenAuth = require('./auth/VaultTokenAuth');
|
|
9
|
+
const VaultIAMAuth = require('./auth/VaultIAMAuth');
|
|
10
|
+
const VaultNodeConfig = require('./VaultNodeConfig');
|
|
11
|
+
const VaultKubernetesAuth = require('./auth/VaultKubernetesAuth');
|
|
12
|
+
const vaultInstances = {};
|
|
13
|
+
|
|
14
|
+
class VaultClient {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Client constructor function.
|
|
18
|
+
*
|
|
19
|
+
* @param {Object} options
|
|
20
|
+
* @param {Object} options.api
|
|
21
|
+
* @param {String} options.api.url - the url of the vault server
|
|
22
|
+
* @param {String} [options.api.apiVersion='v1']
|
|
23
|
+
* @param {Object} options.auth
|
|
24
|
+
* @param {String} options.auth.type
|
|
25
|
+
* @param {Object} options.auth.config - auth configuration variables
|
|
26
|
+
* @param {Object|false} options.logger - Logger that supports "error", "info", "warn", "trace", "debug" methods. Uses `console` by default. Pass `false` to disable logging.
|
|
27
|
+
*/
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.__log = this.__setupLogger(options.logger);
|
|
30
|
+
|
|
31
|
+
this.__api = new VaultApiClient(
|
|
32
|
+
options.api,
|
|
33
|
+
this.__log
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @type {VaultBaseAuth}
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
this.__auth = this.__getAuthProvider(
|
|
41
|
+
options.auth,
|
|
42
|
+
this.__api
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
this.__namespace = options.auth.config.namespace;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Boot an instance of Vault
|
|
50
|
+
*
|
|
51
|
+
* The instance will be stored in a local hash. Calling Vault.boot multiple
|
|
52
|
+
* times with the same name will return the same instance.
|
|
53
|
+
*
|
|
54
|
+
* @param {String} name - Vault instance name
|
|
55
|
+
* @param {Object} [options] - options for {@link Vault#constructor}.
|
|
56
|
+
* @return Vault
|
|
57
|
+
*/
|
|
58
|
+
static boot(name, options) {
|
|
59
|
+
if (options === undefined) {
|
|
60
|
+
throw new errors.InvalidArgumentsError('Options should be provided');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let instance = vaultInstances[name];
|
|
64
|
+
if (instance === undefined) {
|
|
65
|
+
vaultInstances[name] = instance = new VaultClient(options);
|
|
66
|
+
}
|
|
67
|
+
return instance;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get an instance of Vault
|
|
72
|
+
*
|
|
73
|
+
* The instance will be stored in a local hash. Calling Vault.pop multiple
|
|
74
|
+
* times with the same name will return the same instance.
|
|
75
|
+
*
|
|
76
|
+
* @param {String} name - Vault instance name
|
|
77
|
+
* @return Vault
|
|
78
|
+
*/
|
|
79
|
+
static get(name) {
|
|
80
|
+
let instance = vaultInstances[name];
|
|
81
|
+
|
|
82
|
+
if (instance === undefined) {
|
|
83
|
+
throw new errors.InvalidArgumentsError('Invalid instance name');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return instance;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Clear named Vault instance
|
|
91
|
+
*
|
|
92
|
+
* If no name passed all named instances will be cleared.
|
|
93
|
+
*
|
|
94
|
+
* @param {String} [name] - Vault instance name, all instances will be cleared if no name were passed
|
|
95
|
+
*/
|
|
96
|
+
static clear(name) {
|
|
97
|
+
if (typeof name === 'string') {
|
|
98
|
+
delete vaultInstances[name];
|
|
99
|
+
} else {
|
|
100
|
+
for (let k in vaultInstances) {
|
|
101
|
+
if (vaultInstances.hasOwnProperty(k)) {
|
|
102
|
+
delete vaultInstances[k];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @protected
|
|
110
|
+
*
|
|
111
|
+
* @param {Object} authConfig
|
|
112
|
+
* @param {string} authConfig.type
|
|
113
|
+
* @param {string} authConfig.mount
|
|
114
|
+
* @param {Object} authConfig.config
|
|
115
|
+
* @param {VaultApiClient} api
|
|
116
|
+
* @return {VaultBaseAuth}
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
__getAuthProvider(authConfig, api) {
|
|
120
|
+
this.__log.debug('creating vault auth method: "%s"', authConfig.type);
|
|
121
|
+
|
|
122
|
+
switch (authConfig.type) {
|
|
123
|
+
case 'iam':
|
|
124
|
+
return new VaultIAMAuth(
|
|
125
|
+
api,
|
|
126
|
+
this.__log,
|
|
127
|
+
authConfig.config,
|
|
128
|
+
authConfig.mount
|
|
129
|
+
);
|
|
130
|
+
case 'appRole':
|
|
131
|
+
return new VaultAppRoleAuth(
|
|
132
|
+
api,
|
|
133
|
+
this.__log,
|
|
134
|
+
authConfig.config,
|
|
135
|
+
authConfig.mount
|
|
136
|
+
);
|
|
137
|
+
case 'token':
|
|
138
|
+
return new VaultTokenAuth(
|
|
139
|
+
api,
|
|
140
|
+
this.__log,
|
|
141
|
+
authConfig.config,
|
|
142
|
+
authConfig.mount
|
|
143
|
+
);
|
|
144
|
+
case 'kubernetes':
|
|
145
|
+
return new VaultKubernetesAuth(
|
|
146
|
+
api,
|
|
147
|
+
this.__log,
|
|
148
|
+
authConfig.config,
|
|
149
|
+
authConfig.mount
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
throw new errors.InvalidArgumentsError('Unsupported auth method')
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Populates Vault's values to NPM "config" module
|
|
158
|
+
*/
|
|
159
|
+
fillNodeConfig() {
|
|
160
|
+
const vaultConf = new VaultNodeConfig(this);
|
|
161
|
+
|
|
162
|
+
return vaultConf.populate();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
getHeaders(token) {
|
|
166
|
+
if (this.__namespace) {
|
|
167
|
+
return {
|
|
168
|
+
'X-Vault-Token': token.getId(),
|
|
169
|
+
'X-Vault-Namespace': this.__namespace
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return {'X-Vault-Token': token.getId()}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Read secret from Vault
|
|
178
|
+
* @param {string} path - path to the secret
|
|
179
|
+
* @returns {Promise<Lease>}
|
|
180
|
+
*/
|
|
181
|
+
read(path) {
|
|
182
|
+
this.__log.debug('read secret %s', path);
|
|
183
|
+
return this.__auth.getAuthToken()
|
|
184
|
+
.then(token => this.__api.makeRequest('GET', path, null, this.getHeaders(token)))
|
|
185
|
+
.then(res => {
|
|
186
|
+
this.__log.debug('receive secret %s', path);
|
|
187
|
+
return Lease.fromResponse(res);
|
|
188
|
+
})
|
|
189
|
+
.catch((reason) => {
|
|
190
|
+
this.__log.error('read secret failed: %s', reason.message);
|
|
191
|
+
throw reason;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Retrieves secrets list
|
|
197
|
+
*
|
|
198
|
+
* @param {string} path - path to the secret
|
|
199
|
+
* @returns {Promise<Lease>}
|
|
200
|
+
*/
|
|
201
|
+
list(path) {
|
|
202
|
+
this.__log.debug('list secrets %s', path);
|
|
203
|
+
return this.__auth.getAuthToken()
|
|
204
|
+
.then(token => this.__api.makeRequest('LIST', path, null, this.getHeaders(token)))
|
|
205
|
+
.then(res => {
|
|
206
|
+
this.__log.debug('got secrets list %s', path);
|
|
207
|
+
return Lease.fromResponse(res);
|
|
208
|
+
})
|
|
209
|
+
.catch((reason) => {
|
|
210
|
+
this.__log.error('list secrets failed: %s', reason.message);
|
|
211
|
+
throw reason;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Writes data to Vault
|
|
217
|
+
*
|
|
218
|
+
* @param path - path used to write data
|
|
219
|
+
* @param {object} data - data to write
|
|
220
|
+
* @returns {Promise<T | never>}
|
|
221
|
+
*/
|
|
222
|
+
write(path, data) {
|
|
223
|
+
this.__log.debug('write secret %s', path);
|
|
224
|
+
return this.__auth.getAuthToken()
|
|
225
|
+
.then((token) => this.__api.makeRequest('POST', path, data, this.getHeaders(token)))
|
|
226
|
+
.then((response) => {
|
|
227
|
+
this.__log.debug('secret %s was written', path);
|
|
228
|
+
return response;
|
|
229
|
+
})
|
|
230
|
+
.catch((reason) => {
|
|
231
|
+
this.__log.error('write secret failed: %s', reason.message);
|
|
232
|
+
throw reason;
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @private
|
|
238
|
+
*/
|
|
239
|
+
__setupLogger(logger) {
|
|
240
|
+
if (logger === false) {
|
|
241
|
+
return {
|
|
242
|
+
error: _.noop,
|
|
243
|
+
warn: _.noop,
|
|
244
|
+
info: _.noop,
|
|
245
|
+
debug: _.noop,
|
|
246
|
+
trace: _.noop,
|
|
247
|
+
}
|
|
248
|
+
} else if (_.intersection(_.functionsIn(logger), ['error', 'warn', 'info', 'debug', 'trace']).length >= 5) {
|
|
249
|
+
return logger
|
|
250
|
+
} else {
|
|
251
|
+
return {
|
|
252
|
+
error: console.error,
|
|
253
|
+
warn: console.warn,
|
|
254
|
+
info: console.info,
|
|
255
|
+
trace: console.trace,
|
|
256
|
+
// avoid output sensitive information
|
|
257
|
+
debug: _.noop
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
module.exports = VaultClient;
|