Skip to content

Commit

Permalink
updating logical ids
Browse files Browse the repository at this point in the history
  • Loading branch information
eahefnawy committed Aug 31, 2016
1 parent 308889b commit a5e3c31
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 115 deletions.
Expand Up @@ -22,15 +22,15 @@ module.exports = {
"Enabled" : true,
"Name" : "${apiKey}",
"StageKeys" : [{
"RestApiId": { "Ref": "RestApiApigEvent" },
"RestApiId": { "Ref": "ApiGatewayRestApi" },
"StageName": "${this.options.stage}"
}]
}
}
`;

const newApiKeyObject = {
[`ApiKeyApigEvent${index}`]: JSON.parse(apiKeysTemplate),
[`ApiGatewayApiKey${index}`]: JSON.parse(apiKeysTemplate),
};

_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
Expand Down
Expand Up @@ -16,9 +16,14 @@ module.exports = {

if (typeof authorizer === 'string') {
if (authorizer.indexOf(':') === -1) {
this.serverless.service.getFunction(authorizer);
authorizerArn = `",{"Fn::GetAtt" : ["${authorizer}", "Arn"]},"`;
authorizerName = authorizer;

this.serverless.service.getFunction(authorizerName);

const normalizedAuthorizerName = authorizerName[0]
.toUpperCase() + authorizerName.substr(1);
authorizerArn = `",{"Fn::GetAtt" : ["LambdaFunction${
normalizedAuthorizerName}", "Arn"]},"`;
} else {
authorizerArn = authorizer;
const splittedAuthorizerArn = authorizerArn.split(':');
Expand All @@ -37,7 +42,10 @@ module.exports = {
authorizerName = splittedLambdaName[splittedLambdaName.length - 1];
} else if (authorizer.name) {
this.serverless.service.getFunction(authorizer.name);
authorizerArn = `",{"Fn::GetAtt" : ["${authorizer.name}", "Arn"]},"`;
const normalizedAuthorizerName = authorizer.name[0]
.toUpperCase() + authorizer.name.substr(1);
authorizerArn = `",{"Fn::GetAtt" : ["LambdaFunction${
normalizedAuthorizerName}", "Arn"]},"`;
authorizerName = authorizer.name;
} else {
throw new this.serverless.classes
Expand Down Expand Up @@ -68,7 +76,7 @@ module.exports = {
]]},
"IdentitySource" : "${identitySource}",
"Name" : "${authorizerName}",
"RestApiId" : { "Ref": "RestApiApigEvent" },
"RestApiId" : { "Ref": "ApiGatewayRestApi" },
"Type" : "TOKEN"
}
}
Expand All @@ -83,8 +91,11 @@ module.exports = {
authorizer.identityValidationExpression;
}

const normalizedAuthorizerName = authorizerName[0]
.toUpperCase() + authorizerName.substr(1);

const authorizerObject = {
[`${authorizerName}Authorizer`]: authorizerTemplateJson,
[`ApiGatewayAuthorizer${normalizedAuthorizerName}`]: authorizerTemplateJson,
};

_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
Expand Down
Expand Up @@ -9,13 +9,13 @@ module.exports = {
{
"Type" : "AWS::ApiGateway::Deployment",
"Properties" : {
"RestApiId" : { "Ref": "RestApiApigEvent" },
"RestApiId" : { "Ref": "ApiGatewayRestApi" },
"StageName" : "${this.options.stage}"
}
}
`;

const deploymentLogicalId = `DeploymentApigEvent${(new Date()).getTime().toString()}`;
const deploymentLogicalId = `ApiGatewayDeployment${(new Date()).getTime().toString()}`;
const deploymentTemplateJson = JSON.parse(deploymentTemplate);
deploymentTemplateJson.DependsOn = this.methodDependencies;

