node-vault-client 1.0.1 → 1.0.2

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,263 +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
- 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;
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;