2017-04-06 18:30:20 +07:00

140 lines
5.1 KiB
JavaScript

'use strict';
const _ = require('lodash');
class AwsCompileCloudWatchLogEvents {
constructor(serverless) {
this.serverless = serverless;
this.provider = this.serverless.getProvider('aws');
this.hooks = {
'package:compileEvents': this.compileCloudWatchLogEvents.bind(this),
};
}
compileCloudWatchLogEvents() {
const logGroupNames = [];
this.serverless.service.getAllFunctions().forEach((functionName) => {
const functionObj = this.serverless.service.getFunction(functionName);
let cloudWatchLogNumberInFunction = 0;
if (functionObj.events) {
functionObj.events.forEach(event => {
if (event.cloudwatchLog) {
cloudWatchLogNumberInFunction++;
let LogGroupName;
let FilterPattern;
if (typeof event.cloudwatchLog === 'object') {
if (!event.cloudwatchLog.logGroup) {
const errorMessage = [
'Missing "logGroup" property for cloudwatchLog event ',
`in function ${functionName} Please check the docs for more info.`,
].join('');
throw new this.serverless.classes
.Error(errorMessage);
}
if (event.cloudwatchLog.filter && typeof event.cloudwatchLog.filter !== 'string') {
const errorMessage = [
`"filter" property for cloudwatchLog event in function ${functionName} `,
'should be string. Please check the docs for more info.',
].join('');
throw new this.serverless.classes
.Error(errorMessage);
}
LogGroupName = event.cloudwatchLog.logGroup.replace(/\r?\n/g, '');
FilterPattern = event.cloudwatchLog.filter ?
event.cloudwatchLog.filter.replace(/\r?\n/g, '') : '';
} else if (typeof event.cloudwatchLog === 'string') {
LogGroupName = event.cloudwatchLog.replace(/\r?\n/g, '');
FilterPattern = '';
} else {
const errorMessage = [
`cloudwatchLog event of function "${functionName}" is not an object or a string`,
' Please check the docs for more info.',
].join('');
throw new this.serverless.classes
.Error(errorMessage);
}
if (_.indexOf(logGroupNames, LogGroupName) !== -1) {
const errorMessage = [
`"${LogGroupName}" logGroup for cloudwatchLog event is duplicated.`,
' This property can only be set once per CloudFormation stack.',
].join('');
throw new this.serverless.classes
.Error(errorMessage);
}
logGroupNames.push(LogGroupName);
const lambdaLogicalId = this.provider.naming
.getLambdaLogicalId(functionName);
const cloudWatchLogLogicalId = this.provider.naming
.getCloudWatchLogLogicalId(functionName, cloudWatchLogNumberInFunction);
const lambdaPermissionLogicalId = this.provider.naming
.getLambdaCloudWatchLogPermissionLogicalId(functionName,
cloudWatchLogNumberInFunction);
const cloudWatchLogRuleTemplate = `
{
"Type": "AWS::Logs::SubscriptionFilter",
"DependsOn": "${lambdaPermissionLogicalId}",
"Properties": {
"LogGroupName": "${LogGroupName}",
"FilterPattern": "${FilterPattern}",
"DestinationArn": { "Fn::GetAtt": ["${lambdaLogicalId}", "Arn"] }
}
}
`;
const permissionTemplate = `
{
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": { "Fn::GetAtt": ["${
lambdaLogicalId}", "Arn"] },
"Action": "lambda:InvokeFunction",
"Principal": {
"Fn::Join": [ "", [
"logs.",
{ "Ref": "AWS::Region" },
".amazonaws.com"
] ]
},
"SourceArn": {
"Fn::Join": [ "", [
"arn:aws:logs:",
{ "Ref": "AWS::Region" },
":",
{ "Ref": "AWS::AccountId" },
":log-group:",
"${LogGroupName}",
":*"
] ]
}
}
}
`;
const newCloudWatchLogRuleObject = {
[cloudWatchLogLogicalId]: JSON.parse(cloudWatchLogRuleTemplate),
};
const newPermissionObject = {
[lambdaPermissionLogicalId]: JSON.parse(permissionTemplate),
};
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
newCloudWatchLogRuleObject, newPermissionObject);
}
});
}
});
}
}
module.exports = AwsCompileCloudWatchLogEvents;