node-vault-client 0.5.7 → 0.6.0

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.
@@ -1,253 +1,266 @@
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
-
46
- /**
47
- * Boot an instance of Vault
48
- *
49
- * The instance will be stored in a local hash. Calling Vault.boot multiple
50
- * times with the same name will return the same instance.
51
- *
52
- * @param {String} name - Vault instance name
53
- * @param {Object} [options] - options for {@link Vault#constructor}.
54
- * @return Vault
55
- */
56
- static boot(name, options) {
57
- if (options === undefined) {
58
- throw new errors.InvalidArgumentsError('Options should be provided');
59
- }
60
-
61
- let instance = vaultInstances[name];
62
- if (instance === undefined) {
63
- vaultInstances[name] = instance = new VaultClient(options);
64
-
65
- return instance;
66
- }
67
-
68
- throw new errors.InvalidArgumentsError('Instance with such name already booted');
69
- }
70
-
71
- /**
72
- * Get an instance of Vault
73
- *
74
- * The instance will be stored in a local hash. Calling Vault.pop multiple
75
- * times with the same name will return the same instance.
76
- *
77
- * @param {String} name - Vault instance name
78
- * @return Vault
79
- */
80
- static get(name) {
81
- let instance = vaultInstances[name];
82
-
83
- if (instance === undefined) {
84
- throw new errors.InvalidArgumentsError('Invalid instance name');
85
- }
86
-
87
- return instance;
88
- }
89
-
90
- /**
91
- * Clear named Vault instance
92
- *
93
- * If no name passed all named instances will be cleared.
94
- *
95
- * @param {String} [name] - Vault instance name, all instances will be cleared if no name were passed
96
- */
97
- static clear(name) {
98
- if (typeof name === 'string') {
99
- delete vaultInstances[name];
100
- } else {
101
- for (let k in vaultInstances) {
102
- if (vaultInstances.hasOwnProperty(k)) {
103
- delete vaultInstances[k];
104
- }
105
- }
106
- }
107
- }
108
-
109
- /**
110
- * @protected
111
- *
112
- * @param {Object} authConfig
113
- * @param {string} authConfig.type
114
- * @param {string} authConfig.mount
115
- * @param {Object} authConfig.config
116
- * @param {VaultApiClient} api
117
- * @return {VaultBaseAuth}
118
- * @private
119
- */
120
- __getAuthProvider(authConfig, api) {
121
- this.__log.debug('creating vault auth method: "%s"', authConfig.type);
122
-
123
- switch (authConfig.type) {
124
- case 'iam':
125
- return new VaultIAMAuth(
126
- api,
127
- this.__log,
128
- authConfig.config,
129
- authConfig.mount
130
- );
131
- case 'appRole':
132
- return new VaultAppRoleAuth(
133
- api,
134
- this.__log,
135
- authConfig.config,
136
- authConfig.mount
137
- );
138
- case 'token':
139
- return new VaultTokenAuth(
140
- api,
141
- this.__log,
142
- authConfig.config,
143
- authConfig.mount
144
- );
145
- case 'kubernetes':
146
- return new VaultKubernetesAuth(
147
- api,
148
- this.__log,
149
- authConfig.config,
150
- authConfig.mount
151
- );
152
- }
153
-
154
- throw new errors.InvalidArgumentsError('Unsupported auth method')
155
- }
156
-
157
- /**
158
- * Populates Vault's values to NPM "config" module
159
- */
160
- fillNodeConfig() {
161
- const vaultConf = new VaultNodeConfig(this);
162
-
163
- return vaultConf.populate();
164
- }
165
-
166
- /**
167
- * Read secret from Vault
168
- * @param {string} path - path to the secret
169
- * @returns {Promise<Lease>}
170
- */
171
- read(path) {
172
- this.__log.debug('read secret %s', path);
173
- return this.__auth.getAuthToken()
174
- .then(token => this.__api.makeRequest('GET', path, null, {'X-Vault-Token': token.getId()}))
175
- .then(res => {
176
- this.__log.debug('receive secret %s', path);
177
- return Lease.fromResponse(res);
178
- })
179
- .catch((reason) => {
180
- this.__log.error('read secret failed: %s', reason.message);
181
- throw reason;
182
- });
183
- }
184
-
185
- /**
186
- * Retrieves secrets list
187
- *
188
- * @param {string} path - path to the secret
189
- * @returns {Promise<Lease>}
190
- */
191
- list(path) {
192
- this.__log.debug('list secrets %s', path);
193
- return this.__auth.getAuthToken()
194
- .then(token => this.__api.makeRequest('LIST', path, null, {'X-Vault-Token': token.getId()}))
195
- .then(res => {
196
- this.__log.debug('got secrets list %s', path);
197
- return Lease.fromResponse(res);
198
- })
199
- .catch((reason) => {
200
- this.__log.error('list secrets failed: %s', reason.message);
201
- throw reason;
202
- });
203
- }
204
-
205
- /**
206
- * Writes data to Vault
207
- *
208
- * @param path - path used to write data
209
- * @param {object} data - data to write
210
- * @returns {Promise<T | never>}
211
- */
212
- write(path, data) {
213
- this.__log.debug('write secret %s', path);
214
- return this.__auth.getAuthToken()
215
- .then((token) => this.__api.makeRequest('POST', path, data, {'X-Vault-Token': token.getId()}))
216
- .then((response) => {
217
- this.__log.debug('secret %s was written', path);
218
- return response;
219
- })
220
- .catch((reason) => {
221
- this.__log.error('write secret failed: %s', reason.message);
222
- throw reason;
223
- });
224
- }
225
-
226
- /**
227
- * @private
228
- */
229
- __setupLogger(logger) {
230
- if (logger === false) {
231
- return {
232
- error: _.noop,
233
- warn: _.noop,
234
- info: _.noop,
235
- debug: _.noop,
236
- trace: _.noop,
237
- }
238
- } else if (_.intersection(_.functionsIn(logger), ['error', 'warn', 'info', 'debug', 'trace']).length >= 5) {
239
- return logger
240
- } else {
241
- return {
242
- error: console.error,
243
- warn: console.warn,
244
- info: console.info,
245
- trace: console.trace,
246
- // avoid output sensitive information
247
- debug: _.noop
248
- };
249
- }
250
- }
251
- }
252
-
253
- 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
+ throw new errors.InvalidArgumentsError('Instance with such name already booted');
71
+ }
72
+
73
+ /**
74
+ * Get an instance of Vault
75
+ *
76
+ * The instance will be stored in a local hash. Calling Vault.pop multiple
77
+ * times with the same name will return the same instance.
78
+ *
79
+ * @param {String} name - Vault instance name
80
+ * @return Vault
81
+ */
82
+ static get(name) {
83
+ let instance = vaultInstances[name];
84
+
85
+ if (instance === undefined) {
86
+ throw new errors.InvalidArgumentsError('Invalid instance name');
87
+ }
88
+
89
+ return instance;
90
+ }
91
+
92
+ /**
93
+ * Clear named Vault instance
94
+ *
95
+ * If no name passed all named instances will be cleared.
96
+ *
97
+ * @param {String} [name] - Vault instance name, all instances will be cleared if no name were passed
98
+ */
99
+ static clear(name) {
100
+ if (typeof name === 'string') {
101
+ delete vaultInstances[name];
102
+ } else {
103
+ for (let k in vaultInstances) {
104
+ if (vaultInstances.hasOwnProperty(k)) {
105
+ delete vaultInstances[k];
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ /**
112
+ * @protected
113
+ *
114
+ * @param {Object} authConfig
115
+ * @param {string} authConfig.type
116
+ * @param {string} authConfig.mount
117
+ * @param {Object} authConfig.config
118
+ * @param {VaultApiClient} api
119
+ * @return {VaultBaseAuth}
120
+ * @private
121
+ */
122
+ __getAuthProvider(authConfig, api) {
123
+ this.__log.debug('creating vault auth method: "%s"', authConfig.type);
124
+
125
+ switch (authConfig.type) {
126
+ case 'iam':
127
+ return new VaultIAMAuth(
128
+ api,
129
+ this.__log,
130
+ authConfig.config,
131
+ authConfig.mount
132
+ );
133
+ case 'appRole':
134
+ return new VaultAppRoleAuth(
135
+ api,
136
+ this.__log,
137
+ authConfig.config,
138
+ authConfig.mount
139
+ );
140
+ case 'token':
141
+ return new VaultTokenAuth(
142
+ api,
143
+ this.__log,
144
+ authConfig.config,
145
+ authConfig.mount
146
+ );
147
+ case 'kubernetes':
148
+ return new VaultKubernetesAuth(
149
+ api,
150
+ this.__log,
151
+ authConfig.config,
152
+ authConfig.mount
153
+ );
154
+ }
155
+
156
+ throw new errors.InvalidArgumentsError('Unsupported auth method')
157
+ }
158
+
159
+ /**
160
+ * Populates Vault's values to NPM "config" module
161
+ */
162
+ fillNodeConfig() {
163
+ const vaultConf = new VaultNodeConfig(this);
164
+
165
+ return vaultConf.populate();
166
+ }
167
+
168
+ getHeaders() {
169
+ if (this.__namespace) {
170
+ return {
171
+ 'X-Vault-Token': token.getId(),
172
+ 'X-Vault-Namespace': this.__namespace
173
+ }
174
+ }
175
+
176
+ return {'X-Vault-Token': token.getId()}
177
+ }
178
+
179
+ /**
180
+ * Read secret from Vault
181
+ * @param {string} path - path to the secret
182
+ * @returns {Promise<Lease>}
183
+ */
184
+ read(path) {
185
+ this.__log.debug('read secret %s', path);
186
+ return this.__auth.getAuthToken()
187
+ .then(token => this.__api.makeRequest('GET', path, null, this.getHeaders()))
188
+ .then(res => {
189
+ this.__log.debug('receive secret %s', path);
190
+ return Lease.fromResponse(res);
191
+ })
192
+ .catch((reason) => {
193
+ this.__log.error('read secret failed: %s', reason.message);
194
+ throw reason;
195
+ });
196
+ }
197
+
198
+ /**
199
+ * Retrieves secrets list
200
+ *
201
+ * @param {string} path - path to the secret
202
+ * @returns {Promise<Lease>}
203
+ */
204
+ list(path) {
205
+ this.__log.debug('list secrets %s', path);
206
+ return this.__auth.getAuthToken()
207
+ .then(token => this.__api.makeRequest('LIST', path, null, this.getHeaders()))
208
+ .then(res => {
209
+ this.__log.debug('got secrets list %s', path);
210
+ return Lease.fromResponse(res);
211
+ })
212
+ .catch((reason) => {
213
+ this.__log.error('list secrets failed: %s', reason.message);
214
+ throw reason;
215
+ });
216
+ }
217
+
218
+ /**
219
+ * Writes data to Vault
220
+ *
221
+ * @param path - path used to write data
222
+ * @param {object} data - data to write
223
+ * @returns {Promise<T | never>}
224
+ */
225
+ write(path, data) {
226
+ this.__log.debug('write secret %s', path);
227
+ return this.__auth.getAuthToken()
228
+ .then((token) => this.__api.makeRequest('POST', path, data, this.getHeaders()))
229
+ .then((response) => {
230
+ this.__log.debug('secret %s was written', path);
231
+ return response;
232
+ })
233
+ .catch((reason) => {
234
+ this.__log.error('write secret failed: %s', reason.message);
235
+ throw reason;
236
+ });
237
+ }
238
+
239
+ /**
240
+ * @private
241
+ */
242
+ __setupLogger(logger) {
243
+ if (logger === false) {
244
+ return {
245
+ error: _.noop,
246
+ warn: _.noop,
247
+ info: _.noop,
248
+ debug: _.noop,
249
+ trace: _.noop,
250
+ }
251
+ } else if (_.intersection(_.functionsIn(logger), ['error', 'warn', 'info', 'debug', 'trace']).length >= 5) {
252
+ return logger
253
+ } else {
254
+ return {
255
+ error: console.error,
256
+ warn: console.warn,
257
+ info: console.info,
258
+ trace: console.trace,
259
+ // avoid output sensitive information
260
+ debug: _.noop
261
+ };
262
+ }
263
+ }
264
+ }
265
+
266
+ module.exports = VaultClient;