Expand Down
Expand Up @@ -8,18 +8,19 @@ module.exports = {
_.forEach(this.serverless.service.functions, (functionObj, functionName) => {
functionObj.events.forEach(event => {
if (event.http) {
const normalizedFunctionName = functionName[0].toUpperCase() + functionName.substr(1);
const permissionTemplate = `
{
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": { "Fn::GetAtt": ["${functionName}", "Arn"] },
"FunctionName": { "Fn::GetAtt": ["LambdaFunction${normalizedFunctionName}", "Arn"] },
"Action": "lambda:InvokeFunction",
"Principal": "apigateway.amazonaws.com"
}
}
`;

const permissionLogicalId = `${functionName}ApigPermission`;
const permissionLogicalId = `${functionName}LambdaPermissionApiGateway`;

const newPermissionObject = {
[permissionLogicalId]: JSON.parse(permissionTemplate),
Expand All @@ -34,7 +35,10 @@ module.exports = {
if (typeof event.http.authorizer === 'string') {
if (event.http.authorizer.indexOf(':') === -1) {
authorizerName = event.http.authorizer;
authorizerArn = `{ "Fn::GetAtt": ["${authorizerName}", "Arn"] }`;
const normalizedAuthorizerName = authorizerName[0]
.toUpperCase() + authorizerName.substr(1);
authorizerArn = `{ "Fn::GetAtt": ["LambdaFunction${
normalizedAuthorizerName}", "Arn"] }`;
} else {
authorizerArn = `"${event.http.authorizer}"`;
const splittedAuthorizerArn = event.http.authorizer.split(':');
Expand All @@ -51,7 +55,10 @@ module.exports = {
authorizerName = splittedLambdaName[splittedLambdaName.length - 1];
} else if (event.http.authorizer.name) {
authorizerName = event.http.authorizer.name;
authorizerArn = `{ "Fn::GetAtt": ["${authorizerName}", "Arn"] }`;
const normalizedAuthorizerName = authorizerName[0]
.toUpperCase() + authorizerName.substr(1);
authorizerArn = `{ "Fn::GetAtt": ["LambdaFunction${
normalizedAuthorizerName}", "Arn"] }`;
}
}

Expand All @@ -66,14 +73,14 @@ module.exports = {
}
`;

const authorizerPermissionLogicalId = `${authorizerName}ApigPermission`;
const authorizerPermissionLogicalId = `${authorizerName}LambdaPermissionApiGateway`;

const newAuthPermissionObject = {
const newAuthrizerPermissionObject = {
[authorizerPermissionLogicalId]: JSON.parse(authorizerPermissionTemplate),
};

_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
newAuthPermissionObject);
newAuthrizerPermissionObject);
}
}
});
Expand Down
Expand Up @@ -15,7 +15,7 @@ module.exports = {
`;

const newRestApiObject = {
RestApiApigEvent: JSON.parse(restApiTemplate),
ApiGatewayRestApi: JSON.parse(restApiTemplate),
};

_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
Expand Down
150 changes: 94 additions & 56 deletions lib/plugins/aws/deploy/compile/events/s3/index.js
Expand Up @@ -8,21 +8,21 @@ class AwsCompileS3Events {
this.provider = 'aws';

this.hooks = {
'deploy:compileEvents': this.compileS3Events.bind(this),
'deploy:compileEvents': this.this.compileS3Events.bind(this),
};
}

compileS3Events() {
const bucketsLambdaConfigurations = {};
const s3EnabledFunctions = [];
this.serverless.service.getAllFunctions().forEach((functionName) => {
const functionObj = this.serverless.service.getFunction(functionName);

if (functionObj.events) {
for (let i = 0; i < functionObj.events.length; i++) {
const event = functionObj.events[i];

functionObj.events.forEach(event => {
if (event.s3) {
let BucketName;
let Event = 's3:ObjectCreated:*';
let bucketName;
let notificationEvent = 's3:ObjectCreated:*';

if (typeof event.s3 === 'object') {
if (!event.s3.bucket) {
Expand All @@ -34,12 +34,12 @@ class AwsCompileS3Events {
throw new this.serverless.classes
.Error(errorMessage);
}
BucketName = event.s3.bucket + i;
bucketName = event.s3.bucket;
if (event.s3.event) {
Event = event.s3.event;
notificationEvent = event.s3.event;
}
} else if (typeof event.s3 === 'string') {
BucketName = event.s3 + i;
bucketName = event.s3;
} else {
const errorMessage = [
`S3 event of function ${functionName} is not an object nor a string.`,
Expand All @@ -49,59 +49,97 @@ class AwsCompileS3Events {
throw new this.serverless.classes
.Error(errorMessage);
}
const bucketTemplate = `
{
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": "${BucketName}",
"NotificationConfiguration": {
"LambdaConfigurations": [
{
"Event": "${Event}",
"Function": {
"Fn::GetAtt": [
"${functionName}",
"Arn"
]
}
}
]
}
}
}
`;

const permissionTemplate = `
{
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Fn::GetAtt": [
"${functionName}",
"Arn"
]
const normalizedFunctionName = functionName[0].toUpperCase() +
functionName.substr(1);

// check if the bucket already defined
// in another S3 event in the service
if (bucketsLambdaConfigurations[bucketName]) {
const newLambdaConfiguration = {
Event: notificationEvent,
Function: {
'Fn::GetAtt': [
`LambdaFunction${normalizedFunctionName}`,
'Arn',
],
},
};

bucketsLambdaConfigurations[bucketName]
.LambdaConfigurations.push(newLambdaConfiguration);
} else {
bucketsLambdaConfigurations[bucketName] = {
LambdaConfigurations: [
{
Event: notificationEvent,
Function: {
'Fn::GetAtt': [
`LambdaFunction${normalizedFunctionName}`,
'Arn',
],
},
},
"Action": "lambda:InvokeFunction",
"Principal": "s3.amazonaws.com"
}
}
`;
],
};
}
s3EnabledFunctions.push(functionName);
}
});
}
});

const bucketResourceKey = BucketName.replace(/-/g, '');
// iterate over all buckets to be created
// and compile them to CF resources
bucketsLambdaConfigurations.forEach((bucketLambdaConfiguration, bucketName) => {
const bucketTemplate = {
Type: 'AWS::S3::Bucket',
Properties: {
BucketName: bucketName,
NotificationConfiguration: {
LambdaConfigurations: bucketLambdaConfiguration,
},
},
};

const newBucketObject = {
[`${bucketResourceKey}S3Event`]: JSON.parse(bucketTemplate),
};
let normalizedBucketName = bucketName.replace(/-_\./g, '');
normalizedBucketName = normalizedBucketName[0].toUpperCase() +
normalizedBucketName.substr(1);

const newPermissionObject = {
[`${bucketResourceKey}S3EventPermission`]: JSON.parse(permissionTemplate),
};
const bucketLogicalID = `S3Bucket${normalizedBucketName}`;
const bucketCFResource = {
[bucketLogicalID]: bucketTemplate,
};
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
bucketCFResource);
});

_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
newBucketObject, newPermissionObject);
}
}
}
// iterate over all functions with S3 events
// and give S3 permission to invoke them all
// by adding Lambda::Permission resource for each
s3EnabledFunctions.forEach(functionName => {
const normalizedFunctionName = functionName[0].toUpperCase() +
functionName.substr(1);
const permissionTemplate = {
Type: 'AWS::Lambda::Permission',
Properties: {
FunctionName: {
'Fn::GetAtt': [
`LambdaFunction${normalizedFunctionName}`,
'Arn',
],
},
Action: 'lambda:InvokeFunction',
Principal: 's3.amazonaws.com',
},
};

const permissionLogicalID = `LambdaPermission${normalizedFunctionName}S3`;
const permissionCFResource = {
[permissionLogicalID]: permissionTemplate,
};
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
permissionCFResource);
});
}
}
Expand Down

0 comments on commit a5e3c31

Please sign in to comment.