Skip to content

Commit

Permalink
\serverless#8692: Add kmsKeyArn property to provider and
Browse files Browse the repository at this point in the history
`function[]` objects for single function deployment
  • Loading branch information
ifitzsimmons committed Dec 31, 2020
1 parent 715ba60 commit d67a0ad
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 9 deletions.
25 changes: 21 additions & 4 deletions lib/plugins/aws/deployFunction.js
Expand Up @@ -103,10 +103,27 @@ class AwsDeployFunction {
FunctionName: functionObj.name,
};

if ('awsKmsKeyArn' in functionObj && !_.isObject(functionObj.awsKmsKeyArn)) {
params.KMSKeyArn = functionObj.awsKmsKeyArn;
} else if (serviceObj && 'awsKmsKeyArn' in serviceObj && !_.isObject(serviceObj.awsKmsKeyArn)) {
params.KMSKeyArn = serviceObj.awsKmsKeyArn;
let kmsKeyArn = functionObj.kmsKeyArn || providerObj.kmsKeyArn;
if (functionObj.awsKmsKeyArn) {
kmsKeyArn = !kmsKeyArn ? functionObj.awsKmsKeyArn : kmsKeyArn;

this.serverless._logDeprecation(
'FUNCTION_DEPRECATED_PROPERTY_AWS_KMS_KEY_ARN',
'Starting with next major version, awsKmsKeyArn function property will be replaced by function[].kmsKeyArn.'
);
}

if (serviceObj.awsKmsKeyArn) {
kmsKeyArn = !kmsKeyArn ? serviceObj.awsKmsKeyArn : kmsKeyArn;

this.serverless._logDeprecation(
'SERVICE_DEPRECATED_PROPERTY_AWS_KMS_KEY_ARN',
'Starting with next major version, awsKmsKeyArn service property will be replaced by provider.kmsKeyArn.'
);
}

if (kmsKeyArn) {
params.KMSKeyArn = kmsKeyArn;
}

if ('description' in functionObj && !_.isObject(functionObj.description)) {
Expand Down
5 changes: 5 additions & 0 deletions lib/plugins/aws/provider.js
Expand Up @@ -384,6 +384,10 @@ class AwsProvider {
],
},
},
awsKmsArn: {
type: 'string',
pattern: '^arn:aws:kms:',
},
awsLambdaEnvironment: {
type: 'object',
patternProperties: {
Expand Down Expand Up @@ -590,6 +594,7 @@ class AwsProvider {
},
additionalProperties: false,
},
awsKmsKeyArn: { $ref: '#/definitions/awsKmsArn' },
cfnRole: { $ref: '#/definitions/awsArn' },
cloudFront: {
type: 'object',
Expand Down
231 changes: 226 additions & 5 deletions test/unit/lib/plugins/aws/deployFunction.test.js
Expand Up @@ -36,6 +36,7 @@ describe('AwsDeployFunction', () => {
},
},
};
serverless.service.serviceObject = {};
serverless.service.functions = {
first: {
handler: true,
Expand Down Expand Up @@ -232,16 +233,24 @@ describe('AwsDeployFunction', () => {
},
layers: ['arn:aws:lambda:us-east-1:123456789012:layer:layer:1'],
};

awsDeployFunction.serverless._logDeprecation = sinon.spy();
awsDeployFunction.options = options;

await awsDeployFunction.updateFunctionConfiguration();

expect(normalizeArnRoleStub.calledOnce).to.be.equal(true);
expect(normalizeArnRoleStub.calledWithExactly('arn:aws:iam::123456789012:role/Admin'));
expect(updateFunctionConfigurationStub.calledOnce).to.be.equal(true);
expect(
updateFunctionConfigurationStub.calledWithExactly('Lambda', 'updateFunctionConfiguration', {
sinon.assert.calledWith(
awsDeployFunction.serverless._logDeprecation,
'FUNCTION_DEPRECATED_PROPERTY_AWS_KMS_KEY_ARN',
'Starting with next major version, awsKmsKeyArn function property will be replaced by function[].kmsKeyArn.'
);
sinon.assert.calledWith(
updateFunctionConfigurationStub,
'Lambda',
'updateFunctionConfiguration',
{
DeadLetterConfig: {
TargetArn: 'arn:aws:sqs:us-east-1:123456789012:dlq',
},
Expand All @@ -262,8 +271,8 @@ describe('AwsDeployFunction', () => {
SubnetIds: ['2'],
},
Layers: ['arn:aws:lambda:us-east-1:123456789012:layer:layer:1'],
})
).to.be.equal(true);
}
);
});

it('should update only specified params', async () => {
Expand Down Expand Up @@ -421,6 +430,218 @@ describe('AwsDeployFunction', () => {
})
).to.be.equal(true);
});

describe('#KMSKeyArn should be set by "kmsKeyArn" or "awsKmsKeyArn"', () => {
let functionObj = {};

beforeEach(() => {
functionObj = {
awsKmsKeyArn: 'arn:aws:kms:us-east-1:123456789012',
description: 'desc',
handler: 'my_handler',
environment: {
VARIABLE: 'value',
},
name: 'first',
memorySize: 128,
onError: 'arn:aws:sqs:us-east-1:123456789012:dlq',
role: 'arn:aws:iam::123456789012:role/Admin',
timeout: 3,
vpc: {
securityGroupIds: ['1'],
subnetIds: ['2'],
},
layers: ['arn:aws:lambda:us-east-1:123456789012:layer:layer:1'],
};
});

afterEach(() => {
functionObj = {};
});

it('configuration uses the "kmsKeyArn" and logs deprecation warning for functionObj.awsKmsKeyArn', async () => {
options.functionObj = functionObj;
options.functionObj.kmsKeyArn = 'arn:aws:kms:us-east-1:newKey';
awsDeployFunction.serverless._logDeprecation = sinon.spy();
awsDeployFunction.options = options;

await awsDeployFunction.updateFunctionConfiguration();

expect(normalizeArnRoleStub.calledOnce).to.be.equal(true);
expect(normalizeArnRoleStub.calledWithExactly('arn:aws:iam::123456789012:role/Admin'));
expect(updateFunctionConfigurationStub.calledOnce).to.be.equal(true);
sinon.assert.calledWith(
awsDeployFunction.serverless._logDeprecation,
'FUNCTION_DEPRECATED_PROPERTY_AWS_KMS_KEY_ARN',
'Starting with next major version, awsKmsKeyArn function property will be replaced by function[].kmsKeyArn.'
);
sinon.assert.calledWith(
updateFunctionConfigurationStub,
'Lambda',
'updateFunctionConfiguration',
{
DeadLetterConfig: {
TargetArn: 'arn:aws:sqs:us-east-1:123456789012:dlq',
},
Handler: 'my_handler',
Description: 'desc',
Environment: {
Variables: {
VARIABLE: 'value',
},
},
FunctionName: 'first',
KMSKeyArn: 'arn:aws:kms:us-east-1:newKey',
MemorySize: 128,
Role: 'arn:aws:us-east-1:123456789012:role/role',
Timeout: 3,
VpcConfig: {
SecurityGroupIds: ['1'],
SubnetIds: ['2'],
},
Layers: ['arn:aws:lambda:us-east-1:123456789012:layer:layer:1'],
}
);
});

it('configuration uses the "kmsKeyArn" and logs deprecation warning for serviceObj.awsKmsKeyArn', async () => {
options.functionObj = functionObj;
delete options.functionObj.awsKmsKeyArn;
awsDeployFunction.serverless.service.provider.kmsKeyArn = 'arn:aws:kms:us-east-1:newKey';
awsDeployFunction.serverless._logDeprecation = sinon.spy();
awsDeployFunction.serverless.service.serviceObject.awsKmsKeyArn = 'oldKey';
awsDeployFunction.options = options;

await awsDeployFunction.updateFunctionConfiguration();

expect(normalizeArnRoleStub.calledOnce).to.be.equal(true);
expect(normalizeArnRoleStub.calledWithExactly('arn:aws:iam::123456789012:role/Admin'));
expect(updateFunctionConfigurationStub.calledOnce).to.be.equal(true);
sinon.assert.calledWith(
awsDeployFunction.serverless._logDeprecation,
'SERVICE_DEPRECATED_PROPERTY_AWS_KMS_KEY_ARN',
'Starting with next major version, awsKmsKeyArn service property will be replaced by provider.kmsKeyArn.'
);
sinon.assert.calledWith(
updateFunctionConfigurationStub,
'Lambda',
'updateFunctionConfiguration',
{
DeadLetterConfig: {
TargetArn: 'arn:aws:sqs:us-east-1:123456789012:dlq',
},
Handler: 'my_handler',
Description: 'desc',
Environment: {
Variables: {
VARIABLE: 'value',
},
},
FunctionName: 'first',
KMSKeyArn: 'arn:aws:kms:us-east-1:newKey',
MemorySize: 128,
Role: 'arn:aws:us-east-1:123456789012:role/role',
Timeout: 3,
VpcConfig: {
SecurityGroupIds: ['1'],
SubnetIds: ['2'],
},
Layers: ['arn:aws:lambda:us-east-1:123456789012:layer:layer:1'],
}
);
});

it('configuration uses serviceObj.awsKmsKeyArn and logs deprecation warning', async () => {
options.functionObj = functionObj;
delete options.functionObj.awsKmsKeyArn;
awsDeployFunction.serverless._logDeprecation = sinon.spy();
awsDeployFunction.serverless.service.serviceObject.awsKmsKeyArn =
'arn:aws:kms:us-east-1:key';
awsDeployFunction.options = options;

await awsDeployFunction.updateFunctionConfiguration();

expect(normalizeArnRoleStub.calledOnce).to.be.equal(true);
expect(normalizeArnRoleStub.calledWithExactly('arn:aws:iam::123456789012:role/Admin'));
expect(updateFunctionConfigurationStub.calledOnce).to.be.equal(true);
sinon.assert.calledWith(
awsDeployFunction.serverless._logDeprecation,
'SERVICE_DEPRECATED_PROPERTY_AWS_KMS_KEY_ARN',
'Starting with next major version, awsKmsKeyArn service property will be replaced by provider.kmsKeyArn.'
);
sinon.assert.calledWith(
updateFunctionConfigurationStub,
'Lambda',
'updateFunctionConfiguration',
{
DeadLetterConfig: {
TargetArn: 'arn:aws:sqs:us-east-1:123456789012:dlq',
},
Handler: 'my_handler',
Description: 'desc',
Environment: {
Variables: {
VARIABLE: 'value',
},
},
FunctionName: 'first',
KMSKeyArn: 'arn:aws:kms:us-east-1:key',
MemorySize: 128,
Role: 'arn:aws:us-east-1:123456789012:role/role',
Timeout: 3,
VpcConfig: {
SecurityGroupIds: ['1'],
SubnetIds: ['2'],
},
Layers: ['arn:aws:lambda:us-east-1:123456789012:layer:layer:1'],
}
);
});

it('configuration uses functionObj.awsKmsKeyArn and logs deprecation warning', async () => {
options.functionObj = functionObj;
awsDeployFunction.serverless._logDeprecation = sinon.spy();
awsDeployFunction.options = options;

await awsDeployFunction.updateFunctionConfiguration();

expect(normalizeArnRoleStub.calledOnce).to.be.equal(true);
expect(normalizeArnRoleStub.calledWithExactly('arn:aws:iam::123456789012:role/Admin'));
expect(updateFunctionConfigurationStub.calledOnce).to.be.equal(true);
sinon.assert.calledWith(
awsDeployFunction.serverless._logDeprecation,
'FUNCTION_DEPRECATED_PROPERTY_AWS_KMS_KEY_ARN',
'Starting with next major version, awsKmsKeyArn function property will be replaced by function[].kmsKeyArn.'
);
sinon.assert.calledWith(
updateFunctionConfigurationStub,
'Lambda',
'updateFunctionConfiguration',
{
DeadLetterConfig: {
TargetArn: 'arn:aws:sqs:us-east-1:123456789012:dlq',
},
Handler: 'my_handler',
Description: 'desc',
Environment: {
Variables: {
VARIABLE: 'value',
},
},
FunctionName: 'first',
KMSKeyArn: 'arn:aws:kms:us-east-1:123456789012',
MemorySize: 128,
Role: 'arn:aws:us-east-1:123456789012:role/role',
Timeout: 3,
VpcConfig: {
SecurityGroupIds: ['1'],
SubnetIds: ['2'],
},
Layers: ['arn:aws:lambda:us-east-1:123456789012:layer:layer:1'],
}
);
});
});
});

describe('#deployFunction()', () => {
Expand Down

0 comments on commit d67a0ad

Please sign in to comment.