Mitch Garnaat

Updating samples and fixing some bugs found in the process.

...@@ -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
......
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 +}