Showing
8 changed files
with
76 additions
and
25 deletions
... | @@ -58,10 +58,6 @@ class Context(object): | ... | @@ -58,10 +58,6 @@ class Context(object): |
58 | return self.config.get('region', None) | 58 | return self.config.get('region', None) |
59 | 59 | ||
60 | @property | 60 | @property |
61 | - def cfn_config(self): | ||
62 | - return self.config.get('cloudformation', None) | ||
63 | - | ||
64 | - @property | ||
65 | def lambda_config(self): | 61 | def lambda_config(self): |
66 | return self.config.get('lambda', None) | 62 | return self.config.get('lambda', None) |
67 | 63 | ... | ... |
... | @@ -213,4 +213,4 @@ class SNSEventSource(EventSource): | ... | @@ -213,4 +213,4 @@ class SNSEventSource(EventSource): |
213 | 213 | ||
214 | def status(self, function): | 214 | def status(self, function): |
215 | LOG.debug('status for SNS notification for %s', function.name) | 215 | LOG.debug('status for SNS notification for %s', function.name) |
216 | - return self.exist(function) | 216 | + return self.exists(function) | ... | ... |
... | @@ -20,8 +20,6 @@ LOG = logging.getLogger(__name__) | ... | @@ -20,8 +20,6 @@ LOG = logging.getLogger(__name__) |
20 | 20 | ||
21 | class Policy(object): | 21 | class Policy(object): |
22 | 22 | ||
23 | - Path = '/kappa/' | ||
24 | - | ||
25 | def __init__(self, context, config): | 23 | def __init__(self, context, config): |
26 | self._context = context | 24 | self._context = context |
27 | self._config = config | 25 | self._config = config |
... | @@ -39,7 +37,11 @@ class Policy(object): | ... | @@ -39,7 +37,11 @@ class Policy(object): |
39 | 37 | ||
40 | @property | 38 | @property |
41 | def document(self): | 39 | def document(self): |
42 | - return self._config['document'] | 40 | + return self._config.get('document', None) |
41 | + | ||
42 | + @property | ||
43 | + def path(self): | ||
44 | + return self._config.get('path', '/kappa/') | ||
43 | 45 | ||
44 | @property | 46 | @property |
45 | def arn(self): | 47 | def arn(self): |
... | @@ -49,25 +51,36 @@ class Policy(object): | ... | @@ -49,25 +51,36 @@ class Policy(object): |
49 | self._arn = policy.get('Arn', None) | 51 | self._arn = policy.get('Arn', None) |
50 | return self._arn | 52 | return self._arn |
51 | 53 | ||
52 | - def exists(self): | 54 | + def _find_all_policies(self): |
55 | + # boto3 does not currently do pagination for ListPolicies | ||
56 | + # so we have to do it ourselves | ||
57 | + policies = [] | ||
53 | try: | 58 | try: |
54 | - response = self._iam_svc.list_policies(PathPrefix=self.Path) | 59 | + response = self._iam_svc.list_policies() |
55 | - LOG.debug(response) | 60 | + policies += response['Policies'] |
56 | - for policy in response['Policies']: | 61 | + while response['IsTruncated']: |
57 | - if policy['PolicyName'] == self.name: | 62 | + LOG.debug('getting another page of policies') |
58 | - return policy | 63 | + response = self._iam_svc.list_policies( |
64 | + Marker=response['Marker']) | ||
65 | + policies += response['Policies'] | ||
59 | except Exception: | 66 | except Exception: |
60 | LOG.exception('Error listing policies') | 67 | LOG.exception('Error listing policies') |
68 | + return policies | ||
69 | + | ||
70 | + def exists(self): | ||
71 | + for policy in self._find_all_policies(): | ||
72 | + if policy['PolicyName'] == self.name: | ||
73 | + return policy | ||
61 | return None | 74 | return None |
62 | 75 | ||
63 | def create(self): | 76 | def create(self): |
64 | LOG.debug('creating policy %s', self.name) | 77 | LOG.debug('creating policy %s', self.name) |
65 | policy = self.exists() | 78 | policy = self.exists() |
66 | - if not policy: | 79 | + if not policy and self.document: |
67 | with open(self.document, 'rb') as fp: | 80 | with open(self.document, 'rb') as fp: |
68 | try: | 81 | try: |
69 | response = self._iam_svc.create_policy( | 82 | response = self._iam_svc.create_policy( |
70 | - Path=self.Path, PolicyName=self.name, | 83 | + Path=self.path, PolicyName=self.name, |
71 | PolicyDocument=fp.read(), | 84 | PolicyDocument=fp.read(), |
72 | Description=self.description) | 85 | Description=self.description) |
73 | LOG.debug(response) | 86 | LOG.debug(response) |
... | @@ -76,7 +89,9 @@ class Policy(object): | ... | @@ -76,7 +89,9 @@ class Policy(object): |
76 | 89 | ||
77 | def delete(self): | 90 | def delete(self): |
78 | response = None | 91 | response = None |
79 | - if self.arn: | 92 | + # Only delete the policy if it has a document associated with it. |
93 | + # This indicates that it was a custom policy created by kappa. | ||
94 | + if self.arn and self.document: | ||
80 | LOG.debug('deleting policy %s', self.name) | 95 | LOG.debug('deleting policy %s', self.name) |
81 | response = self._iam_svc.delete_policy(PolicyArn=self.arn) | 96 | response = self._iam_svc.delete_policy(PolicyArn=self.arn) |
82 | LOG.debug(response) | 97 | LOG.debug(response) | ... | ... |
1 | --- | 1 | --- |
2 | +# Change the profile and region to suit your application | ||
2 | profile: personal | 3 | profile: personal |
3 | region: us-east-1 | 4 | region: us-east-1 |
4 | iam: | 5 | iam: |
5 | - role_name: KinesisSampleRole | 6 | + # In this case, we are using an existing managed policy so we just |
6 | - role_policy: AWSLambdaKinesisExecutionRole | 7 | + # need to put the name of that policy here. |
8 | + policy: | ||
9 | + name: AWSLambdaKinesisExecutionRole | ||
10 | + # The name of the IAM role used for executing the Lambda function. | ||
11 | + # The policy listed above will be attached to this role once it is created. | ||
12 | + role: | ||
13 | + name: KinesisSampleRole | ||
7 | lambda: | 14 | lambda: |
8 | name: KinesisSample | 15 | name: KinesisSample |
9 | zipfile_name: KinesisSample.zip | 16 | zipfile_name: KinesisSample.zip |
... | @@ -15,6 +22,8 @@ lambda: | ... | @@ -15,6 +22,8 @@ lambda: |
15 | timeout: 3 | 22 | timeout: 3 |
16 | event_sources: | 23 | event_sources: |
17 | - | 24 | - |
25 | + # You need to change this arn to point to your own kinesis | ||
26 | + # stream that you have created separately. | ||
18 | arn: arn:aws:kinesis:us-east-1:084307701560:stream/lambdastream | 27 | arn: arn:aws:kinesis:us-east-1:084307701560:stream/lambdastream |
19 | starting_position: TRIM_HORIZON | 28 | starting_position: TRIM_HORIZON |
20 | batch_size: 100 | 29 | batch_size: 100 | ... | ... |
1 | --- | 1 | --- |
2 | +# Change profile and region to suit your application | ||
2 | profile: personal | 3 | profile: personal |
3 | region: us-east-1 | 4 | region: us-east-1 |
4 | -cloudformation: | 5 | +iam: |
5 | - template: roles.cf | 6 | + # In this case, we are using an existing managed policy so we just |
6 | - stack_name: TestS3 | 7 | + # need to put the name of that policy here. |
7 | - exec_role: ExecRole | 8 | + policy: |
8 | - invoke_role: InvokeRole | 9 | + name: AWSLambdaExecute |
10 | + # The name of the IAM role used for executing the Lambda function. | ||
11 | + # The policy listed above will be attached to this role once it is created. | ||
12 | + role: | ||
13 | + name: KappaS3SampleRole | ||
9 | lambda: | 14 | lambda: |
10 | name: S3Sample | 15 | name: S3Sample |
11 | zipfile_name: S3Sample.zip | 16 | zipfile_name: S3Sample.zip | ... | ... |
... | @@ -16,7 +16,9 @@ exports.handler = function(event, context) { | ... | @@ -16,7 +16,9 @@ exports.handler = function(event, context) { |
16 | // Read options from the event. | 16 | // Read options from the event. |
17 | console.log("Reading options from event:\n", util.inspect(event, {depth: 5})); | 17 | console.log("Reading options from event:\n", util.inspect(event, {depth: 5})); |
18 | var srcBucket = event.Records[0].s3.bucket.name; | 18 | var srcBucket = event.Records[0].s3.bucket.name; |
19 | - var srcKey = event.Records[0].s3.object.key; | 19 | + // Object key may have spaces or unicode non-ASCII characters. |
20 | + var srcKey = | ||
21 | + decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")); | ||
20 | var dstBucket = srcBucket + "resized"; | 22 | var dstBucket = srcBucket + "resized"; |
21 | var dstKey = "resized-" + srcKey; | 23 | var dstKey = "resized-" + srcKey; |
22 | 24 | ... | ... |
1 | --- | 1 | --- |
2 | +# change profile and region to suit your needs | ||
2 | profile: personal | 3 | profile: personal |
3 | region: us-east-1 | 4 | region: us-east-1 |
4 | resources: resources.json | 5 | resources: resources.json |
... | @@ -24,9 +25,11 @@ lambda: | ... | @@ -24,9 +25,11 @@ lambda: |
24 | statement_id: sns_invoke | 25 | statement_id: sns_invoke |
25 | action: lambda:invokeFunction | 26 | action: lambda:invokeFunction |
26 | principal: sns.amazonaws.com | 27 | principal: sns.amazonaws.com |
28 | + # change this to refer to your own SNS topic | ||
27 | source_arn: arn:aws:sns:us-east-1:084307701560:lambda_topic | 29 | source_arn: arn:aws:sns:us-east-1:084307701560:lambda_topic |
28 | event_sources: | 30 | event_sources: |
29 | - | 31 | - |
32 | + # change this to refer to your own SNS topic | ||
30 | arn: arn:aws:sns:us-east-1:084307701560:lambda_topic | 33 | arn: arn:aws:sns:us-east-1:084307701560:lambda_topic |
31 | test_data: input.json | 34 | test_data: input.json |
32 | 35 | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
samples/sns/input.json
0 → 100644
1 | +{ | ||
2 | + "Records":[ | ||
3 | + { | ||
4 | + "EventSource":"aws:sns", | ||
5 | + "EventVersion": "1.0", | ||
6 | + "EventSubscriptionArn": "arn:aws:sns:us-east-1:123456789012:lambda_topic:0b6941c3-f04d-4d3e-a66d-b1df00e1e381", | ||
7 | + "Sns":{ | ||
8 | + "Type" : "Notification", | ||
9 | + "MessageId" : "e70fa8dd-0d77-5944-8862-e569494b48b5", | ||
10 | + "TopicArn" : "arn:aws:sns:us-east-1:658794617753:lambda-chat", | ||
11 | + "Message" : "{\"name\":\"Mitch Garnaat\",\"message\":\"just testing this out\"}", | ||
12 | + "Timestamp" : "2015-04-24T13:15:40.632Z", | ||
13 | + "Channel" : "foo", | ||
14 | + "SignatureVersion" : "1", | ||
15 | + "Signature" : "n0zU4mvKQT5vy6RbDK3BoiWQrFBirbaIGRQOVXE4Vx1XE0SrsXBo4mPm2eDMgjFboP0RJxRCvkFpN07mbnVOIoT2UWKVD2hU1vLdTlEPE4ppSSx17KzhABsOuA8XwijL3hm4cpVHmCmhNXcKekC+fGCryjf9cxr6ODm45PxxE4WLSak85uLzgWhfbAEgPqD2Q/Fa3NwJIyBkZWEdlpJCeaZb4gCzPauvcynRyzWS+e+76WpXMgInCU2y7lhtajDpHrDlZ13UvHOWAQONFRGJXsxFeP370tnzVKfdfMPNbmr4gb3dk+VP0+PsyrIakqp31cO5umUZwSeVZaXLQLewmg==", | ||
16 | + "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-d6d679a1d18e95c2f9ffcf11f4f9e198.pem", | ||
17 | + "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:658794617753:lambda-chat:f1bde0aa-11eb-4417-a9cf-6a00c6aac0a7" | ||
18 | + } | ||
19 | + } | ||
20 | + ] | ||
21 | +} |
-
Please register or login to post a comment