Skip to content

Commit 58bf73c

Browse files
author
Sergii Kovalev
committed
Fix SNS for case when function names where function name A startwith function name B
- test stack updated with case that covers the issue
1 parent 58ebcbd commit 58bf73c

File tree

7 files changed

+266
-23
lines changed

7 files changed

+266
-23
lines changed

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
/node_modules
2-
/coverage
3-
/.nyc_output
42

53
# Jetbrains IDEs
64
.idea/

lib/stackops/apiGateway.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
186186
this.options.verbose && this._serverless.cli.log('Configuring stage');
187187
const stageResource = internal.createStageResource.call(this, `${stackName}-ApiGatewayRestApi`, deploymentName);
188188
aliasResources.push({ ApiGatewayStage: stageResource });
189-
189+
190190
const baseMapping = _.assign({}, _.pickBy(stageStack.Resources, ['Type', 'AWS::ApiGateway::BasePathMapping']));
191191
if (!_.isEmpty(baseMapping)) {
192192
const baseMappingName = _.keys(baseMapping)[0];
@@ -198,7 +198,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
198198
aliasResources.push(baseMapping);
199199
delete stageStack.Resources[baseMappingName];
200200
}
201-
}
201+
}
202202

203203
// Fetch lambda permissions, methods and resources. These have to be updated later to allow the aliased functions.
204204
const apiLambdaPermissions =
@@ -280,7 +280,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
280280
const functionName = _.replace(name, /LambdaPermissionApiGateway$/, '');
281281
const versionName = _.find(_.keys(versions), version => _.startsWith(version, `${functionName}LambdaVersion`));
282282
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, `${functionName}Alias`));
283-
const isExternalRef = isExternalRefAuthorizerPredicate(permission.Properties.FunctionName);
283+
const isExternalRef = isExternalRefAuthorizerPredicate(permission.Properties.FunctionName);
284284

285285
// Adjust references and alias permissions
286286
if (!isExternalRef) {
@@ -305,9 +305,9 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
305305
]
306306
};
307307
}
308-
308+
309309
// Add dependency on function version
310-
if (!isExternalRef) {
310+
if (!isExternalRef) {
311311
permission.DependsOn = [ versionName, aliasName ];
312312
} else {
313313
permission.DependsOn = _.compact([ versionName, aliasName ]);

lib/stackops/snsEvents.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
3131
_.forOwn(lambdaSubscriptions, subscription => {
3232
const functionNameRef = utils.findAllReferences(_.get(subscription, 'Endpoint'));
3333
const functionName = _.replace(_.get(functionNameRef, '[0].ref', ''), /LambdaFunction$/, '');
34-
const versionName = _.find(_.keys(versions), version => _.startsWith(version, functionName));
35-
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName));
34+
const versionName = _.find(_.keys(versions), version => _.startsWith(version, `${functionName}LambdaVersion`));
35+
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, `${functionName}Alias`));
3636

3737
subscription.Endpoint = { Ref: aliasName };
3838

@@ -54,8 +54,8 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
5454

5555
const functionNameRef = utils.findAllReferences(_.get(subscription.Properties, 'Endpoint'));
5656
const functionName = _.replace(_.get(functionNameRef, '[0].ref', ''), /LambdaFunction$/, '');
57-
const versionName = _.find(_.keys(versions), version => _.startsWith(version, functionName));
58-
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName));
57+
const versionName = _.find(_.keys(versions), version => _.startsWith(version, `${functionName}LambdaVersion`));
58+
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, `${functionName}Alias`));
5959

6060
subscription.Properties.Endpoint = { Ref: aliasName };
6161
subscription.DependsOn = [ versionName, aliasName ];
@@ -72,8 +72,8 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
7272
// Adjust permission to reference the function aliases
7373
_.forOwn(snsLambdaPermissions, (permission, name) => {
7474
const functionName = _.replace(name, /LambdaPermission.*$/, '');
75-
const versionName = _.find(_.keys(versions), version => _.startsWith(version, functionName));
76-
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName));
75+
const versionName = _.find(_.keys(versions), version => _.startsWith(version, `${functionName}LambdaVersion`));
76+
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, `${functionName}Alias`));
7777

7878
// Adjust references and alias permissions
7979
permission.Properties.FunctionName = { Ref: aliasName };

