@kumologica/sdk 3.2.0-beta13 → 3.2.0-beta14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/commands/export-commands/cloudformation.js +3 -2
- package/cli/commands/export-commands/utils/validator.js +51 -1
- package/package.json +4 -4
- package/src/app/lib/aws/index.js +103 -347
- package/src/app/ui/editor-client/public/red/red.js +20 -1
- package/src/app/ui/editor-client/public/red/red.min.js +1 -1
- package/src/app/ui/editor-client/src/js/ui/tab-awsDeploy.js +20 -1
- package/src/app/lib/aws/ca-alexa-api.js +0 -29
- package/src/app/lib/aws/cf.js +0 -449
|
@@ -329,6 +329,7 @@ RED.sidebar.awsDeploy = (function () {
|
|
|
329
329
|
<!--option value="lex">Amazon Lex</option-->
|
|
330
330
|
<!--option value="alexa">Amazon Alexa</option-->
|
|
331
331
|
<option selected value="api">Amazon API Gateway</option>
|
|
332
|
+
<option selected value="websocket">Amazon WebSocket API</option>
|
|
332
333
|
<!--option value="cf">Amazon CloudFront (Lambda@Edge)</option-->
|
|
333
334
|
<!--option value="firehose">Amazon Kinesis Data Firehose</option-->
|
|
334
335
|
<option disabled>────────────────────</option>
|
|
@@ -1385,6 +1386,16 @@ RED.sidebar.awsDeploy = (function () {
|
|
|
1385
1386
|
{ label: 'Resource', key: 'resource', value: '', required: false },
|
|
1386
1387
|
{ label: 'Authorizer Id', key: 'authorizerId', value: '', required: false }
|
|
1387
1388
|
];
|
|
1389
|
+
parameterSets['websocket'] = [
|
|
1390
|
+
{
|
|
1391
|
+
label: 'ApiId',
|
|
1392
|
+
key: 'apiId',
|
|
1393
|
+
value: '',
|
|
1394
|
+
required: true,
|
|
1395
|
+
function: 'attachDataList',
|
|
1396
|
+
},
|
|
1397
|
+
{ label: 'Deployment Stage', key: 'stage', value: '', required: true }
|
|
1398
|
+
];
|
|
1388
1399
|
parameterSets['alb'] = [
|
|
1389
1400
|
{
|
|
1390
1401
|
label: 'App Load Balancer',
|
|
@@ -1434,7 +1445,15 @@ RED.sidebar.awsDeploy = (function () {
|
|
|
1434
1445
|
parameterSets['cwevents'] = [
|
|
1435
1446
|
{ label: 'Expression', key: 'expression', value: 'cron()', required: true },
|
|
1436
1447
|
{ label: 'Reference', key: 'reference', value: '' },
|
|
1437
|
-
{ label: 'Name', key: 'name', value: ''}
|
|
1448
|
+
{ label: 'Name', key: 'name', value: ''},
|
|
1449
|
+
{ label: 'State',
|
|
1450
|
+
key: 'state',
|
|
1451
|
+
value: '',
|
|
1452
|
+
list: [
|
|
1453
|
+
{ k: 'ENABLED', v: 'ENABLED' },
|
|
1454
|
+
{ k: 'DISABLED', v: 'DISABLED' }
|
|
1455
|
+
],
|
|
1456
|
+
},
|
|
1438
1457
|
];
|
|
1439
1458
|
//parameterSets['cwlogs'] = [
|
|
1440
1459
|
// {
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
const AWS = require('aws-sdk');
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
* AWS JS API:
|
|
5
|
-
* https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html
|
|
6
|
-
*/
|
|
7
|
-
class CAAlexa {
|
|
8
|
-
|
|
9
|
-
constructor(log) {
|
|
10
|
-
this.log = log;
|
|
11
|
-
this.alexa = new AWS.AlexaForBusiness({region: 'us-east-1'});
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/AlexaForBusiness.html#listSkills-property
|
|
16
|
-
*/
|
|
17
|
-
async listSkills() {
|
|
18
|
-
|
|
19
|
-
const response = await this.alexa.listSkills({}).promise();
|
|
20
|
-
|
|
21
|
-
// {"SkillSummaries":[{"SkillId":"amzn1.ask.skill.8ac93c7f-22ec-48c7-a19d-de22baffc503","SkillName":"Writing Tips","SupportsLinking":false,"EnablementType":"ENABLED","SkillType":"PUBLIC"}]}
|
|
22
|
-
|
|
23
|
-
return response.SkillSummaries.map(function(v) {
|
|
24
|
-
return {id: v.SkillId, name: v.SkillName, arn: v.SkillName};
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
module.exports = CAAlexa;
|
package/src/app/lib/aws/cf.js
DELETED
|
@@ -1,449 +0,0 @@
|
|
|
1
|
-
const AWS = require('aws-sdk');
|
|
2
|
-
const jp = require('jsonpath');
|
|
3
|
-
const KLRekognition = require('./kl-rekognition-api');
|
|
4
|
-
|
|
5
|
-
class AWSCFTemplate {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.rekognition = new KLRekognition();
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/*
|
|
11
|
-
* Creates cloud formation template file for current lambda:
|
|
12
|
-
* It is composed of:
|
|
13
|
-
* - lambda definition
|
|
14
|
-
* - lambda's role
|
|
15
|
-
* - lambda's policy
|
|
16
|
-
* - if event subriptions confirmed then event source mappings for:
|
|
17
|
-
* - dynamodb stream
|
|
18
|
-
* - sns
|
|
19
|
-
* - kinesis
|
|
20
|
-
* - if flow nodes are provided then
|
|
21
|
-
* - role added for each downstream aws node
|
|
22
|
-
*/
|
|
23
|
-
createCfTemplate(params, settings, nodes, region) {
|
|
24
|
-
let ts = new Date();
|
|
25
|
-
|
|
26
|
-
let template = {
|
|
27
|
-
AWSTemplateFormatVersion: '2010-09-09',
|
|
28
|
-
Resources: {},
|
|
29
|
-
Outputs: {
|
|
30
|
-
LambdaArn: {
|
|
31
|
-
Description: 'The Arn of the cloud action flow lambda.',
|
|
32
|
-
Value: { 'Fn::GetAtt': ['Lambda', 'Arn'] }
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
let lambda = {
|
|
38
|
-
Type: "AWS::Lambda::Function",
|
|
39
|
-
Properties: {
|
|
40
|
-
FunctionName: settings.functionName,
|
|
41
|
-
Handler: "lambda.handler",
|
|
42
|
-
Role: { "Fn::GetAtt": [ "LambdaRole", "Arn" ] },
|
|
43
|
-
Code: {
|
|
44
|
-
S3Bucket: settings.deploymentBucketName,
|
|
45
|
-
S3Key: settings.zipFileName
|
|
46
|
-
},
|
|
47
|
-
Runtime: "nodejs12.x",
|
|
48
|
-
Timeout: 300,
|
|
49
|
-
Environment: {
|
|
50
|
-
Variables: {}
|
|
51
|
-
},
|
|
52
|
-
Tags: [
|
|
53
|
-
{
|
|
54
|
-
Key : "Kumologica-ts",
|
|
55
|
-
Value : `${ts.toISOString()}`
|
|
56
|
-
}
|
|
57
|
-
]
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
template.Resources['Lambda'] = lambda;
|
|
61
|
-
|
|
62
|
-
let lambdaRole = {
|
|
63
|
-
Type: 'AWS::IAM::Role',
|
|
64
|
-
Properties: {
|
|
65
|
-
RoleName: settings.roleName,
|
|
66
|
-
AssumeRolePolicyDocument: {
|
|
67
|
-
Version: '2012-10-17',
|
|
68
|
-
Statement: [
|
|
69
|
-
{
|
|
70
|
-
Effect: 'Allow',
|
|
71
|
-
Principal: {
|
|
72
|
-
Service: ['lambda.amazonaws.com']
|
|
73
|
-
},
|
|
74
|
-
Action: ['sts:AssumeRole']
|
|
75
|
-
}
|
|
76
|
-
]
|
|
77
|
-
},
|
|
78
|
-
Path: '/',
|
|
79
|
-
Policies: [
|
|
80
|
-
{
|
|
81
|
-
PolicyName: 'AWSLambdaBasicExecutionPolicy',
|
|
82
|
-
PolicyDocument: {
|
|
83
|
-
Version: '2012-10-17',
|
|
84
|
-
Statement: [
|
|
85
|
-
{
|
|
86
|
-
Effect: 'Allow',
|
|
87
|
-
Action: [
|
|
88
|
-
'logs:CreateLogGroup',
|
|
89
|
-
'logs:CreateLogStream',
|
|
90
|
-
'logs:PutLogEvents'
|
|
91
|
-
],
|
|
92
|
-
Resource: '*'
|
|
93
|
-
}
|
|
94
|
-
]
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
]
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const xRayPolicy = {
|
|
102
|
-
PolicyName: 'AWSLambdaXRayPolicy',
|
|
103
|
-
PolicyDocument: {
|
|
104
|
-
Version: '2012-10-17',
|
|
105
|
-
Statement: [
|
|
106
|
-
{
|
|
107
|
-
Effect: 'Allow',
|
|
108
|
-
Action: [
|
|
109
|
-
'xray:PutTraceSegments',
|
|
110
|
-
'xray:PutTelemetryRecords'
|
|
111
|
-
],
|
|
112
|
-
Resource: '*'
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
if (params.description) {
|
|
119
|
-
lambda.Properties.Description = params.description;
|
|
120
|
-
}
|
|
121
|
-
if (params.memory) {
|
|
122
|
-
lambda.Properties.MemorySize = params.memory;
|
|
123
|
-
}
|
|
124
|
-
if (params.timeout) {
|
|
125
|
-
lambda.Properties.Timeout = params.timeout;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (params.reservedConcurrency) {
|
|
129
|
-
lambda.Properties.ReservedConcurrentExecutions = params.reservedConcurrency;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (params.xRay) {
|
|
133
|
-
lambdaRole.Properties.Policies.push(xRayPolicy);
|
|
134
|
-
lambda.Properties.TracingConfig = {'Mode': 'Active'};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (params.role) {
|
|
138
|
-
lambda.Properties.Role = params.role;
|
|
139
|
-
}
|
|
140
|
-
if (params.environment) {
|
|
141
|
-
params.environment.forEach(function(env, index) {
|
|
142
|
-
lambda.Properties.Environment.Variables[env.key] = env.value;
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (params.tags) {
|
|
147
|
-
params.tags.forEach(function(tag, index) {
|
|
148
|
-
lambda.Properties.Tags.push({'Key': tag.key, 'Value': tag.value});
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// adding inbound services permissions, only for dynamodb stream, sqs and kinesis
|
|
153
|
-
if (params.events) {
|
|
154
|
-
for (var i = 0; i < params.events.length; i++) {
|
|
155
|
-
if (['dynamodb', 'sqs', 'kinesis'].includes(params.events[i].source)) {
|
|
156
|
-
var mappingName = `${params.events[i].source}Mapping${i}`;
|
|
157
|
-
|
|
158
|
-
template.Resources[mappingName] = this.eventSourceMapping(params.events[i], settings);
|
|
159
|
-
|
|
160
|
-
if (params.events[i].source === 'dynamodb') {
|
|
161
|
-
lambdaRole.Properties.Policies.push(
|
|
162
|
-
this.dynamoDbStreamPolicy(params.events[i])
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
if (params.events[i].source === 'sqs') {
|
|
166
|
-
lambdaRole.Properties.Policies.push(
|
|
167
|
-
this.sqsPolicy(params.events[i])
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
if (params.events[i].source === 'kinesis') {
|
|
171
|
-
lambdaRole.Properties.Policies.push(
|
|
172
|
-
this.kinesisPolicy(params.events[i])
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// adding all outbound services operations to iam role
|
|
180
|
-
if (nodes) {
|
|
181
|
-
for (var i=0; i<nodes.length; i++) {
|
|
182
|
-
// exluding lambda for time being
|
|
183
|
-
if (this.validNodeType(nodes[i])) {
|
|
184
|
-
// if (nodes[i] && nodes[i].type && ['Rekognition', 'S3', 'SQS', 'Cloudwatch', 'Dynamo DB', 'SNS', 'SES', 'SSM'].includes(nodes[i].type)) {
|
|
185
|
-
|
|
186
|
-
if (nodes[i].type === 'Dynamo DB') {
|
|
187
|
-
//arn:aws:dynamodb:ap-southeast-2:174842903734:table/contact_us
|
|
188
|
-
let tableArn = this.handleValue(lambda, nodes[i].tableArn);
|
|
189
|
-
let tableParts = tableArn.split(":");
|
|
190
|
-
let tableName = '*';
|
|
191
|
-
if (tableParts && tableParts[5]) {
|
|
192
|
-
tableName = tableParts[5].replace('table/', '');
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
this.handlePolicy(lambdaRole, `KLDDB${tableName}`, `dynamodb:${nodes[i].operation}`, tableArn);
|
|
196
|
-
|
|
197
|
-
} else if (nodes[i].type === 'Lambda') {
|
|
198
|
-
//arn:aws:lambda:ap-southeast-2:174450237637:function:kumologica-deployments-flow-lambda
|
|
199
|
-
let lambdaArn = this.handleValue(lambda, nodes[i].LambdaArn);
|
|
200
|
-
let lambdaParts = lambdaArn.split(":");
|
|
201
|
-
let lambdaName = '*';
|
|
202
|
-
|
|
203
|
-
if (lambdaParts && lambdaParts[6]) {
|
|
204
|
-
lambdaName = lambdaParts[6];
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
this.handlePolicy(lambdaRole, `KLLBD${lambdaName}`, `lambda:InvokeFunction`, lambdaArn);
|
|
208
|
-
|
|
209
|
-
} else if (nodes[i].type === 'SQS') {
|
|
210
|
-
let queueArn = this.handleValue(lambda, nodes[i].QueueArn);
|
|
211
|
-
let queueName = queueArn.split(":")[5];
|
|
212
|
-
this.handlePolicy(lambdaRole, `KLSQS${queueName}`, `sqs:${nodes[i].operation}`, queueArn);
|
|
213
|
-
|
|
214
|
-
} else if (nodes[i].type === 'SNS') {
|
|
215
|
-
const topic = this.handleValue(lambda, nodes[i].publishTopic);
|
|
216
|
-
this.handlePolicy(lambdaRole, `KLSNS${topic}`, `sns:${nodes[i].operation}`, topic);
|
|
217
|
-
|
|
218
|
-
} else if (nodes[i].type === 'SES') {
|
|
219
|
-
this.handlePolicy(lambdaRole, `KLSES`, `ses:${nodes[i].operation}`, '*');
|
|
220
|
-
|
|
221
|
-
} else if (nodes[i].type === 'SSM') {
|
|
222
|
-
let key;
|
|
223
|
-
if (nodes[i].operation === "GetParametersByPath") {
|
|
224
|
-
key = this.handleValue(lambda, nodes[i].Path);
|
|
225
|
-
} else {
|
|
226
|
-
key = this.handleValue(lambda, nodes[i].Key);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (key.startsWith('/')) {
|
|
230
|
-
key = key.substring(1);
|
|
231
|
-
}
|
|
232
|
-
const ssmArn = {'Fn::Sub': 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/' + key};
|
|
233
|
-
this.handlePolicy(lambdaRole, `KLSSM${new Date().valueOf()}`, `ssm:${nodes[i].operation}`, ssmArn);
|
|
234
|
-
|
|
235
|
-
if (nodes[i].operation === "GetParameter" && nodes[i].Key.startsWith("/aws/reference/secretsmanager/")) {
|
|
236
|
-
const smArn = {'Fn::Sub': 'arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:*'};
|
|
237
|
-
this.handlePolicy(lambdaRole, `KLSM${new Date().valueOf()}`, "secretsmanager:GetSecretValue", smArn);
|
|
238
|
-
}
|
|
239
|
-
} else if (nodes[i].type === 'S3') {
|
|
240
|
-
let bucketName = this.handleValue(lambda, nodes[i].Bucket);
|
|
241
|
-
const bucketArn = `arn:aws:s3:::${bucketName}/*`;
|
|
242
|
-
this.handlePolicy(lambdaRole, `KLS3${bucketName}`, `s3:${nodes[i].operation}`, bucketArn);
|
|
243
|
-
|
|
244
|
-
} else if (nodes[i].type === 'Cloudwatch') {
|
|
245
|
-
let source = this.handleValue(lambda, nodes[i].Source);
|
|
246
|
-
this.handlePolicy(lambdaRole, `KLCWE${source}`, `event:${nodes[i].operation}`, source);
|
|
247
|
-
|
|
248
|
-
} else if (nodes[i].type === 'Rekognition') {
|
|
249
|
-
const resource = this.rekognition.mapResource(nodes[i].operation, region, '*', nodes[i]);
|
|
250
|
-
this.handlePolicy(lambdaRole, `KLR${nodes[i].operation}`, `rekognition:${nodes[i].operation}`, resource);
|
|
251
|
-
|
|
252
|
-
if (['DetectModerationLabels',
|
|
253
|
-
'DetectText',
|
|
254
|
-
'DetectLabels',
|
|
255
|
-
'DetectFaces',
|
|
256
|
-
'IndexFaces',
|
|
257
|
-
'RecognizeCelebrities',
|
|
258
|
-
'SearchFacesByImage',
|
|
259
|
-
'StartStreamProcessor',
|
|
260
|
-
'StopStreamProcessor'].includes(nodes[i].operation)) {
|
|
261
|
-
|
|
262
|
-
const bucketName = nodes[i].Image;
|
|
263
|
-
const bucketArn = `arn:aws:s3:::${bucketName}/*`;
|
|
264
|
-
this.handlePolicy(lambdaRole, `KLS3${bucketName}`, `s3:Get*`, bucketArn);
|
|
265
|
-
this.handlePolicy(lambdaRole, `KLS3${bucketName}`, `s3:List*`, bucketArn);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (!params.role) {
|
|
273
|
-
template.Resources['LambdaRole'] = lambdaRole;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return template;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
validNodeType(node) {
|
|
280
|
-
return node
|
|
281
|
-
&& node.type
|
|
282
|
-
&& ['Rekognition', 'S3', 'SQS', 'Cloudwatch', 'Dynamo DB', 'SNS', 'SES', 'SSM', 'Lambda'].includes(node.type);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
//
|
|
286
|
-
// Function allows the storage of aws resource identifier (arn or other)
|
|
287
|
-
// in either:
|
|
288
|
-
// - string property - value returned as is (key input)
|
|
289
|
-
// - env property - key input is a key to reference environment variable.
|
|
290
|
-
// if env variables got key missing then error is returned
|
|
291
|
-
// if var or msg used then error is returned, in these cases its impossible
|
|
292
|
-
// to determine the value
|
|
293
|
-
handleValue(lambda, key) {
|
|
294
|
-
let value;
|
|
295
|
-
|
|
296
|
-
if (!key) {
|
|
297
|
-
return key;
|
|
298
|
-
}
|
|
299
|
-
let keyValue = key.replace(/\s+/g, '');
|
|
300
|
-
|
|
301
|
-
if (keyValue.startsWith("env.")) {
|
|
302
|
-
keyValue = keyValue.replace("env.", "");
|
|
303
|
-
value = lambda.Properties.Environment.Variables[keyValue];
|
|
304
|
-
if (!value) {
|
|
305
|
-
throw new Error(`Missing Environment variable: ${keyValue}`);
|
|
306
|
-
}
|
|
307
|
-
} else if (key.startsWith("msg.") || key.startsWith("vars.")) {
|
|
308
|
-
throw new Error('Only literal string and Environment variable references env. are supported sources of values. To use other types you must specify explicit role arn in function properties.');
|
|
309
|
-
} else {
|
|
310
|
-
value = key;
|
|
311
|
-
}
|
|
312
|
-
return this.sanitizeValue(value);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Removes strings in quotes, they will cause cloudformation script to be invalid
|
|
316
|
-
sanitizeValue(value) {
|
|
317
|
-
let v = value.trim();
|
|
318
|
-
if (v.charAt(0) === '"' && v.charAt(v.length -1) === '"') {
|
|
319
|
-
return v.substr(1,v.length -2);
|
|
320
|
-
}
|
|
321
|
-
return value;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
//
|
|
325
|
-
// Function handles policy changes for specific resource:
|
|
326
|
-
// - creates new policy for resource if not found
|
|
327
|
-
// - updates existing resource policy (if found) with new permissions
|
|
328
|
-
//
|
|
329
|
-
handlePolicy(lambdaRole, policyName, operation, id) {
|
|
330
|
-
policyName = policyName.replace('/', '-').replace('*', 'all');
|
|
331
|
-
let policy = jp.query(lambdaRole.Properties, `Policies[?(@.PolicyName=='${policyName}')]`);
|
|
332
|
-
|
|
333
|
-
if (policy.length == 1) {
|
|
334
|
-
policy[0].PolicyDocument.Statement[0].Action.push(operation);
|
|
335
|
-
} else {
|
|
336
|
-
lambdaRole.Properties.Policies.push(
|
|
337
|
-
this.outputPolicy(policyName, operation, id));
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
dynamoDbStreamPolicy(event) {
|
|
342
|
-
if (!event.stream) {
|
|
343
|
-
throw new Error(`Missing Trigger Parameter: DynamoDB Stream's ARN`);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
return {
|
|
347
|
-
PolicyName: 'KumologicaLambdaDynamoDbStreamPolicy',
|
|
348
|
-
PolicyDocument: {
|
|
349
|
-
Version: '2012-10-17',
|
|
350
|
-
Statement: [
|
|
351
|
-
{
|
|
352
|
-
Action: [
|
|
353
|
-
'dynamodb:DescribeStream',
|
|
354
|
-
'dynamodb:GetRecords',
|
|
355
|
-
'dynamodb:GetShardIterator'
|
|
356
|
-
],
|
|
357
|
-
Resource: event.stream,
|
|
358
|
-
Effect: 'Allow'
|
|
359
|
-
}
|
|
360
|
-
]
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
outputPolicy(name, action, resource) {
|
|
366
|
-
return {
|
|
367
|
-
PolicyName: name,
|
|
368
|
-
PolicyDocument: {
|
|
369
|
-
Version: '2012-10-17',
|
|
370
|
-
Statement: [
|
|
371
|
-
{
|
|
372
|
-
Action: [action],
|
|
373
|
-
Resource: resource,
|
|
374
|
-
Effect: 'Allow'
|
|
375
|
-
}
|
|
376
|
-
]
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
sqsPolicy(event) {
|
|
382
|
-
if (!event.stream) {
|
|
383
|
-
throw new Error(`Missing Trigger Parameter: SQS url`);
|
|
384
|
-
}
|
|
385
|
-
return {
|
|
386
|
-
PolicyName: 'KLSQSPolicy'+process.hrtime(),
|
|
387
|
-
PolicyDocument: {
|
|
388
|
-
Version: '2012-10-17',
|
|
389
|
-
Statement: [
|
|
390
|
-
{
|
|
391
|
-
Action: [
|
|
392
|
-
'sqs:ReceiveMessage',
|
|
393
|
-
'sqs:DeleteMessage',
|
|
394
|
-
'sqs:GetQueueAttributes'
|
|
395
|
-
],
|
|
396
|
-
Resource: event.stream,
|
|
397
|
-
Effect: 'Allow'
|
|
398
|
-
}
|
|
399
|
-
]
|
|
400
|
-
}
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
kinesisPolicy(event) {
|
|
405
|
-
return {
|
|
406
|
-
PolicyName: 'KumologicaLambdaKinesisPolicy',
|
|
407
|
-
PolicyDocument: {
|
|
408
|
-
Version: '2012-10-17',
|
|
409
|
-
Statement: [
|
|
410
|
-
{
|
|
411
|
-
Action: [
|
|
412
|
-
'kinesis:DescribeStream',
|
|
413
|
-
'kinesis:DescribeStreamSummary',
|
|
414
|
-
'kinesis:GetRecords',
|
|
415
|
-
'kinesis:GetShardIterator',
|
|
416
|
-
'kinesis:ListShards',
|
|
417
|
-
'kinesis:ListStreams',
|
|
418
|
-
'kinesis:SubscribeToShard'
|
|
419
|
-
],
|
|
420
|
-
Resource: event.stream,
|
|
421
|
-
Effect: 'Allow'
|
|
422
|
-
}
|
|
423
|
-
]
|
|
424
|
-
}
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
eventSourceMapping(event, settings) {
|
|
429
|
-
|
|
430
|
-
let mapping = {
|
|
431
|
-
Type: 'AWS::Lambda::EventSourceMapping',
|
|
432
|
-
DependsOn: 'Lambda',
|
|
433
|
-
Properties: {
|
|
434
|
-
EventSourceArn: event.stream,
|
|
435
|
-
FunctionName: { 'Fn::GetAtt': ['Lambda', 'Arn'] },
|
|
436
|
-
BatchSize: event.batchSize,
|
|
437
|
-
MaximumBatchingWindowInSeconds: event.batchWindow,
|
|
438
|
-
Enabled: true
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
if (event.startingPosition) {
|
|
443
|
-
mapping.Properties.StartingPosition = event.startingPosition;
|
|
444
|
-
}
|
|
445
|
-
return mapping;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
module.exports = AWSCFTemplate;
|