mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
197 lines
6.7 KiB
JavaScript
197 lines
6.7 KiB
JavaScript
import _ from 'lodash'
|
|
import ServerlessError from '../../../../../serverless-error.js'
|
|
import resolveLambdaTarget from '../../../utils/resolve-lambda-target.js'
|
|
|
|
class AwsCompileCloudWatchEventEvents {
|
|
constructor(serverless) {
|
|
this.serverless = serverless
|
|
this.provider = this.serverless.getProvider('aws')
|
|
|
|
this.hooks = {
|
|
'package:compileEvents': async () => this.compileCloudWatchEventEvents(),
|
|
}
|
|
|
|
this.serverless.configSchemaHandler.defineFunctionEvent(
|
|
'aws',
|
|
'cloudwatchEvent',
|
|
{
|
|
type: 'object',
|
|
properties: {
|
|
event: { type: 'object' },
|
|
input: {
|
|
anyOf: [{ type: 'string', maxLength: 8192 }, { type: 'object' }],
|
|
},
|
|
inputPath: { type: 'string', minLength: 1, maxLength: 256 },
|
|
inputTransformer: {
|
|
type: 'object',
|
|
properties: {
|
|
inputPathsMap: {
|
|
type: 'object',
|
|
additionalProperties: { type: 'string', minLength: 1 },
|
|
},
|
|
inputTemplate: { type: 'string', minLength: 1, maxLength: 8192 },
|
|
},
|
|
required: ['inputTemplate'],
|
|
additionalProperties: false,
|
|
},
|
|
description: { type: 'string', maxLength: 512 },
|
|
name: {
|
|
type: 'string',
|
|
pattern: '[a-zA-Z0-9-_.]+',
|
|
minLength: 1,
|
|
maxLength: 64,
|
|
},
|
|
enabled: { type: 'boolean' },
|
|
},
|
|
additionalProperties: false,
|
|
},
|
|
)
|
|
}
|
|
|
|
compileCloudWatchEventEvents() {
|
|
this.serverless.service.getAllFunctions().forEach((functionName) => {
|
|
const functionObj = this.serverless.service.getFunction(functionName)
|
|
let cloudWatchEventNumberInFunction = 0
|
|
|
|
if (functionObj.events) {
|
|
functionObj.events.forEach((event) => {
|
|
if (event.cloudwatchEvent) {
|
|
cloudWatchEventNumberInFunction++
|
|
let State
|
|
let Input
|
|
let InputTransformer
|
|
|
|
const EventPattern = JSON.stringify(event.cloudwatchEvent.event)
|
|
State = 'ENABLED'
|
|
if (event.cloudwatchEvent.enabled === false) {
|
|
State = 'DISABLED'
|
|
}
|
|
const Name = event.cloudwatchEvent.name
|
|
const InputPath = event.cloudwatchEvent.inputPath
|
|
const Description = event.cloudwatchEvent.description
|
|
Input = event.cloudwatchEvent.input
|
|
InputTransformer = event.cloudwatchEvent.inputTransformer
|
|
|
|
if (
|
|
[Input, InputPath, InputTransformer].filter(Boolean).length > 1
|
|
) {
|
|
throw new ServerlessError(
|
|
[
|
|
'You can only set one of input, inputPath, or inputTransformer ',
|
|
'properties at the same time for cloudwatch events. ',
|
|
'Please check the AWS docs for more info',
|
|
].join(''),
|
|
'CLOUDWATCH_MULTIPLE_INPUT_PROPERTIES',
|
|
)
|
|
}
|
|
|
|
if (Input && typeof Input === 'object') {
|
|
Input = JSON.stringify(Input)
|
|
}
|
|
if (Input && typeof Input === 'string') {
|
|
// escape quotes to favor JSON.parse
|
|
Input = Input.replace(/"/g, '\\"')
|
|
}
|
|
if (InputTransformer) {
|
|
InputTransformer = this.formatInputTransformer(InputTransformer)
|
|
}
|
|
|
|
const cloudWatchLogicalId =
|
|
this.provider.naming.getCloudWatchEventLogicalId(
|
|
functionName,
|
|
cloudWatchEventNumberInFunction,
|
|
)
|
|
const lambdaPermissionLogicalId =
|
|
this.provider.naming.getLambdaCloudWatchEventPermissionLogicalId(
|
|
functionName,
|
|
cloudWatchEventNumberInFunction,
|
|
)
|
|
const cloudWatchId =
|
|
this.provider.naming.getCloudWatchEventId(functionName)
|
|
|
|
const dependsOn = _.get(functionObj.targetAlias, 'logicalId')
|
|
|
|
const cloudWatchEventRuleTemplate = `
|
|
{
|
|
"Type": "AWS::Events::Rule",
|
|
${dependsOn ? `"DependsOn": "${dependsOn}",` : ''}
|
|
"Properties": {
|
|
"EventPattern": ${EventPattern.replace(/\\n|\\r/g, '')},
|
|
"State": "${State}",
|
|
${Description ? `"Description": "${Description}",` : ''}
|
|
${Name ? `"Name": "${Name}",` : ''}
|
|
"Targets": [{
|
|
${
|
|
Input
|
|
? `"Input": "${Input.replace(/\\n|\\r/g, '')}",`
|
|
: ''
|
|
}
|
|
${
|
|
InputPath
|
|
? `"InputPath": "${InputPath.replace(/\r?\n/g, '')}",`
|
|
: ''
|
|
}
|
|
${
|
|
InputTransformer
|
|
? `"InputTransformer": ${InputTransformer},`
|
|
: ''
|
|
}
|
|
"Arn": ${JSON.stringify(
|
|
resolveLambdaTarget(functionName, functionObj),
|
|
)},
|
|
"Id": "${cloudWatchId}"
|
|
}]
|
|
}
|
|
}
|
|
`
|
|
|
|
const permissionTemplate = `
|
|
{
|
|
"Type": "AWS::Lambda::Permission",
|
|
${dependsOn ? `"DependsOn": "${dependsOn}",` : ''}
|
|
"Properties": {
|
|
"FunctionName": ${JSON.stringify(
|
|
resolveLambdaTarget(functionName, functionObj),
|
|
)},
|
|
"Action": "lambda:InvokeFunction",
|
|
"Principal": "events.amazonaws.com",
|
|
"SourceArn": { "Fn::GetAtt": ["${cloudWatchLogicalId}", "Arn"] }
|
|
}
|
|
}
|
|
`
|
|
|
|
const newCloudWatchEventRuleObject = {
|
|
[cloudWatchLogicalId]: JSON.parse(cloudWatchEventRuleTemplate),
|
|
}
|
|
|
|
const newPermissionObject = {
|
|
[lambdaPermissionLogicalId]: JSON.parse(permissionTemplate),
|
|
}
|
|
|
|
_.merge(
|
|
this.serverless.service.provider.compiledCloudFormationTemplate
|
|
.Resources,
|
|
newCloudWatchEventRuleObject,
|
|
newPermissionObject,
|
|
)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
formatInputTransformer(inputTransformer) {
|
|
const cfmOutput = {
|
|
// InputTemplate is required
|
|
InputTemplate: inputTransformer.inputTemplate,
|
|
}
|
|
// InputPathsMap is optional
|
|
if (inputTransformer.inputPathsMap) {
|
|
cfmOutput.InputPathsMap = inputTransformer.inputPathsMap
|
|
}
|
|
return JSON.stringify(cfmOutput)
|
|
}
|
|
}
|
|
|
|
export default AwsCompileCloudWatchEventEvents
|