lib/utils.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ class Utils {
8989

9090
/**
9191
* Checks if a CF resource permission targets the given service as Principal.
92-
* @param {string} service
92+
* @param {Object} permission
93+
* @param {string} service
9394
*/
9495
static hasPermissionPrincipal(permission, service) {
9596
const principal = _.get(permission, 'Properties.Principal');

test/data/alias-stack-1.json

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,25 @@
99
"RetentionInDays": 7
1010
}
1111
},
12+
"Testfct1WithSuffixAlias": {
13+
"Type": "AWS::Lambda::Alias",
14+
"Properties": {
15+
"Description": "Echo function echoes alias",
16+
"FunctionName": {
17+
"Fn::ImportValue": "sls-test-project-dev-Testfct1WithSuffix-LambdaFunctionArn"
18+
},
19+
"FunctionVersion": {
20+
"Fn::GetAtt": [
21+
"Testfct1WithSuffixLambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU",
22+
"Version"
23+
]
24+
},
25+
"Name": "myAlias"
26+
},
27+
"DependsOn": [
28+
"Testfct1WithSuffixLambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU"
29+
]
30+
},
1231
"Testfct1Alias": {
1332
"Type": "AWS::Lambda::Alias",
1433
"Properties": {
@@ -47,6 +66,17 @@
4766
"WarmUpPluginLambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU"
4867
]
4968
},
69+
"Testfct1WithSuffixLambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU": {
70+
"Type": "AWS::Lambda::Version",
71+
"DeletionPolicy": "Delete",
72+
"Properties": {
73+
"FunctionName": {
74+
"Fn::ImportValue": "sls-test-project-dev-Testfct1WithSuffix-LambdaFunctionArn"
75+
},
76+
"CodeSha256": "Wh5jTkiTR67+V05RPWQIlzPI25WiPbdHDYNgbtAMneU=",
77+
"Description": "Echo function echoes alias"
78+
}
79+
},
5080
"Testfct1LambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU": {
5181
"Type": "AWS::Lambda::Version",
5282
"DeletionPolicy": "Delete",
@@ -97,6 +127,40 @@
97127
"ApiGatewayDeployment1494367071211"
98128
]
99129
},
130+
"Testfct1WithSuffixLambdaPermissionApiGateway": {
131+
"Type": "AWS::Lambda::Permission",
132+
"Properties": {
133+
"FunctionName": {
134+
"Ref": "Testfct1WithSuffixAlias"
135+
},
136+
"Action": "lambda:InvokeFunction",
137+
"Principal": "apigateway.amazonaws.com",
138+
"SourceArn": {
139+
"Fn::Join": [
140+
"",
141+
[
142+
"arn:aws:execute-api:",
143+
{
144+
"Ref": "AWS::Region"
145+
},
146+
":",
147+
{
148+
"Ref": "AWS::AccountId"
149+
},
150+
":",
151+
{
152+
"Fn::ImportValue": "sls-test-project-dev-ApiGatewayRestApi"
153+
},
154+
"/*/*"
155+
]
156+
]
157+
}
158+
},
159+
"DependsOn": [
160+
"Testfct1WithSuffixLambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU",
161+
"Testfct1WithSuffixAlias"
162+
]
163+
},
100164
"Testfct1LambdaPermissionApiGateway": {
101165
"Type": "AWS::Lambda::Permission",
102166
"Properties": {

test/data/sls-stack-1.json

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"LogGroupName": "/aws/lambda/sls-test-project-dev-testfct1"
1212
}
1313
},
14+
"Testfct1WithSuffixLogGroup": {
15+
"Type": "AWS::Logs::LogGroup",
16+
"Properties": {
17+
"LogGroupName": "/aws/lambda/sls-test-project-dev-testfct1-with-suffix"
18+
}
19+
},
1420
"WarmUpPluginLogGroup": {
1521
"Type": "AWS::Logs::LogGroup",
1622
"Properties": {
@@ -197,6 +203,70 @@
197203
"Description": "Echo function echoes alias"
198204
}
199205
},
206+
"Testfct1WithSuffixLambdaFunction": {
207+
"Type": "AWS::Lambda::Function",
208+
"Properties": {
209+
"Code": {
210+
"S3Bucket": {
211+
"Ref": "ServerlessDeploymentBucket"
212+
},
213+
"S3Key": "serverless/sls-test-project/dev/1494367071172-2017-05-09T21:57:51.172Z/sls-test-project.zip"
214+
},
215+
"FunctionName": "sls-test-project-dev-testfct1-with-suffix",
216+
"Handler": "handlers/testfct1-with-suffix/handler.handle",
217+
"MemorySize": 512,
218+
"Role": {
219+
"Fn::GetAtt": [
220+
"IamRoleLambdaExecution",
221+
"Arn"
222+
]
223+
},
224+
"Runtime": "nodejs4.3",
225+
"Timeout": 15,
226+
"Description": "Echo function echoes alias",
227+
"Environment": {
228+
"Variables": {
229+
"SERVERLESS_PROJECT_NAME": "sls-test-project",
230+
"SERVERLESS_PROJECT": "sls-test-project",
231+
"SERVERLESS_STAGE": "dev",
232+
"SERVERLESS_REGION": "us-east-1",
233+
"TEST_TABLE_NAME": {
234+
"Ref": "TestDynamoDbTable"
235+
}
236+
}
237+
},
238+
"VpcConfig": {
239+
"SecurityGroupIds": [
240+
{
241+
"Fn::ImportValue": "stashimi-dev-PrivateSG"
242+
}
243+
],
244+
"SubnetIds": [
245+
{
246+
"Fn::ImportValue": "stashimi-dev-PrivateSubnet1"
247+
},
248+
{
249+
"Fn::ImportValue": "stashimi-dev-PrivateSubnet2"
250+
}
251+
]
252+
}
253+
},
254+
"DependsOn": [
255+
"Testfct1WithSuffixLogGroup",
256+
"IamRoleLambdaExecution"
257+
]
258+
},
259+
"Testfct1WithSuffixLambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU": {
260+
"Type": "AWS::Lambda::Version",
261+
"DeletionPolicy": "Retain",
262+
"Properties": {
263+
"FunctionName": {
264+
"Ref": "Testfct1WithSuffixLambdaFunction"
265+
},
266+
"CodeSha256": "Wh5jTkiTR67+V05RPWQIlzPI25WiPbdHDYNgbtAMneU=",
267+
"Description": "Echo function echoes alias"
268+
}
269+
},
200270
"WarmUpPluginLambdaFunction": {
201271
"Type": "AWS::Lambda::Function",
202272
"Properties": {
@@ -401,6 +471,104 @@
401471
]
402472
}
403473
}
474+
},
475+
"ApiGatewayResourceFunc2": {
476+
"Type": "AWS::ApiGateway::Resource",
477+
"Properties": {
478+
"ParentId": {
479+
"Fn::GetAtt": [
480+
"ApiGatewayRestApi",
481+
"RootResourceId"
482+
]
483+
},
484+
"PathPart": "func1-with-suffix",
485+
"RestApiId": {
486+
"Ref": "ApiGatewayRestApi"
487+
}
488+
}
489+
},
490+
"ApiGatewayMethodFunc2Get": {
491+
"Type": "AWS::ApiGateway::Method",
492+
"Properties": {
493+
"HttpMethod": "GET",
494+
"RequestParameters": {},
495+
"ResourceId": {
496+
"Ref": "ApiGatewayResourceFunc2"
497+
},
498+
"RestApiId": {
499+
"Ref": "ApiGatewayRestApi"
500+
},
501+
"AuthorizationType": "NONE",
502+
"Integration": {
503+
"IntegrationHttpMethod": "POST",
504+
"Type": "AWS_PROXY",
505+
"Uri": {
506+
"Fn::Join": [
507+
"",
508+
[
509+
"arn:aws:apigateway:",
510+
{
511+
"Ref": "AWS::Region"
512+
},
513+
":lambda:path/2015-03-31/functions/",
514+
{
515+
"Fn::GetAtt": [
516+
"Testfct1WithSuffixLambdaFunction",
517+
"Arn"
518+
]
519+
},
520+
"/invocations"
521+
]
522+
]
523+
}
524+
},
525+
"MethodResponses": []
526+
}
527+
},
528+
"ApiGatewayDeployment1494367071212": {
529+
"Type": "AWS::ApiGateway::Deployment",
530+
"Properties": {
531+
"RestApiId": {
532+
"Ref": "ApiGatewayRestApi"
533+
},
534+
"StageName": "dev"
535+
},
536+
"DependsOn": [
537+
"ApiGatewayMethodFunc2Get"
538+
]
539+
},
540+
"Testfct1WithSuffixLambdaPermissionApiGateway": {
541+
"Type": "AWS::Lambda::Permission",
542+
"Properties": {
543+
"FunctionName": {
544+
"Fn::GetAtt": [
545+
"Testfct1WithSuffixLambdaFunction",
546+
"Arn"
547+
]
548+
},
549+
"Action": "lambda:InvokeFunction",
550+
"Principal": "apigateway.amazonaws.com",
551+
"SourceArn": {
552+
"Fn::Join": [
553+
"",
554+
[
555+
"arn:aws:execute-api:",
556+
{
557+
"Ref": "AWS::Region"
558+
},
559+
":",
560+
{
561+
"Ref": "AWS::AccountId"
562+
},
563+
":",
564+
{
565+
"Ref": "ApiGatewayRestApi"
566+
},
567+
"/*/*"
568+
]
569+
]
570+
}
571+
}
404572
}
405573
},
406574
"Outputs": {
@@ -415,6 +583,12 @@
415583
"Ref": "Testfct1LambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU"
416584
}
417585
},
586+
"Testfct1WithSuffixLambdaFunctionQualifiedArn": {
587+
"Description": "Current Lambda function version",
588+
"Value": {
589+
"Ref": "Testfct1WithSuffixLambdaVersionWh5jTkiTR67V05RPWQIlzPI25WiPbdHDYNgbtAMneU"
590+
}
591+
},
418592
"WarmUpPluginLambdaFunctionQualifiedArn": {
419593
"Description": "Current Lambda function version",
420594
"Value": {

0 commit comments

Comments
 (0)