Skip to content

Commit e4a0609

Browse files
Add support for secrets manager environment variables
Closes #286
1 parent 24e62d8 commit e4a0609

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

package/lib/compileFunctions.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ module.exports = {
4949
_.get(funcObject, 'timeout') || _.get(this, 'serverless.service.provider.timeout') || '60s';
5050
funcTemplate.properties.environmentVariables =
5151
this.provider.getConfiguredEnvironment(funcObject);
52+
funcTemplate.properties.secretEnvironmentVariables =
53+
this.provider.getConfiguredSecrets(funcObject);
5254

5355
if (!funcTemplate.properties.serviceAccountEmail) {
5456
delete funcTemplate.properties.serviceAccountEmail;
@@ -80,6 +82,9 @@ module.exports = {
8082
if (!_.size(funcTemplate.properties.environmentVariables)) {
8183
delete funcTemplate.properties.environmentVariables;
8284
}
85+
if (!_.size(funcTemplate.properties.secretEnvironmentVariables)) {
86+
delete funcTemplate.properties.secretEnvironmentVariables;
87+
}
8388

8489
funcTemplate.properties.labels = _.assign(
8590
{},

package/lib/compileFunctions.test.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,109 @@ describe('CompileFunctions', () => {
507507
});
508508
});
509509

510+
it('should set the secret environment variables based on the function configuration', () => {
511+
googlePackage.serverless.service.functions = {
512+
func1: {
513+
handler: 'func1',
514+
secrets: [
515+
{
516+
key: 'TEST_SECRET',
517+
secret: 'secret',
518+
version: 'latest',
519+
},
520+
],
521+
events: [{ http: 'foo' }],
522+
},
523+
};
524+
525+
const compiledResources = [
526+
{
527+
type: 'gcp-types/cloudfunctions-v1:projects.locations.functions',
528+
name: 'my-service-dev-func1',
529+
properties: {
530+
parent: 'projects/myProject/locations/us-central1',
531+
runtime: 'nodejs10',
532+
function: 'my-service-dev-func1',
533+
entryPoint: 'func1',
534+
availableMemoryMb: 256,
535+
secretEnvironmentVariables: [
536+
{
537+
key: 'TEST_SECRET',
538+
secret: 'secret',
539+
version: 'latest',
540+
},
541+
],
542+
timeout: '60s',
543+
sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip',
544+
httpsTrigger: {
545+
url: 'foo',
546+
},
547+
labels: {},
548+
},
549+
},
550+
];
551+
552+
return googlePackage.compileFunctions().then(() => {
553+
expect(consoleLogStub.calledOnce).toEqual(true);
554+
expect(
555+
googlePackage.serverless.service.provider.compiledConfigurationTemplate.resources
556+
).toEqual(compiledResources);
557+
});
558+
});
559+
560+
it('should merge the secret environment variables on the provider configuration and function definition', () => {
561+
googlePackage.serverless.service.functions = {
562+
func1: {
563+
handler: 'func1',
564+
secrets: [
565+
{ key: 'TEST_SECRET', secret: 'secret1', version: 'latest' },
566+
{ key: 'TEST_SECRET2', secret: 'secret2', version: 'latest' },
567+
],
568+
events: [{ http: 'foo' }],
569+
},
570+
};
571+
googlePackage.serverless.service.provider.secrets = [
572+
{ key: 'TEST_SECRET', secret: 'secretbase', version: 'latest' },
573+
{ key: 'TEST_SECRET_PROVIDER', secret: 'secretprovider', version: 'latest' },
574+
];
575+
576+
const compiledResources = [
577+
{
578+
type: 'gcp-types/cloudfunctions-v1:projects.locations.functions',
579+
name: 'my-service-dev-func1',
580+
properties: {
581+
parent: 'projects/myProject/locations/us-central1',
582+
runtime: 'nodejs10',
583+
function: 'my-service-dev-func1',
584+
entryPoint: 'func1',
585+
availableMemoryMb: 256,
586+
secretEnvironmentVariables: [
587+
{ key: 'TEST_SECRET', secret: 'secret1', version: 'latest' },
588+
{ key: 'TEST_SECRET2', secret: 'secret2', version: 'latest' },
589+
{ key: 'TEST_SECRET_PROVIDER', secret: 'secretprovider', version: 'latest' },
590+
],
591+
timeout: '60s',
592+
sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip',
593+
httpsTrigger: {
594+
url: 'foo',
595+
},
596+
labels: {},
597+
},
598+
},
599+
];
600+
601+
return googlePackage.compileFunctions().then(() => {
602+
expect(consoleLogStub.calledOnce).toEqual(true);
603+
expect(
604+
googlePackage.serverless.service.provider.compiledConfigurationTemplate.resources
605+
).toEqual(compiledResources);
606+
expect(googlePackage.serverless.service.provider.secrets).toEqual([
607+
{ key: 'TEST_SECRET', secret: 'secretbase', version: 'latest' },
608+
{ key: 'TEST_SECRET_PROVIDER', secret: 'secretprovider', version: 'latest' },
609+
]);
610+
});
611+
});
612+
510613
it('should compile "http" events properly', () => {
511614
googlePackage.serverless.service.functions = {
512615
func1: {

provider/googleProvider.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ class GoogleProvider {
9292
},
9393
additionalProperties: false,
9494
},
95+
cloudFunctionSecretEnvironmentVariables: {
96+
type: 'object',
97+
},
9598
cloudFunctionVpcEgress: {
9699
enum: ['ALL', 'ALL_TRAFFIC', 'PRIVATE', 'PRIVATE_RANGES_ONLY'],
97100
},
@@ -119,6 +122,7 @@ class GoogleProvider {
119122
memorySize: { $ref: '#/definitions/cloudFunctionMemory' }, // Can be overridden by function configuration
120123
timeout: { type: 'string' }, // Can be overridden by function configuration
121124
environment: { $ref: '#/definitions/cloudFunctionEnvironmentVariables' }, // Can be overridden by function configuration
125+
secrets: { $ref: '#/definitions/cloudFunctionSecretEnvironmentVariables' }, // Can be overridden by function configuration
122126
vpc: { type: 'string' }, // Can be overridden by function configuration
123127
vpcEgress: { $ref: '#/definitions/cloudFunctionVpcEgress' }, // Can be overridden by function configuration
124128
labels: { $ref: '#/definitions/resourceManagerLabels' }, // Can be overridden by function configuration
@@ -133,6 +137,7 @@ class GoogleProvider {
133137
timeout: { type: 'string' }, // Override provider configuration
134138
minInstances: { type: 'number' },
135139
environment: { $ref: '#/definitions/cloudFunctionEnvironmentVariables' }, // Override provider configuration
140+
secrets: { $ref: '#/definitions/cloudFunctionSecretEnvironmentVariables' }, // Can be overridden by function configuration
136141
vpc: { type: 'string' }, // Override provider configuration
137142
vpcEgress: { $ref: '#/definitions/cloudFunctionVpcEgress' }, // Can be overridden by function configuration
138143
labels: { $ref: '#/definitions/resourceManagerLabels' }, // Override provider configuration
@@ -279,6 +284,14 @@ class GoogleProvider {
279284
);
280285
}
281286

287+
getConfiguredSecrets(funcObject) {
288+
const providerSecrets = _.get(this, 'serverless.service.provider.secrets', []);
289+
const functionSecrets = funcObject.secrets || [];
290+
return _.unionWith(functionSecrets, providerSecrets, (providerSecret, functionSecret) => {
291+
return functionSecret.key === providerSecret.key;
292+
});
293+
}
294+
282295
getConfiguredEnvironment(funcObject) {
283296
return _.merge(
284297
{},

0 commit comments

Comments
 (0)