@@ -14,11 +14,14 @@ const logger = pino({
14
14
15
15
describe ( 'VaultBackend' , ( ) => {
16
16
let clientMock
17
+ let clientMock2
17
18
let vaultBackend
18
19
const defaultFakeMountPoint = 'defaultFakeMountPoint'
19
20
const defaultFakeRole = 'defaultFakeRole'
20
21
const mountPoint = 'fakeMountPoint'
22
+ const mountPoint2 = 'fakeMountPoint2'
21
23
const role = 'fakeRole'
24
+ const role2 = 'fakeRole2'
22
25
const secretKey = 'fakeSecretKey'
23
26
const secretValue = 'open, sesame'
24
27
const secretData = { [ secretKey ] : secretValue }
@@ -50,9 +53,10 @@ describe('VaultBackend', () => {
50
53
51
54
beforeEach ( ( ) => {
52
55
clientMock = sinon . mock ( )
53
-
56
+ clientMock2 = sinon . mock ( )
57
+ let mock = 0
54
58
vaultBackend = new VaultBackend ( {
55
- client : clientMock ,
59
+ vaultFactory : ( ) => mock ++ === 0 ? clientMock : clientMock2 ,
56
60
tokenRenewThreshold : vaultTokenRenewThreshold ,
57
61
logger : logger ,
58
62
defaultVaultMountPoint : defaultFakeMountPoint ,
@@ -63,6 +67,7 @@ describe('VaultBackend', () => {
63
67
describe ( '_get' , ( ) => {
64
68
beforeEach ( ( ) => {
65
69
clientMock . read = sinon . stub ( ) . returns ( kv2Secret )
70
+ clientMock . token = undefined
66
71
clientMock . tokenLookupSelf = sinon . stub ( ) . returns ( mockTokenLookupResultMustRenew )
67
72
clientMock . tokenRenewSelf = sinon . stub ( ) . returns ( true )
68
73
clientMock . kubernetesLogin = sinon . stub ( ) . returns ( {
@@ -71,9 +76,17 @@ describe('VaultBackend', () => {
71
76
}
72
77
} )
73
78
74
- vaultBackend . _fetchServiceAccountToken = sinon . stub ( ) . returns ( jwt )
79
+ clientMock2 . read = sinon . stub ( ) . returns ( kv2Secret )
80
+ clientMock2 . token = undefined
81
+ clientMock2 . tokenLookupSelf = sinon . stub ( ) . returns ( mockTokenLookupResultMustRenew )
82
+ clientMock2 . tokenRenewSelf = sinon . stub ( ) . returns ( true )
83
+ clientMock2 . kubernetesLogin = sinon . stub ( ) . returns ( {
84
+ auth : {
85
+ client_token : '5678'
86
+ }
87
+ } )
75
88
76
- clientMock . token = undefined
89
+ vaultBackend . _fetchServiceAccountToken = sinon . stub ( ) . returns ( jwt )
77
90
} )
78
91
79
92
it ( 'logs in and returns secret property value - default' , async ( ) => {
@@ -227,6 +240,168 @@ describe('VaultBackend', () => {
227
240
// ... and expect to get its proper value
228
241
expect ( secretPropertyValue ) . equals ( quotedSecretValue )
229
242
} )
243
+
244
+ it ( 'returns secret property value using client associated with role given in _get' , async ( ) => {
245
+ clientMock . read = sinon . stub ( ) . returns ( kv2Secret )
246
+ clientMock2 . read = sinon . stub ( ) . returns ( kv2Secret )
247
+
248
+ const secretPropertyValue = await vaultBackend . _get ( {
249
+ specOptions : {
250
+ vaultMountPoint : mountPoint ,
251
+ vaultRole : role
252
+ } ,
253
+ key : secretKey
254
+ } )
255
+
256
+ // First, we log into Vault with role 1...
257
+ sinon . assert . calledWith ( clientMock . kubernetesLogin , {
258
+ mount_point : mountPoint ,
259
+ role : role ,
260
+ jwt : jwt
261
+ } )
262
+
263
+ // ... then we fetch the secret ...
264
+ sinon . assert . calledWith ( clientMock . read , secretKey )
265
+
266
+ // ... and expect to get its proper value
267
+ expect ( secretPropertyValue ) . equals ( quotedSecretValue )
268
+
269
+ const secretPropertyValue2 = await vaultBackend . _get ( {
270
+ specOptions : {
271
+ vaultMountPoint : mountPoint ,
272
+ vaultRole : role2
273
+ } ,
274
+ key : secretKey
275
+ } )
276
+
277
+ // Now ensure we log into Vault with role 2...
278
+ sinon . assert . calledWith ( clientMock2 . kubernetesLogin , {
279
+ mount_point : mountPoint ,
280
+ role : role2 ,
281
+ jwt : jwt
282
+ } )
283
+
284
+ // ... then we fetch the secret ...
285
+ sinon . assert . calledWith ( clientMock2 . read , secretKey )
286
+
287
+ // ... and expect to get its proper value
288
+ expect ( secretPropertyValue2 ) . equals ( quotedSecretValue )
289
+ } )
290
+
291
+ it ( 'returns secret property value using client associated with mountpoint given in _get' , async ( ) => {
292
+ clientMock . read = sinon . stub ( ) . returns ( kv2Secret )
293
+ clientMock2 . read = sinon . stub ( ) . returns ( kv2Secret )
294
+
295
+ const secretPropertyValue = await vaultBackend . _get ( {
296
+ specOptions : {
297
+ vaultMountPoint : mountPoint ,
298
+ vaultRole : role
299
+ } ,
300
+ key : secretKey
301
+ } )
302
+
303
+ // First, we log into Vault with mountpoint 1...
304
+ sinon . assert . calledWith ( clientMock . kubernetesLogin , {
305
+ mount_point : mountPoint ,
306
+ role : role ,
307
+ jwt : jwt
308
+ } )
309
+
310
+ // ... then we fetch the secret ...
311
+ sinon . assert . calledWith ( clientMock . read , secretKey )
312
+
313
+ // ... and expect to get its proper value
314
+ expect ( secretPropertyValue ) . equals ( quotedSecretValue )
315
+
316
+ const secretPropertyValue2 = await vaultBackend . _get ( {
317
+ specOptions : {
318
+ vaultMountPoint : mountPoint2 ,
319
+ vaultRole : role
320
+ } ,
321
+ key : secretKey
322
+ } )
323
+
324
+ // Now ensure we log into Vault with mountpoint 2...
325
+ sinon . assert . calledWith ( clientMock2 . kubernetesLogin , {
326
+ mount_point : mountPoint2 ,
327
+ role : role ,
328
+ jwt : jwt
329
+ } )
330
+
331
+ // ... then we fetch the secret ...
332
+ sinon . assert . calledWith ( clientMock2 . read , secretKey )
333
+
334
+ // ... and expect to get its proper value
335
+ expect ( secretPropertyValue2 ) . equals ( quotedSecretValue )
336
+ } )
337
+
338
+ it ( 'ensure we cache the clients for each role' , async ( ) => {
339
+ clientMock . read = sinon . stub ( ) . returns ( kv2Secret )
340
+ clientMock2 . read = sinon . stub ( ) . returns ( kv2Secret )
341
+
342
+ await vaultBackend . _get ( {
343
+ specOptions : {
344
+ vaultMountPoint : mountPoint ,
345
+ vaultRole : role
346
+ } ,
347
+ key : secretKey
348
+ } )
349
+
350
+ // First, we log into Vault with role 1...
351
+ sinon . assert . calledWith ( clientMock . kubernetesLogin , {
352
+ mount_point : mountPoint ,
353
+ role : role ,
354
+ jwt : jwt
355
+ } )
356
+ sinon . assert . calledOnce ( clientMock . read )
357
+
358
+ clientMock . token = 'an-existing-token'
359
+ clientMock . tokenLookupSelf = sinon . stub ( ) . returns ( mockTokenLookupResultNoRenew )
360
+
361
+ // now we have active role 1 client, we now activate role 2 client
362
+
363
+ await vaultBackend . _get ( {
364
+ specOptions : {
365
+ vaultMountPoint : mountPoint ,
366
+ vaultRole : role2
367
+ } ,
368
+ key : secretKey
369
+ } )
370
+
371
+ // we log into Vault with role 2...
372
+ sinon . assert . calledWith ( clientMock2 . kubernetesLogin , {
373
+ mount_point : mountPoint ,
374
+ role : role2 ,
375
+ jwt : jwt
376
+ } )
377
+ sinon . assert . calledOnce ( clientMock2 . read )
378
+
379
+ clientMock2 . token = 'an-existing-token'
380
+ clientMock2 . tokenLookupSelf = sinon . stub ( ) . returns ( mockTokenLookupResultNoRenew )
381
+
382
+ // Back to role1
383
+ await vaultBackend . _get ( {
384
+ specOptions : {
385
+ vaultMountPoint : mountPoint ,
386
+ vaultRole : role
387
+ } ,
388
+ key : secretKey
389
+ } )
390
+
391
+ sinon . assert . calledOnce ( clientMock . kubernetesLogin )
392
+ sinon . assert . calledTwice ( clientMock . read )
393
+
394
+ await vaultBackend . _get ( {
395
+ specOptions : {
396
+ vaultMountPoint : mountPoint ,
397
+ vaultRole : role2
398
+ } ,
399
+ key : secretKey
400
+ } )
401
+
402
+ sinon . assert . calledOnce ( clientMock2 . kubernetesLogin )
403
+ sinon . assert . calledTwice ( clientMock2 . read )
404
+ } )
230
405
} )
231
406
232
407
describe ( 'getSecretManifestData' , ( ) => {
0 commit comments