@@ -15,20 +15,22 @@ class KVBackend extends AbstractBackend {
15
15
16
16
/**
17
17
* Fetch Kubernetes secret property values.
18
- * @param {Object[] } secretProperties - Kubernetes secret properties.
19
- * @param {string } secretProperties [].key - Secret key in the backend.
20
- * @param {string } secretProperties [].name - Kubernetes Secret property name.
21
- * @param {string } secretProperties [].property - If the backend secret is an
18
+ * @param {Object[] } data - Kubernetes secret properties.
19
+ * @param {string } data [].key - Secret key in the backend.
20
+ * @param {string } data [].name - Kubernetes Secret property name.
21
+ * @param {string } data [].property - If the backend secret is an
22
22
* object, this is the property name of the value to use.
23
- * @param {string } secretProperties[]. roleArn - If the client should assume a role before fetching the secret
23
+ * @param {string } roleArn - If the client should assume a role before fetching the secret
24
24
* @returns {Promise } Promise object representing secret property values.
25
25
*/
26
- _fetchSecretPropertyValues ( { externalData , roleArn } ) {
27
- return Promise . all ( externalData . map ( async secretProperty => {
26
+ _fetchDataValues ( { data , roleArn } ) {
27
+ return Promise . all ( data . map ( async secretProperty => {
28
28
this . _logger . info ( `fetching secret property ${ secretProperty . name } with role: ${ roleArn || 'no role set' } ` )
29
- const value = await this . _get ( { secretKey : secretProperty . key , roleArn } )
29
+ const plainOrObjValue = await this . _get ( { secretKey : secretProperty . key , roleArn } )
30
+ const shouldParseValue = 'property' in secretProperty
30
31
31
- if ( 'property' in secretProperty ) {
32
+ let value = plainOrObjValue
33
+ if ( shouldParseValue ) {
32
34
let parsedValue
33
35
try {
34
36
parsedValue = JSON . parse ( value )
@@ -43,10 +45,30 @@ class KVBackend extends AbstractBackend {
43
45
throw new Error ( `Could not find property ${ secretProperty . property } in ${ secretProperty . key } ` )
44
46
}
45
47
46
- return parsedValue [ secretProperty . property ]
48
+ value = parsedValue [ secretProperty . property ]
47
49
}
48
50
49
- return value
51
+ return { [ secretProperty . name ] : value }
52
+ } ) )
53
+ }
54
+
55
+ /**
56
+ * Fetch Kubernetes secret property values.
57
+ * @param {string[] } dataFrom - Array of secret keys in the backend
58
+ * @param {string } roleArn - If the client should assume a role before fetching the secret
59
+ * @returns {Promise } Promise object representing secret property values.
60
+ */
61
+ _fetchDataFromValues ( { dataFrom, roleArn } ) {
62
+ return Promise . all ( dataFrom . map ( async secretKey => {
63
+ this . _logger . info ( `fetching secret ${ secretKey } with role: ${ roleArn || 'no role set' } ` )
64
+ const value = await this . _get ( { secretKey, roleArn } )
65
+
66
+ try {
67
+ return JSON . parse ( value )
68
+ } catch ( err ) {
69
+ this . _logger . warn ( `Failed to JSON.parse value for '${ secretKey } ',` +
70
+ ` please verify that your secret value is correctly formatted as JSON.` )
71
+ }
50
72
} ) )
51
73
}
52
74
@@ -62,18 +84,33 @@ class KVBackend extends AbstractBackend {
62
84
* @param {SecretDescriptor } secretDescriptor - Kubernetes secret descriptor.
63
85
* @returns {Promise } Promise object representing Kubernetes secret manifest data.
64
86
*/
65
- async getSecretManifestData ( { secretDescriptor } ) {
66
- const data = { }
67
- // Use secretDescriptor.properties to be backwards compatible.
68
- const externalData = secretDescriptor . data || secretDescriptor . properties
69
- const secretPropertyValues = await this . _fetchSecretPropertyValues ( {
70
- externalData,
71
- roleArn : secretDescriptor . roleArn
72
- } )
73
- externalData . forEach ( ( secretProperty , index ) => {
74
- data [ secretProperty . name ] = ( Buffer . from ( secretPropertyValues [ index ] , 'utf8' ) ) . toString ( 'base64' )
75
- } )
76
- return data
87
+ async getSecretManifestData ( {
88
+ secretDescriptor : {
89
+ // Use secretDescriptor.properties to be backwards compatible.
90
+ properties = [ ] ,
91
+ data = properties ,
92
+ dataFrom = [ ] ,
93
+ roleArn
94
+ }
95
+ } ) {
96
+ const [ dataFromValues , dataValues ] = await Promise . all ( [
97
+ this . _fetchDataFromValues ( { dataFrom, roleArn } ) ,
98
+ this . _fetchDataValues ( { data, roleArn } )
99
+ ] )
100
+
101
+ const plainValues = dataFromValues . concat ( dataValues )
102
+ . reduce ( ( acc , parsedValue ) => ( {
103
+ ...acc ,
104
+ ...parsedValue
105
+ } ) , { } )
106
+
107
+ const encodedEntries = Object . entries ( plainValues )
108
+ . map ( ( [ name , plainValue ] ) => [
109
+ name ,
110
+ ( Buffer . from ( `${ plainValue } ` , 'utf8' ) ) . toString ( 'base64' )
111
+ ] )
112
+
113
+ return Object . fromEntries ( encodedEntries )
77
114
}
78
115
}
79
116
0 commit comments