Skip to content

Commit 1c57a94

Browse files
authored
Merge pull request #151 from iwaiktos/add-cloudwatchevent
Add support for CloudWatch Events
2 parents 74f5a44 + 4873149 commit 1c57a94

File tree

5 files changed

+580
-2
lines changed

5 files changed

+580
-2
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
'use strict';
2+
3+
const _ = require('lodash');
4+
const BbPromise = require('bluebird');
5+
6+
module.exports = {
7+
compileCloudWatchEventEvents() {
8+
_.forEach(this.getAllStateMachines(), (stateMachineName) => {
9+
const stateMachineObj = this.getStateMachine(stateMachineName);
10+
let cloudWatchEventNumberInFunction = 0;
11+
12+
if (stateMachineObj.events) {
13+
_.forEach(stateMachineObj.events, (event) => {
14+
if (event.cloudwatchEvent) {
15+
cloudWatchEventNumberInFunction++;
16+
let EventPattern;
17+
let State;
18+
let Input;
19+
let InputPath;
20+
let Description;
21+
let Name;
22+
23+
if (typeof event.cloudwatchEvent === 'object') {
24+
if (!event.cloudwatchEvent.event) {
25+
const errorMessage = [
26+
`Missing "event" property for cloudwatch event in stateMachine ${stateMachineName}`, // eslint-disable-line max-len
27+
' Please check the docs for more info.',
28+
].join('');
29+
throw new this.serverless.classes
30+
.Error(errorMessage);
31+
}
32+
33+
EventPattern = JSON.stringify(event.cloudwatchEvent.event);
34+
State = 'ENABLED';
35+
if (event.cloudwatchEvent.enabled === false) {
36+
State = 'DISABLED';
37+
}
38+
Input = event.cloudwatchEvent.input;
39+
InputPath = event.cloudwatchEvent.inputPath;
40+
Description = event.cloudwatchEvent.description;
41+
Name = event.cloudwatchEvent.name;
42+
43+
if (Input && InputPath) {
44+
const errorMessage = [
45+
'You can\'t set both input & inputPath properties at the',
46+
'same time for cloudwatch events.',
47+
'Please check the AWS docs for more info',
48+
].join('');
49+
throw new this.serverless.classes.Error(errorMessage);
50+
}
51+
52+
if (Input && typeof Input === 'object') {
53+
Input = JSON.stringify(Input);
54+
}
55+
if (Input && typeof Input === 'string') {
56+
// escape quotes to favor JSON.parse
57+
Input = Input.replace(/\"/g, '\\"'); // eslint-disable-line
58+
}
59+
} else {
60+
const errorMessage = [
61+
`CloudWatch event of stateMachine "${stateMachineName}" is not an object`,
62+
' Please check the docs for more info.',
63+
].join('');
64+
throw new this.serverless.classes
65+
.Error(errorMessage);
66+
}
67+
68+
const stateMachineLogicalId = this
69+
.getStateMachineLogicalId(stateMachineName, stateMachineObj);
70+
const cloudWatchLogicalId = this
71+
.getCloudWatchEventLogicalId(stateMachineName, cloudWatchEventNumberInFunction);
72+
const cloudWatchIamRoleLogicalId = this
73+
.getCloudWatchEventToStepFunctionsIamRoleLogicalId(stateMachineName);
74+
const cloudWatchId = this.getCloudWatchEventId(stateMachineName);
75+
const policyName = this.getCloudWatchEventPolicyName(stateMachineName);
76+
77+
const cloudWatchEventRuleTemplate = `
78+
{
79+
"Type": "AWS::Events::Rule",
80+
"Properties": {
81+
"EventPattern": ${EventPattern.replace(/\\n|\\r/g, '')},
82+
"State": "${State}",
83+
${Description ? `"Description": "${Description}",` : ''}
84+
${Name ? `"Name": "${Name}",` : ''}
85+
"Targets": [{
86+
${Input ? `"Input": "${Input.replace(/\\n|\\r/g, '')}",` : ''}
87+
${InputPath ? `"InputPath": "${InputPath.replace(/\r?\n/g, '')}",` : ''}
88+
"Arn": { "Ref": "${stateMachineLogicalId}" },
89+
"Id": "${cloudWatchId}",
90+
"RoleArn": {
91+
"Fn::GetAtt": [
92+
"${cloudWatchIamRoleLogicalId}",
93+
"Arn"
94+
]
95+
}
96+
}]
97+
}
98+
}
99+
`;
100+
101+
const iamRoleTemplate = `
102+
{
103+
"Type": "AWS::IAM::Role",
104+
"Properties": {
105+
"AssumeRolePolicyDocument": {
106+
"Version": "2012-10-17",
107+
"Statement": [
108+
{
109+
"Effect": "Allow",
110+
"Principal": {
111+
"Service": "events.amazonaws.com"
112+
},
113+
"Action": "sts:AssumeRole"
114+
}
115+
]
116+
},
117+
"Policies": [
118+
{
119+
"PolicyName": "${policyName}",
120+
"PolicyDocument": {
121+
"Version": "2012-10-17",
122+
"Statement": [
123+
{
124+
"Effect": "Allow",
125+
"Action": [
126+
"states:StartExecution"
127+
],
128+
"Resource": {
129+
"Ref": "${stateMachineLogicalId}"
130+
}
131+
}
132+
]
133+
}
134+
}
135+
]
136+
}
137+
}
138+
`;
139+
140+
const newCloudWatchEventRuleObject = {
141+
[cloudWatchLogicalId]: JSON.parse(cloudWatchEventRuleTemplate),
142+
};
143+
144+
const newPermissionObject = {
145+
[cloudWatchIamRoleLogicalId]: JSON.parse(iamRoleTemplate),
146+
};
147+
148+
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
149+
newCloudWatchEventRuleObject, newPermissionObject);
150+
}
151+
});
152+
}
153+
});
154+
return BbPromise.resolve();
155+
},
156+
};

0 commit comments

Comments
 (0)