Adding samples directory and add-event-source command plus polling after create/updating CF stack.
Showing
7 changed files
with
168 additions
and
1 deletions
... | @@ -64,7 +64,7 @@ def set_debug_logger(logger_names=['kappa'], stream=None): | ... | @@ -64,7 +64,7 @@ def set_debug_logger(logger_names=['kappa'], stream=None): |
64 | @click.argument( | 64 | @click.argument( |
65 | 'command', | 65 | 'command', |
66 | required=True, | 66 | required=True, |
67 | - type=click.Choice(['deploy', 'test', 'tail', 'delete']) | 67 | + type=click.Choice(['deploy', 'test', 'tail', 'add-event-source', 'delete']) |
68 | ) | 68 | ) |
69 | def main(config=None, debug=False, dryrun=False, command=None): | 69 | def main(config=None, debug=False, dryrun=False, command=None): |
70 | if debug: | 70 | if debug: |
... | @@ -79,6 +79,8 @@ def main(config=None, debug=False, dryrun=False, command=None): | ... | @@ -79,6 +79,8 @@ def main(config=None, debug=False, dryrun=False, command=None): |
79 | kappa.tail() | 79 | kappa.tail() |
80 | elif command == 'delete': | 80 | elif command == 'delete': |
81 | kappa.delete() | 81 | kappa.delete() |
82 | + elif command == 'add-event-source': | ||
83 | + kappa.add_event_source() | ||
82 | 84 | ||
83 | 85 | ||
84 | if __name__ == '__main__': | 86 | if __name__ == '__main__': | ... | ... |
... | @@ -14,6 +14,7 @@ | ... | @@ -14,6 +14,7 @@ |
14 | import logging | 14 | import logging |
15 | import os | 15 | import os |
16 | import zipfile | 16 | import zipfile |
17 | +import time | ||
17 | 18 | ||
18 | import botocore.session | 19 | import botocore.session |
19 | from botocore.exceptions import ClientError | 20 | from botocore.exceptions import ClientError |
... | @@ -23,6 +24,8 @@ LOG = logging.getLogger(__name__) | ... | @@ -23,6 +24,8 @@ LOG = logging.getLogger(__name__) |
23 | 24 | ||
24 | class Kappa(object): | 25 | class Kappa(object): |
25 | 26 | ||
27 | + completed_states = ('CREATE_COMPLETE', 'UPDATE_COMPLETE') | ||
28 | + | ||
26 | def __init__(self, config): | 29 | def __init__(self, config): |
27 | self.config = config | 30 | self.config = config |
28 | self.session = botocore.session.get_session() | 31 | self.session = botocore.session.get_session() |
... | @@ -52,6 +55,14 @@ class Kappa(object): | ... | @@ -52,6 +55,14 @@ class Kappa(object): |
52 | response = cfn.create_stack( | 55 | response = cfn.create_stack( |
53 | StackName=stack_name, TemplateBody=template_body, | 56 | StackName=stack_name, TemplateBody=template_body, |
54 | Capabilities=['CAPABILITY_IAM']) | 57 | Capabilities=['CAPABILITY_IAM']) |
58 | + done = False | ||
59 | + while not done: | ||
60 | + response = cfn.describe_stacks(StackName=stack_name) | ||
61 | + status = response['Stacks'][0]['StackStatus'] | ||
62 | + LOG.debug('Stack status is: %s', status) | ||
63 | + if status in self.completed_states: | ||
64 | + done = True | ||
65 | + time.sleep(1) | ||
55 | 66 | ||
56 | def get_role_arn(self, role_name): | 67 | def get_role_arn(self, role_name): |
57 | role_arn = None | 68 | role_arn = None |
... | @@ -157,6 +168,20 @@ class Kappa(object): | ... | @@ -157,6 +168,20 @@ class Kappa(object): |
157 | for log_event in response['events']: | 168 | for log_event in response['events']: |
158 | print('%s: %s' % (log_event['timestamp'], log_event['message'])) | 169 | print('%s: %s' % (log_event['timestamp'], log_event['message'])) |
159 | 170 | ||
171 | + def add_event_source(self): | ||
172 | + lambda_svc = self.session.create_client('lambda', self.region) | ||
173 | + try: | ||
174 | + invoke_role = self.get_role_arn( | ||
175 | + self.config['cloudformation']['invoke_role']) | ||
176 | + response = lambda_svc.add_event_source( | ||
177 | + FunctionName=self.config['lambda']['name'], | ||
178 | + Role=invoke_role, | ||
179 | + EventSource=self.config['lambda']['event_source'], | ||
180 | + BatchSize=self.config['lambda'].get('batch_size', 100)) | ||
181 | + LOG.debug(response) | ||
182 | + except Exception: | ||
183 | + LOG.exception('Unable to add event source') | ||
184 | + | ||
160 | def deploy(self): | 185 | def deploy(self): |
161 | self.create_update_roles( | 186 | self.create_update_roles( |
162 | self.config['cloudformation']['stack_name'], | 187 | self.config['cloudformation']['stack_name'], | ... | ... |
samples/kinesis/ProcessKinesisRecords.js
0 → 100644
1 | +console.log('Loading event'); | ||
2 | +exports.handler = function(event, context) { | ||
3 | + console.log(JSON.stringify(event, null, ' ')); | ||
4 | + for(i = 0; i < event.Records.length; ++i) { | ||
5 | + encodedPayload = event.Records[i].kinesis.data; | ||
6 | + payload = new Buffer(encodedPayload, 'base64').toString('ascii'); | ||
7 | + console.log("Decoded payload: " + payload); | ||
8 | + } | ||
9 | + context.done(null, "Hello World"); // SUCCESS with message | ||
10 | +}; |
samples/kinesis/config.yml
0 → 100644
1 | +--- | ||
2 | +profile: personal | ||
3 | +region: us-east-1 | ||
4 | +cloudformation: | ||
5 | + template: roles.cf | ||
6 | + stack_name: TestKinesis | ||
7 | + exec_role: ExecRole | ||
8 | + invoke_role: InvokeRole | ||
9 | +lambda: | ||
10 | + name: KinesisSample | ||
11 | + zipfile_name: KinesisSample.zip | ||
12 | + description: Testing Kinesis Lambda handler | ||
13 | + path: ProcessKinesisRecords.js | ||
14 | + handler: ProcessKinesisRecords.handler | ||
15 | + runtime: nodejs | ||
16 | + memory_size: 128 | ||
17 | + timeout: 3 | ||
18 | + mode: event | ||
19 | + event_source: arn:aws:kinesis:us-east-1:084307701560:stream/lambdastream | ||
20 | + test_data: input.json | ||
21 | + | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
samples/kinesis/input.json
0 → 100644
1 | +{ | ||
2 | + "Records": [ | ||
3 | + { | ||
4 | + "kinesis": { | ||
5 | + "partitionKey": "partitionKey-3", | ||
6 | + "kinesisSchemaVersion": "1.0", | ||
7 | + "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=", | ||
8 | + "sequenceNumber": "49545115243490985018280067714973144582180062593244200961" | ||
9 | + }, | ||
10 | + "eventSource": "aws:kinesis", | ||
11 | + "eventID": "shardId-000000000000:49545115243490985018280067714973144582180062593244200961", | ||
12 | + "invokeIdentityArn": "arn:aws:iam::059493405231:role/testLEBRole", | ||
13 | + "eventVersion": "1.0", | ||
14 | + "eventName": "aws:kinesis:record", | ||
15 | + "eventSourceARN": "arn:aws:kinesis:us-east-1:35667example:stream/examplestream", | ||
16 | + "awsRegion": "us-east-1" | ||
17 | + } | ||
18 | + ] | ||
19 | +} |
samples/kinesis/roles.cf
0 → 100644
1 | +{ | ||
2 | + "AWSTemplateFormatVersion": "2010-09-09", | ||
3 | + "Resources": { | ||
4 | + "ExecRole": { | ||
5 | + "Type": "AWS::IAM::Role", | ||
6 | + "Properties": { | ||
7 | + "AssumeRolePolicyDocument": { | ||
8 | + "Version" : "2012-10-17", | ||
9 | + "Statement": [ { | ||
10 | + "Effect": "Allow", | ||
11 | + "Principal": { | ||
12 | + "Service": [ "lambda.amazonaws.com" ] | ||
13 | + }, | ||
14 | + "Action": [ "sts:AssumeRole" ] | ||
15 | + } ] | ||
16 | + } | ||
17 | + } | ||
18 | + }, | ||
19 | + "ExecRolePolicies": { | ||
20 | + "Type": "AWS::IAM::Policy", | ||
21 | + "Properties": { | ||
22 | + "PolicyName": "ExecRolePolicy", | ||
23 | + "PolicyDocument": { | ||
24 | + "Version" : "2012-10-17", | ||
25 | + "Statement": [ { | ||
26 | + "Effect": "Allow", | ||
27 | + "Action": [ | ||
28 | + "logs:*" | ||
29 | + ], | ||
30 | + "Resource": "arn:aws:logs:*:*:*" | ||
31 | + } ] | ||
32 | + }, | ||
33 | + "Roles": [ { "Ref": "ExecRole" } ] | ||
34 | + } | ||
35 | + }, | ||
36 | + "InvokeRole": { | ||
37 | + "Type": "AWS::IAM::Role", | ||
38 | + "Properties": { | ||
39 | + "AssumeRolePolicyDocument": { | ||
40 | + "Version" : "2012-10-17", | ||
41 | + "Statement": [ { | ||
42 | + "Effect": "Allow", | ||
43 | + "Principal": { | ||
44 | + "Service": [ "s3.amazonaws.com" ] | ||
45 | + }, | ||
46 | + "Action": [ "sts:AssumeRole" ], | ||
47 | + "Condition": { | ||
48 | + "ArnLike": { | ||
49 | + "sts:ExternalId": "arn:aws:s3:::*" | ||
50 | + } | ||
51 | + } | ||
52 | + }, | ||
53 | + { | ||
54 | + "Effect": "Allow", | ||
55 | + "Principal": { | ||
56 | + "Service": "lambda.amazonaws.com" | ||
57 | + }, | ||
58 | + "Action": "sts:AssumeRole" | ||
59 | + } ] | ||
60 | + } | ||
61 | + } | ||
62 | + }, | ||
63 | + "InvokeRolePolicies": { | ||
64 | + "Type": "AWS::IAM::Policy", | ||
65 | + "Properties": { | ||
66 | + "PolicyName": "ExecRolePolicy", | ||
67 | + "PolicyDocument": { | ||
68 | + "Version" : "2012-10-17", | ||
69 | + "Statement": [ | ||
70 | + { | ||
71 | + "Effect":"Allow", | ||
72 | + "Action":[ | ||
73 | + "lambda:InvokeFunction", | ||
74 | + "kinesis:GetRecords", | ||
75 | + "kinesis:GetShardIterator", | ||
76 | + "kinesis:DescribeStream", | ||
77 | + "kinesis:ListStreams" | ||
78 | + ], | ||
79 | + "Resource":[ | ||
80 | + "*" | ||
81 | + ] | ||
82 | + } | ||
83 | + ] | ||
84 | + }, | ||
85 | + "Roles": [ { "Ref": "InvokeRole" } ] | ||
86 | + } | ||
87 | + } | ||
88 | + } | ||
89 | +} |
-
Please register or login to post a comment