Mitch Garnaat

A bunch of changes to support new unit testing strategy with placebo. More tests to come.

Showing 42 changed files with 1067 additions and 333 deletions
...@@ -3,6 +3,7 @@ python: ...@@ -3,6 +3,7 @@ python:
3 - "2.7" 3 - "2.7"
4 - "3.3" 4 - "3.3"
5 - "3.4" 5 - "3.4"
6 + - "3.5"
6 install: 7 install:
7 - pip install -r requirements.txt 8 - pip install -r requirements.txt
8 - pip install coverage python-coveralls 9 - pip install coverage python-coveralls
......
...@@ -16,18 +16,18 @@ import logging ...@@ -16,18 +16,18 @@ import logging
16 16
17 import jmespath 17 import jmespath
18 import boto3 18 import boto3
19 -import placebo
20 19
21 20
22 LOG = logging.getLogger(__name__) 21 LOG = logging.getLogger(__name__)
23 22
23 +_session_cache = {}
24 +
24 25
25 class AWSClient(object): 26 class AWSClient(object):
26 27
27 - def __init__(self, service_name, region_name, profile_name): 28 + def __init__(self, service_name, session):
28 self._service_name = service_name 29 self._service_name = service_name
29 - self._region_name = region_name 30 + self._session = session
30 - self._profile_name = profile_name
31 self.client = self._create_client() 31 self.client = self._create_client()
32 32
33 @property 33 @property
...@@ -35,20 +35,11 @@ class AWSClient(object): ...@@ -35,20 +35,11 @@ class AWSClient(object):
35 return self._service_name 35 return self._service_name
36 36
37 @property 37 @property
38 - def region_name(self): 38 + def session(self):
39 - return self._region_name 39 + return self._session
40 -
41 - @property
42 - def profile_name(self):
43 - return self._profile_name
44 40
45 def _create_client(self): 41 def _create_client(self):
46 - global recording_path 42 + client = self._session.client(self._service_name)
47 - session = boto3.session.Session(
48 - region_name=self._region_name, profile_name=self._profile_name)
49 - if recording_path:
50 - placebo.attach(session)
51 - client = session.client(self._service_name)
52 return client 43 return client
53 44
54 def call(self, op_name, query=None, **kwargs): 45 def call(self, op_name, query=None, **kwargs):
...@@ -93,17 +84,15 @@ class AWSClient(object): ...@@ -93,17 +84,15 @@ class AWSClient(object):
93 return data 84 return data
94 85
95 86
96 -_client_cache = {} 87 +def create_session(profile_name, region_name):
97 - 88 + global _session_cache
98 -recording_path = None 89 + session_key = '{}:{}'.format(profile_name, region_name)
90 + if session_key not in _session_cache:
91 + session = boto3.session.Session(
92 + region_name=region_name, profile_name=profile_name)
93 + _session_cache[session_key] = session
94 + return _session_cache[session_key]
99 95
100 96
101 -def create_client(service_name, context): 97 +def create_client(service_name, session):
102 - global _client_cache 98 + return AWSClient(service_name, session)
103 - client_key = '{}:{}:{}'.format(service_name, context.region,
104 - context.profile)
105 - if client_key not in _client_cache:
106 - client = AWSClient(service_name, context.region,
107 - context.profile)
108 - _client_cache[client_key] = client
109 - return _client_cache[client_key]
......
...@@ -24,6 +24,8 @@ import kappa.policy ...@@ -24,6 +24,8 @@ import kappa.policy
24 import kappa.role 24 import kappa.role
25 import kappa.awsclient 25 import kappa.awsclient
26 26
27 +import placebo
28 +
27 LOG = logging.getLogger(__name__) 29 LOG = logging.getLogger(__name__)
28 30
29 DebugFmtString = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' 31 DebugFmtString = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
...@@ -38,10 +40,15 @@ class Context(object): ...@@ -38,10 +40,15 @@ class Context(object):
38 self.set_logger('kappa', logging.DEBUG) 40 self.set_logger('kappa', logging.DEBUG)
39 else: 41 else:
40 self.set_logger('kappa', logging.INFO) 42 self.set_logger('kappa', logging.INFO)
41 - kappa.awsclient.recording_path = recording_path
42 self._load_cache() 43 self._load_cache()
43 self.config = yaml.load(config_file) 44 self.config = yaml.load(config_file)
44 self.environment = environment 45 self.environment = environment
46 + profile = self.config['environments'][self.environment]['profile']
47 + region = self.config['environments'][self.environment]['region']
48 + self.session = kappa.awsclient.create_session(profile, region)
49 + if recording_path:
50 + self.pill = placebo.attach(self.session, recording_path)
51 + self.pill.record()
45 self.policy = kappa.policy.Policy( 52 self.policy = kappa.policy.Policy(
46 self, self.config['environments'][self.environment]) 53 self, self.config['environments'][self.environment])
47 self.role = kappa.role.Role( 54 self.role = kappa.role.Role(
......
...@@ -48,7 +48,8 @@ class KinesisEventSource(EventSource): ...@@ -48,7 +48,8 @@ class KinesisEventSource(EventSource):
48 48
49 def __init__(self, context, config): 49 def __init__(self, context, config):
50 super(KinesisEventSource, self).__init__(context, config) 50 super(KinesisEventSource, self).__init__(context, config)
51 - self._lambda = kappa.awsclient.create_client('kinesis', context) 51 + self._lambda = kappa.awsclient.create_client(
52 + 'kinesis', context.session)
52 53
53 def _get_uuid(self, function): 54 def _get_uuid(self, function):
54 uuid = None 55 uuid = None
...@@ -150,7 +151,7 @@ class S3EventSource(EventSource): ...@@ -150,7 +151,7 @@ class S3EventSource(EventSource):
150 151
151 def __init__(self, context, config): 152 def __init__(self, context, config):
152 super(S3EventSource, self).__init__(context, config) 153 super(S3EventSource, self).__init__(context, config)
153 - self._s3 = kappa.awsclient.create_client('s3', config) 154 + self._s3 = kappa.awsclient.create_client('s3', context.session)
154 155
155 def _make_notification_id(self, function_name): 156 def _make_notification_id(self, function_name):
156 return 'Kappa-%s-notification' % function_name 157 return 'Kappa-%s-notification' % function_name
...@@ -213,7 +214,7 @@ class SNSEventSource(EventSource): ...@@ -213,7 +214,7 @@ class SNSEventSource(EventSource):
213 214
214 def __init__(self, context, config): 215 def __init__(self, context, config):
215 super(SNSEventSource, self).__init__(context, config) 216 super(SNSEventSource, self).__init__(context, config)
216 - self._sns = kappa.awsclient.create_client('sns', context) 217 + self._sns = kappa.awsclient.create_client('sns', context.session)
217 218
218 def _make_notification_id(self, function_name): 219 def _make_notification_id(self, function_name):
219 return 'Kappa-%s-notification' % function_name 220 return 'Kappa-%s-notification' % function_name
......
...@@ -33,7 +33,7 @@ class Function(object): ...@@ -33,7 +33,7 @@ class Function(object):
33 self._context = context 33 self._context = context
34 self._config = config 34 self._config = config
35 self._lambda_client = kappa.awsclient.create_client( 35 self._lambda_client = kappa.awsclient.create_client(
36 - 'lambda', context) 36 + 'lambda', context.session)
37 self._response = None 37 self._response = None
38 self._log = None 38 self._log = None
39 39
......
...@@ -26,7 +26,8 @@ class Log(object): ...@@ -26,7 +26,8 @@ class Log(object):
26 def __init__(self, context, log_group_name): 26 def __init__(self, context, log_group_name):
27 self._context = context 27 self._context = context
28 self.log_group_name = log_group_name 28 self.log_group_name = log_group_name
29 - self._log_client = kappa.awsclient.create_client('logs', context) 29 + self._log_client = kappa.awsclient.create_client(
30 + 'logs', context.session)
30 31
31 def _check_for_log_group(self): 32 def _check_for_log_group(self):
32 LOG.debug('checking for log group') 33 LOG.debug('checking for log group')
......
...@@ -26,7 +26,8 @@ class Policy(object): ...@@ -26,7 +26,8 @@ class Policy(object):
26 def __init__(self, context, config): 26 def __init__(self, context, config):
27 self._context = context 27 self._context = context
28 self._config = config 28 self._config = config
29 - self._iam_client = kappa.awsclient.create_client('iam', self._context) 29 + self._iam_client = kappa.awsclient.create_client(
30 + 'iam', self._context.session)
30 self._arn = self._config['policy'].get('arn', None) 31 self._arn = self._config['policy'].get('arn', None)
31 32
32 @property 33 @property
...@@ -75,10 +76,11 @@ class Policy(object): ...@@ -75,10 +76,11 @@ class Policy(object):
75 def _find_all_policies(self): 76 def _find_all_policies(self):
76 try: 77 try:
77 response = self._iam_client.call( 78 response = self._iam_client.call(
78 - 'list_policies') 79 + 'list_policies', PathPrefix=self.path)
79 except Exception: 80 except Exception:
80 LOG.exception('Error listing policies') 81 LOG.exception('Error listing policies')
81 - return response['Policies'] 82 + response = {}
83 + return response.get('Policies', list())
82 84
83 def _list_versions(self): 85 def _list_versions(self):
84 try: 86 try:
......
...@@ -40,7 +40,8 @@ class Role(object): ...@@ -40,7 +40,8 @@ class Role(object):
40 def __init__(self, context, config): 40 def __init__(self, context, config):
41 self._context = context 41 self._context = context
42 self._config = config 42 self._config = config
43 - self._iam_client = kappa.awsclient.create_client('iam', context) 43 + self._iam_client = kappa.awsclient.create_client(
44 + 'iam', context.session)
44 self._arn = None 45 self._arn = None
45 46
46 @property 47 @property
...@@ -64,7 +65,8 @@ class Role(object): ...@@ -64,7 +65,8 @@ class Role(object):
64 response = self._iam_client.call('list_roles') 65 response = self._iam_client.call('list_roles')
65 except Exception: 66 except Exception:
66 LOG.exception('Error listing roles') 67 LOG.exception('Error listing roles')
67 - return response['Roles'] 68 + response = {}
69 + return response.get('Roles', list())
68 70
69 def exists(self): 71 def exists(self):
70 for role in self._find_all_roles(): 72 for role in self._find_all_roles():
......
1 boto3>=1.2.2 1 boto3>=1.2.2
2 -placebo>=0.3.0 2 +placebo>=0.4.1
3 click==5.1 3 click==5.1
4 PyYAML>=3.11 4 PyYAML>=3.11
5 mock>=1.0.1 5 mock>=1.0.1
......
1 +.kappa/
2 +kappa.yml
...@@ -6,7 +6,7 @@ import os ...@@ -6,7 +6,7 @@ import os
6 6
7 requires = [ 7 requires = [
8 'boto3>=1.2.2', 8 'boto3>=1.2.2',
9 - 'placebo>=0.3.0', 9 + 'placebo>=0.4.1',
10 'click>=5.0', 10 'click>=5.0',
11 'PyYAML>=3.11' 11 'PyYAML>=3.11'
12 ] 12 ]
...@@ -36,10 +36,10 @@ setup( ...@@ -36,10 +36,10 @@ setup(
36 'Natural Language :: English', 36 'Natural Language :: English',
37 'License :: OSI Approved :: Apache Software License', 37 'License :: OSI Approved :: Apache Software License',
38 'Programming Language :: Python', 38 'Programming Language :: Python',
39 - 'Programming Language :: Python :: 2.6',
40 'Programming Language :: Python :: 2.7', 39 'Programming Language :: Python :: 2.7',
41 'Programming Language :: Python :: 3', 40 'Programming Language :: Python :: 3',
42 'Programming Language :: Python :: 3.3', 41 'Programming Language :: Python :: 3.3',
43 - 'Programming Language :: Python :: 3.4' 42 + 'Programming Language :: Python :: 3.4',
43 + 'Programming Language :: Python :: 3.5'
44 ), 44 ),
45 ) 45 )
......
1 +[foobar]
2 +aws_access_key_id = foo
3 +aws_secret_access_key = bar
1 -{
2 - "Statement":[
3 - {"Condition":
4 - {"ArnLike":{"AWS:SourceArn":"arn:aws:sns:us-east-1:123456789012:lambda_topic"}},
5 - "Resource":"arn:aws:lambda:us-east-1:123456789023:function:messageStore",
6 - "Action":"lambda:invokeFunction",
7 - "Principal":{"Service":"sns.amazonaws.com"},
8 - "Sid":"sns invoke","Effect":"Allow"
9 - }],
10 - "Id":"default",
11 - "Version":"2012-10-17"
12 -}
1 +dev: {config_md5: 3ccd0a5630fa4e0d0effeb9de0b551a3, policy_md5: 12273b7917929c02cfc755f4700e1e2b,
2 + zip_md5: b6605fd4990542106fa95b62ea62d70e}
1 +
2 +
3 +def handler(event, context):
4 + return {'status': 'success'}
No preview for this file type
1 +---
2 +name: kappa-simple
3 +environments:
4 + dev:
5 + profile: foobar
6 + region: us-west-2
7 + policy:
8 + resources:
9 + - arn: arn:aws:logs:*:*:*
10 + actions:
11 + - "*"
12 +lambda:
13 + description: Foo the Bar
14 + handler: simple.handler
15 + runtime: python2.7
16 + memory_size: 256
17 + timeout: 3
1 -import inspect
2 -
3 -import mock
4 -
5 -import tests.unit.responses as responses
6 -
7 -
8 -class MockAWS(object):
9 -
10 - def __init__(self, profile=None, region=None):
11 - self.response_map = {}
12 - for name, value in inspect.getmembers(responses):
13 - if name.startswith('__'):
14 - continue
15 - if '_' in name:
16 - service_name, request_name = name.split('_', 1)
17 - if service_name not in self.response_map:
18 - self.response_map[service_name] = {}
19 - self.response_map[service_name][request_name] = value
20 -
21 - def create_client(self, client_name):
22 - client = None
23 - if client_name in self.response_map:
24 - client = mock.Mock()
25 - for request in self.response_map[client_name]:
26 - response = self.response_map[client_name][request]
27 - setattr(client, request, mock.Mock(side_effect=response))
28 - return client
29 -
30 -
31 -def get_aws(context):
32 - return MockAWS()
1 -import datetime
2 -from dateutil.tz import tzutc
3 -
4 -iam_list_policies = [{u'IsTruncated': True,
5 - u'Marker': 'ABcyoYmSlphARcitCJruhVIxKW3Hg1LJD3Fm4LAW8iGKykrSNrApiUoz2rjIuNiLJpT6JtUgP5M7wTuPZcHu1KsvMarvgFBFQObTPSa4WF22Zg==',
6 - u'Policies': [{u'Arn': 'arn:aws:iam::123456789012:policy/FooPolicy',
7 - u'AttachmentCount': 0,
8 - u'CreateDate': datetime.datetime(2015, 2, 24, 3, 16, 24, tzinfo=tzutc()),
9 - u'DefaultVersionId': 'v2',
10 - u'IsAttachable': True,
11 - u'Path': '/',
12 - u'PolicyId': 'ANPAJHWE6R7YT7PLAH3KG',
13 - u'PolicyName': 'FooPolicy',
14 - u'UpdateDate': datetime.datetime(2015, 2, 25, 0, 19, 12, tzinfo=tzutc())},
15 - {u'Arn': 'arn:aws:iam::123456789012:policy/BarPolicy',
16 - u'AttachmentCount': 1,
17 - u'CreateDate': datetime.datetime(2015, 2, 25, 0, 11, 57, tzinfo=tzutc()),
18 - u'DefaultVersionId': 'v2',
19 - u'IsAttachable': True,
20 - u'Path': '/',
21 - u'PolicyId': 'ANPAJU7MVBQXOQTVQN3VM',
22 - u'PolicyName': 'BarPolicy',
23 - u'UpdateDate': datetime.datetime(2015, 2, 25, 0, 13, 8, tzinfo=tzutc())},
24 - {u'Arn': 'arn:aws:iam::123456789012:policy/FiePolicy',
25 - u'AttachmentCount': 1,
26 - u'CreateDate': datetime.datetime(2015, 3, 21, 19, 18, 21, tzinfo=tzutc()),
27 - u'DefaultVersionId': 'v4',
28 - u'IsAttachable': True,
29 - u'Path': '/',
30 - u'PolicyId': 'ANPAIXQ72B2OH2RZPYQ4Y',
31 - u'PolicyName': 'FiePolicy',
32 - u'UpdateDate': datetime.datetime(2015, 3, 26, 23, 26, 52, tzinfo=tzutc())}],
33 -'ResponseMetadata': {'HTTPStatusCode': 200,
34 - 'RequestId': '4e87c995-ecf2-11e4-bb10-51f1499b3162'}}]
35 -
36 -iam_create_policy = [{u'Policy': {u'PolicyName': 'LambdaChatDynamoDBPolicy', u'CreateDate': datetime.datetime(2015, 4, 27, 12, 13, 35, 240000, tzinfo=tzutc()), u'AttachmentCount': 0, u'IsAttachable': True, u'PolicyId': 'ANPAISQNU4EPZZDVZUOKU', u'DefaultVersionId': 'v1', u'Path': '/kappa/', u'Arn': 'arn:aws:iam::658794617753:policy/kappa/LambdaChatDynamoDBPolicy', u'UpdateDate': datetime.datetime(2015, 4, 27, 12, 13, 35, 240000, tzinfo=tzutc())}, 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'd403e95f-ecd6-11e4-9ee0-15e8b71db930'}}]
37 -
38 -iam_list_roles = [{'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'd41415ff-ecd6-11e4-bb10-51f1499b3162'}, u'IsTruncated': False, u'Roles': [{u'AssumeRolePolicyDocument': {u'Version': u'2012-10-17', u'Statement': [{u'Action': u'sts:AssumeRole', u'Principal': {u'Service': u'lambda.amazonaws.com'}, u'Effect': u'Allow', u'Sid': u''}]}, u'RoleId': 'AROAJ4JSNL3M4UYI6GDYS', u'CreateDate': datetime.datetime(2015, 4, 27, 11, 59, 19, tzinfo=tzutc()), u'RoleName': 'FooRole', u'Path': '/kappa/', u'Arn': 'arn:aws:iam::123456789012:role/kappa/FooRole'}]}]
39 -
40 -iam_create_role = [{u'Role': {u'AssumeRolePolicyDocument': {u'Version': u'2012-10-17', u'Statement': [{u'Action': [u'sts:AssumeRole'], u'Effect': u'Allow', u'Principal': {u'Service': [u'lambda.amazonaws.com']}}]}, u'RoleId': 'AROAIT2ZRRPQBOIBBHPZU', u'CreateDate': datetime.datetime(2015, 4, 27, 12, 13, 35, 426000, tzinfo=tzutc()), u'RoleName': 'BazRole', u'Path': '/kappa/', u'Arn': 'arn:aws:iam::123456789012:role/kappa/BazRole'}, 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'd41fd55c-ecd6-11e4-9fd8-03ee0021e940'}}]
41 -
42 -iam_get_role = [{u'Role': {u'AssumeRolePolicyDocument': {u'Version': u'2012-10-17', u'Statement': [{u'Action': u'sts:AssumeRole', u'Principal': {u'Service': u's3.amazonaws.com'}, u'Effect': u'Allow', u'Condition': {u'ArnLike': {u'sts:ExternalId': u'arn:aws:s3:::*'}}, u'Sid': u''}, {u'Action': u'sts:AssumeRole', u'Principal': {u'Service': u'lambda.amazonaws.com'}, u'Effect': u'Allow', u'Sid': u''}]}, u'RoleId': 'AROAIEVJHUJG2I4MG5PSC', u'CreateDate': datetime.datetime(2015, 1, 6, 17, 37, 44, tzinfo=tzutc()), u'RoleName': 'TestKinesis-InvokeRole-IF6VUXY9MBJN', u'Path': '/', u'Arn': 'arn:aws:iam::0123456789012:role/TestKinesis-InvokeRole-FOO'}, 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'dd6e8d42-9699-11e4-afe6-d3625e8b365b'}}]
43 -
44 -iam_attach_role_policy = [{'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'd43e32dc-ecd6-11e4-9fd8-03ee0021e940'}}]
45 -
46 -iam_detach_role_policy = [{'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'a7d30b51-ecd6-11e4-bbe4-d996b8ad5d9e'}}]
47 -
48 -iam_delete_role = [{'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': 'a7e5a97e-ecd6-11e4-ae9e-6dee7bf37e66'}}]
49 -
50 -lambda_create_function = [{u'FunctionName': u'LambdaChatDynamoDB', 'ResponseMetadata': {'HTTPStatusCode': 201, 'RequestId': 'd7840efb-ecd6-11e4-b8b0-f7f3177894e9'}, u'CodeSize': 22024, u'MemorySize': 128, u'FunctionArn': u'arn:aws:lambda:us-east-1:123456789012:function:FooBarFunction', u'Handler': u'FooBarFunction.handler', u'Role': u'arn:aws:iam::123456789012:role/kappa/BazRole', u'Timeout': 3, u'LastModified': u'2015-04-27T12:13:41.147+0000', u'Runtime': u'nodejs', u'Description': u'A FooBar function'}]
51 -
52 -lambda_delete_function = [{'ResponseMetadata': {'HTTPStatusCode': 204, 'RequestId': 'a499b2c2-ecd6-11e4-8d2a-77b7e55836e7'}}]
53 -
54 -logs_describe_log_groups = [{'ResponseMetadata': {'HTTPStatusCode': 200,
55 - 'RequestId': 'da962431-afed-11e4-8c17-1776597471e6'},
56 - u'logGroups': [{u'arn': u'arn:aws:logs:us-east-1:0123456789012:log-group:/aws/lambda/KinesisSample*',
57 - u'creationTime': 1423175925414,
58 - u'logGroupName': u'foo/bar',
59 - u'metricFilterCount': 1,
60 - u'storedBytes': 0}]},
61 -{'ResponseMetadata': {'HTTPStatusCode': 200,
62 - 'RequestId': 'da962431-afed-11e4-8c17-1776597471e6'},
63 - u'logGroups': [{u'arn': u'arn:aws:logs:us-east-1:0123456789012:log-group:/aws/lambda/KinesisSample*',
64 - u'creationTime': 1423175925414,
65 - u'logGroupName': u'foo/bar',
66 - u'metricFilterCount': 1,
67 - u'storedBytes': 0}]}]
68 -
69 -logs_describe_log_streams = [{u'logStreams': [{u'firstEventTimestamp': 1417042749449, u'lastEventTimestamp': 1417042749547, u'creationTime': 1417042748263, u'uploadSequenceToken': u'49540114640150833041490484409222729829873988799393975922', u'logStreamName': u'1cc48e4e613246b7974094323259d600', u'lastIngestionTime': 1417042750483, u'arn': u'arn:aws:logs:us-east-1:0123456789012:log-group:/aws/lambda/KinesisSample:log-stream:1cc48e4e613246b7974094323259d600', u'storedBytes': 712}, {u'firstEventTimestamp': 1417272406988, u'lastEventTimestamp': 1417272407088, u'creationTime': 1417272405690, u'uploadSequenceToken': u'49540113907504451034164105858363493278561872472363261986', u'logStreamName': u'2782a5ff88824c85a9639480d1ed7bbe', u'lastIngestionTime': 1417272408043, u'arn': u'arn:aws:logs:us-east-1:0123456789012:log-group:/aws/lambda/KinesisSample:log-stream:2782a5ff88824c85a9639480d1ed7bbe', u'storedBytes': 712}, {u'firstEventTimestamp': 1420569035842, u'lastEventTimestamp': 1420569035941, u'creationTime': 1420569034614, u'uploadSequenceToken': u'49540113907883563702539166025438885323514410026454245426', u'logStreamName': u'2d62991a479b4ebf9486176122b72a55', u'lastIngestionTime': 1420569036909, u'arn': u'arn:aws:logs:us-east-1:0123456789012:log-group:/aws/lambda/KinesisSample:log-stream:2d62991a479b4ebf9486176122b72a55', u'storedBytes': 709}, {u'firstEventTimestamp': 1418244027421, u'lastEventTimestamp': 1418244027541, u'creationTime': 1418244026907, u'uploadSequenceToken': u'49540113964795065449189116778452984186276757901477438642', u'logStreamName': u'4f44ffa128d6405591ca83b2b0f9dd2d', u'lastIngestionTime': 1418244028484, u'arn': u'arn:aws:logs:us-east-1:0123456789012:log-group:/aws/lambda/KinesisSample:log-stream:4f44ffa128d6405591ca83b2b0f9dd2d', u'storedBytes': 1010}, {u'firstEventTimestamp': 1418242565524, u'lastEventTimestamp': 1418242565641, u'creationTime': 1418242564196, u'uploadSequenceToken': u'49540113095132904942090446312687285178819573422397343074', u'logStreamName': u'69c5ac87e7e6415985116e8cb44e538e', u'lastIngestionTime': 1418242566558, u'arn': u'arn:aws:logs:us-east-1:0123456789012:log-group:/aws/lambda/KinesisSample:log-stream:69c5ac87e7e6415985116e8cb44e538e', u'storedBytes': 713}, {u'firstEventTimestamp': 1417213193378, u'lastEventTimestamp': 1417213193478, u'creationTime': 1417213192095, u'uploadSequenceToken': u'49540113336360065754596187770479764234792559857643841394', u'logStreamName': u'f68e3d87b8a14cdba338f6926f7cf50a', u'lastIngestionTime': 1417213194421, u'arn': u'arn:aws:logs:us-east-1:0123456789012:log-group:/aws/lambda/KinesisSample:log-stream:f68e3d87b8a14cdba338f6926f7cf50a', u'storedBytes': 711}], 'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': '2a6d4941-969b-11e4-947f-19d1c72ede7e'}}]
70 -
71 -logs_get_log_events = [{'ResponseMetadata': {'HTTPStatusCode': 200, 'RequestId': '2a7deb71-969b-11e4-914b-8f1f3d7b023d'}, u'nextForwardToken': u'f/31679748107442531967654742688057700554200447759088287749', u'events': [{u'ingestionTime': 1420569036909, u'timestamp': 1420569035842, u'message': u'2015-01-06T18:30:35.841Z\tko2sss03iq7l2pdk\tLoading event\n'}, {u'ingestionTime': 1420569036909, u'timestamp': 1420569035899, u'message': u'START RequestId: 23007242-95d2-11e4-a10e-7b2ab60a7770\n'}, {u'ingestionTime': 1420569036909, u'timestamp': 1420569035940, u'message': u'2015-01-06T18:30:35.940Z\t23007242-95d2-11e4-a10e-7b2ab60a7770\t{\n "Records": [\n {\n "kinesis": {\n "partitionKey": "partitionKey-3",\n "kinesisSchemaVersion": "1.0",\n "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=",\n "sequenceNumber": "49545115243490985018280067714973144582180062593244200961"\n },\n "eventSource": "aws:kinesis",\n "eventID": "shardId-000000000000:49545115243490985018280067714973144582180062593244200961",\n "invokeIdentityArn": "arn:aws:iam::0123456789012:role/testLEBRole",\n "eventVersion": "1.0",\n "eventName": "aws:kinesis:record",\n "eventSourceARN": "arn:aws:kinesis:us-east-1:35667example:stream/examplestream",\n "awsRegion": "us-east-1"\n }\n ]\n}\n'}, {u'ingestionTime': 1420569036909, u'timestamp': 1420569035940, u'message': u'2015-01-06T18:30:35.940Z\t23007242-95d2-11e4-a10e-7b2ab60a7770\tDecoded payload: Hello, this is a test 123.\n'}, {u'ingestionTime': 1420569036909, u'timestamp': 1420569035941, u'message': u'END RequestId: 23007242-95d2-11e4-a10e-7b2ab60a7770\n'}, {u'ingestionTime': 1420569036909, u'timestamp': 1420569035941, u'message': u'REPORT RequestId: 23007242-95d2-11e4-a10e-7b2ab60a7770\tDuration: 98.51 ms\tBilled Duration: 100 ms \tMemory Size: 128 MB\tMax Memory Used: 26 MB\t\n'}], u'nextBackwardToken': u'b/31679748105234758193000210997045664445208259969996226560'}]
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 200,
6 + "RequestId": "1276680a-a219-11e5-8386-d3391e1d709e"
7 + }
8 + }
9 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "Policy": {
5 + "PolicyName": "kappa-simple_dev",
6 + "CreateDate": {
7 + "hour": 4,
8 + "__class__": "datetime",
9 + "month": 12,
10 + "second": 46,
11 + "microsecond": 302000,
12 + "year": 2015,
13 + "day": 14,
14 + "minute": 13
15 + },
16 + "AttachmentCount": 0,
17 + "IsAttachable": true,
18 + "PolicyId": "ANPAJ6USPUIU5QKQ7DWMG",
19 + "DefaultVersionId": "v1",
20 + "Path": "/kappa/",
21 + "Arn": "arn:aws:iam::123456789012:policy/kappa/kappa-simple_dev",
22 + "UpdateDate": {
23 + "hour": 4,
24 + "__class__": "datetime",
25 + "month": 12,
26 + "second": 46,
27 + "microsecond": 302000,
28 + "year": 2015,
29 + "day": 14,
30 + "minute": 13
31 + }
32 + },
33 + "ResponseMetadata": {
34 + "HTTPStatusCode": 200,
35 + "RequestId": "11cdf3d8-a219-11e5-a392-d5ea3c3fc695"
36 + }
37 + }
38 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "Role": {
5 + "AssumeRolePolicyDocument": "%7B%0A%20%20%20%20%22Version%22%20%3A%20%222012-10-17%22%2C%0A%20%20%20%20%22Statement%22%3A%20%5B%20%7B%0A%20%20%20%20%20%20%20%20%22Effect%22%3A%20%22Allow%22%2C%0A%20%20%20%20%20%20%20%20%22Principal%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Service%22%3A%20%5B%20%22lambda.amazonaws.com%22%20%5D%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%22Action%22%3A%20%5B%20%22sts%3AAssumeRole%22%20%5D%0A%20%20%20%20%7D%20%5D%0A%7D",
6 + "RoleId": "AROAICWPJDQLUTEOHRQZO",
7 + "CreateDate": {
8 + "hour": 4,
9 + "__class__": "datetime",
10 + "month": 12,
11 + "second": 46,
12 + "microsecond": 988000,
13 + "year": 2015,
14 + "day": 14,
15 + "minute": 13
16 + },
17 + "RoleName": "kappa-simple_dev",
18 + "Path": "/kappa/",
19 + "Arn": "arn:aws:iam::123456789012:role/kappa/kappa-simple_dev"
20 + },
21 + "ResponseMetadata": {
22 + "HTTPStatusCode": 200,
23 + "RequestId": "123d5777-a219-11e5-8386-d3391e1d709e"
24 + }
25 + }
26 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "Role": {
5 + "AssumeRolePolicyDocument": "%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22lambda.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D",
6 + "RoleId": "AROAICWPJDQLUTEOHRQZO",
7 + "CreateDate": {
8 + "hour": 4,
9 + "__class__": "datetime",
10 + "month": 12,
11 + "second": 46,
12 + "microsecond": 0,
13 + "year": 2015,
14 + "day": 14,
15 + "minute": 13
16 + },
17 + "RoleName": "kappa-simple_dev",
18 + "Path": "/kappa/",
19 + "Arn": "arn:aws:iam::123456789012:role/kappa/kappa-simple_dev"
20 + },
21 + "ResponseMetadata": {
22 + "HTTPStatusCode": 200,
23 + "RequestId": "12dca49a-a219-11e5-9912-d70327f9be2c"
24 + }
25 + }
26 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "Role": {
5 + "AssumeRolePolicyDocument": "%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22lambda.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D",
6 + "RoleId": "AROAICWPJDQLUTEOHRQZO",
7 + "CreateDate": {
8 + "hour": 4,
9 + "__class__": "datetime",
10 + "month": 12,
11 + "second": 46,
12 + "microsecond": 0,
13 + "year": 2015,
14 + "day": 14,
15 + "minute": 13
16 + },
17 + "RoleName": "kappa-simple_dev",
18 + "Path": "/kappa/",
19 + "Arn": "arn:aws:iam::123456789012:role/kappa/kappa-simple_dev"
20 + },
21 + "ResponseMetadata": {
22 + "HTTPStatusCode": 200,
23 + "RequestId": "1bd39022-a219-11e5-bb1e-6b18bfdcba09"
24 + }
25 + }
26 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 200,
6 + "RequestId": "11b86fd0-a219-11e5-aa2b-a9045f9fc5ef"
7 + },
8 + "IsTruncated": false,
9 + "Policies": [
10 + {
11 + "PolicyName": "FooBar1",
12 + "CreateDate": {
13 + "hour": 13,
14 + "__class__": "datetime",
15 + "month": 8,
16 + "second": 28,
17 + "microsecond": 0,
18 + "year": 2015,
19 + "day": 12,
20 + "minute": 10
21 + },
22 + "AttachmentCount": 1,
23 + "IsAttachable": true,
24 + "PolicyId": "ANPAIJJXBXY4EMCZAWQ3C",
25 + "DefaultVersionId": "v1",
26 + "Path": "/kappa/",
27 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar1",
28 + "UpdateDate": {
29 + "hour": 13,
30 + "__class__": "datetime",
31 + "month": 8,
32 + "second": 28,
33 + "microsecond": 0,
34 + "year": 2015,
35 + "day": 12,
36 + "minute": 10
37 + }
38 + },
39 + {
40 + "PolicyName": "FooBar2",
41 + "CreateDate": {
42 + "hour": 13,
43 + "__class__": "datetime",
44 + "month": 10,
45 + "second": 25,
46 + "microsecond": 0,
47 + "year": 2015,
48 + "day": 14,
49 + "minute": 52
50 + },
51 + "AttachmentCount": 0,
52 + "IsAttachable": true,
53 + "PolicyId": "ANPAI36ZNZUCBKGG3T762",
54 + "DefaultVersionId": "v2",
55 + "Path": "/kappa/",
56 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar2",
57 + "UpdateDate": {
58 + "hour": 17,
59 + "__class__": "datetime",
60 + "month": 10,
61 + "second": 28,
62 + "microsecond": 0,
63 + "year": 2015,
64 + "day": 17,
65 + "minute": 59
66 + }
67 + },
68 + {
69 + "PolicyName": "FooBar3",
70 + "CreateDate": {
71 + "hour": 13,
72 + "__class__": "datetime",
73 + "month": 8,
74 + "second": 57,
75 + "microsecond": 0,
76 + "year": 2015,
77 + "day": 12,
78 + "minute": 7
79 + },
80 + "AttachmentCount": 1,
81 + "IsAttachable": true,
82 + "PolicyId": "ANPAJZKD6WN4LDNGR5VRA",
83 + "DefaultVersionId": "v1",
84 + "Path": "/kappa/",
85 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar3",
86 + "UpdateDate": {
87 + "hour": 13,
88 + "__class__": "datetime",
89 + "month": 8,
90 + "second": 57,
91 + "microsecond": 0,
92 + "year": 2015,
93 + "day": 12,
94 + "minute": 7
95 + }
96 + },
97 + {
98 + "PolicyName": "FooBar4",
99 + "CreateDate": {
100 + "hour": 13,
101 + "__class__": "datetime",
102 + "month": 8,
103 + "second": 39,
104 + "microsecond": 0,
105 + "year": 2015,
106 + "day": 12,
107 + "minute": 11
108 + },
109 + "AttachmentCount": 1,
110 + "IsAttachable": true,
111 + "PolicyId": "ANPAIV3ZSVCRYFGHBPZAI",
112 + "DefaultVersionId": "v1",
113 + "Path": "/kappa/",
114 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar4",
115 + "UpdateDate": {
116 + "hour": 13,
117 + "__class__": "datetime",
118 + "month": 8,
119 + "second": 39,
120 + "microsecond": 0,
121 + "year": 2015,
122 + "day": 12,
123 + "minute": 11
124 + }
125 + },
126 + {
127 + "PolicyName": "FooBar5",
128 + "CreateDate": {
129 + "hour": 19,
130 + "__class__": "datetime",
131 + "month": 12,
132 + "second": 15,
133 + "microsecond": 0,
134 + "year": 2015,
135 + "day": 10,
136 + "minute": 22
137 + },
138 + "AttachmentCount": 1,
139 + "IsAttachable": true,
140 + "PolicyId": "ANPAJ3MM445EFVC6OWPIO",
141 + "DefaultVersionId": "v1",
142 + "Path": "/kappa/",
143 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar5",
144 + "UpdateDate": {
145 + "hour": 19,
146 + "__class__": "datetime",
147 + "month": 12,
148 + "second": 15,
149 + "microsecond": 0,
150 + "year": 2015,
151 + "day": 10,
152 + "minute": 22
153 + }
154 + },
155 + {
156 + "PolicyName": "FooBar6",
157 + "CreateDate": {
158 + "hour": 21,
159 + "__class__": "datetime",
160 + "month": 12,
161 + "second": 6,
162 + "microsecond": 0,
163 + "year": 2015,
164 + "day": 4,
165 + "minute": 2
166 + },
167 + "AttachmentCount": 1,
168 + "IsAttachable": true,
169 + "PolicyId": "ANPAIP7OSTDZSQHOHVWV6",
170 + "DefaultVersionId": "v2",
171 + "Path": "/kappa/",
172 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar6",
173 + "UpdateDate": {
174 + "hour": 21,
175 + "__class__": "datetime",
176 + "month": 12,
177 + "second": 25,
178 + "microsecond": 0,
179 + "year": 2015,
180 + "day": 4,
181 + "minute": 2
182 + }
183 + },
184 + {
185 + "PolicyName": "FooBar7",
186 + "CreateDate": {
187 + "hour": 22,
188 + "__class__": "datetime",
189 + "month": 12,
190 + "second": 36,
191 + "microsecond": 0,
192 + "year": 2015,
193 + "day": 7,
194 + "minute": 21
195 + },
196 + "AttachmentCount": 1,
197 + "IsAttachable": true,
198 + "PolicyId": "ANPAIA2TJQQSOWHRHICNO",
199 + "DefaultVersionId": "v3",
200 + "Path": "/kappa/",
201 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar7",
202 + "UpdateDate": {
203 + "hour": 6,
204 + "__class__": "datetime",
205 + "month": 12,
206 + "second": 0,
207 + "microsecond": 0,
208 + "year": 2015,
209 + "day": 8,
210 + "minute": 32
211 + }
212 + },
213 + {
214 + "PolicyName": "FooBar8",
215 + "CreateDate": {
216 + "hour": 5,
217 + "__class__": "datetime",
218 + "month": 11,
219 + "second": 53,
220 + "microsecond": 0,
221 + "year": 2015,
222 + "day": 25,
223 + "minute": 24
224 + },
225 + "AttachmentCount": 0,
226 + "IsAttachable": true,
227 + "PolicyId": "ANPAIO2EBHUIAPYICII4A",
228 + "DefaultVersionId": "v2",
229 + "Path": "/kappa/",
230 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar8",
231 + "UpdateDate": {
232 + "hour": 6,
233 + "__class__": "datetime",
234 + "month": 11,
235 + "second": 27,
236 + "microsecond": 0,
237 + "year": 2015,
238 + "day": 25,
239 + "minute": 2
240 + }
241 + },
242 + {
243 + "PolicyName": "FooBar9",
244 + "CreateDate": {
245 + "hour": 6,
246 + "__class__": "datetime",
247 + "month": 11,
248 + "second": 46,
249 + "microsecond": 0,
250 + "year": 2015,
251 + "day": 25,
252 + "minute": 15
253 + },
254 + "AttachmentCount": 1,
255 + "IsAttachable": true,
256 + "PolicyId": "ANPAJT2LR77BP2XNBBQWI",
257 + "DefaultVersionId": "v1",
258 + "Path": "/kappa/",
259 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar9",
260 + "UpdateDate": {
261 + "hour": 6,
262 + "__class__": "datetime",
263 + "month": 11,
264 + "second": 46,
265 + "microsecond": 0,
266 + "year": 2015,
267 + "day": 25,
268 + "minute": 15
269 + }
270 + },
271 + {
272 + "PolicyName": "FooBar10",
273 + "CreateDate": {
274 + "hour": 23,
275 + "__class__": "datetime",
276 + "month": 12,
277 + "second": 33,
278 + "microsecond": 0,
279 + "year": 2015,
280 + "day": 2,
281 + "minute": 36
282 + },
283 + "AttachmentCount": 1,
284 + "IsAttachable": true,
285 + "PolicyId": "ANPAIVVQ7LO6NZQ5ZT366",
286 + "DefaultVersionId": "v5",
287 + "Path": "/kappa/",
288 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar10",
289 + "UpdateDate": {
290 + "hour": 7,
291 + "__class__": "datetime",
292 + "month": 12,
293 + "second": 58,
294 + "microsecond": 0,
295 + "year": 2015,
296 + "day": 8,
297 + "minute": 6
298 + }
299 + },
300 + {
301 + "PolicyName": "FooBar11",
302 + "CreateDate": {
303 + "hour": 3,
304 + "__class__": "datetime",
305 + "month": 9,
306 + "second": 58,
307 + "microsecond": 0,
308 + "year": 2015,
309 + "day": 10,
310 + "minute": 38
311 + },
312 + "AttachmentCount": 1,
313 + "IsAttachable": true,
314 + "PolicyId": "ANPAISZHUMFND5KVSKA3G",
315 + "DefaultVersionId": "v1",
316 + "Path": "/kappa/",
317 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar11",
318 + "UpdateDate": {
319 + "hour": 3,
320 + "__class__": "datetime",
321 + "month": 9,
322 + "second": 58,
323 + "microsecond": 0,
324 + "year": 2015,
325 + "day": 10,
326 + "minute": 38
327 + }
328 + },
329 + {
330 + "PolicyName": "FooBar12",
331 + "CreateDate": {
332 + "hour": 3,
333 + "__class__": "datetime",
334 + "month": 9,
335 + "second": 23,
336 + "microsecond": 0,
337 + "year": 2015,
338 + "day": 10,
339 + "minute": 40
340 + },
341 + "AttachmentCount": 1,
342 + "IsAttachable": true,
343 + "PolicyId": "ANPAIQ7EDDRWYE77AZLGE",
344 + "DefaultVersionId": "v1",
345 + "Path": "/kappa/",
346 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar12",
347 + "UpdateDate": {
348 + "hour": 3,
349 + "__class__": "datetime",
350 + "month": 9,
351 + "second": 23,
352 + "microsecond": 0,
353 + "year": 2015,
354 + "day": 10,
355 + "minute": 40
356 + }
357 + },
358 + {
359 + "PolicyName": "FooBar13",
360 + "CreateDate": {
361 + "hour": 15,
362 + "__class__": "datetime",
363 + "month": 10,
364 + "second": 54,
365 + "microsecond": 0,
366 + "year": 2015,
367 + "day": 27,
368 + "minute": 56
369 + },
370 + "AttachmentCount": 1,
371 + "IsAttachable": true,
372 + "PolicyId": "ANPAIPNSCAHGGUTCHBSSO",
373 + "DefaultVersionId": "v4",
374 + "Path": "/kappa/",
375 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar13",
376 + "UpdateDate": {
377 + "hour": 16,
378 + "__class__": "datetime",
379 + "month": 10,
380 + "second": 44,
381 + "microsecond": 0,
382 + "year": 2015,
383 + "day": 27,
384 + "minute": 11
385 + }
386 + },
387 + {
388 + "PolicyName": "FooBar14",
389 + "CreateDate": {
390 + "hour": 15,
391 + "__class__": "datetime",
392 + "month": 11,
393 + "second": 34,
394 + "microsecond": 0,
395 + "year": 2015,
396 + "day": 15,
397 + "minute": 43
398 + },
399 + "AttachmentCount": 1,
400 + "IsAttachable": true,
401 + "PolicyId": "ANPAINLJTSXNVHPQE47BU",
402 + "DefaultVersionId": "v1",
403 + "Path": "/kappa/",
404 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar14",
405 + "UpdateDate": {
406 + "hour": 15,
407 + "__class__": "datetime",
408 + "month": 11,
409 + "second": 34,
410 + "microsecond": 0,
411 + "year": 2015,
412 + "day": 15,
413 + "minute": 43
414 + }
415 + }
416 + ]
417 + }
418 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 200,
6 + "RequestId": "1264405a-a219-11e5-ad54-c769aa17a0a1"
7 + },
8 + "IsTruncated": false,
9 + "Policies": [
10 + {
11 + "PolicyName": "kappa-simple_dev",
12 + "CreateDate": {
13 + "hour": 4,
14 + "__class__": "datetime",
15 + "month": 12,
16 + "second": 46,
17 + "microsecond": 0,
18 + "year": 2015,
19 + "day": 14,
20 + "minute": 13
21 + },
22 + "AttachmentCount": 0,
23 + "IsAttachable": true,
24 + "PolicyId": "ANPAJ6USPUIU5QKQ7DWMG",
25 + "DefaultVersionId": "v1",
26 + "Path": "/kappa/",
27 + "Arn": "arn:aws:iam::123456789012:policy/kappa/kappa-simple_dev",
28 + "UpdateDate": {
29 + "hour": 4,
30 + "__class__": "datetime",
31 + "month": 12,
32 + "second": 46,
33 + "microsecond": 0,
34 + "year": 2015,
35 + "day": 14,
36 + "minute": 13
37 + }
38 + },
39 + {
40 + "PolicyName": "FooBar15",
41 + "CreateDate": {
42 + "hour": 19,
43 + "__class__": "datetime",
44 + "month": 12,
45 + "second": 15,
46 + "microsecond": 0,
47 + "year": 2015,
48 + "day": 10,
49 + "minute": 22
50 + },
51 + "AttachmentCount": 1,
52 + "IsAttachable": true,
53 + "PolicyId": "ANPAJ3MM445EFVC6OWPIO",
54 + "DefaultVersionId": "v1",
55 + "Path": "/kappa/",
56 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar15",
57 + "UpdateDate": {
58 + "hour": 19,
59 + "__class__": "datetime",
60 + "month": 12,
61 + "second": 15,
62 + "microsecond": 0,
63 + "year": 2015,
64 + "day": 10,
65 + "minute": 22
66 + }
67 + }
68 + ]
69 + }
70 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 200,
6 + "RequestId": "1b40516e-a219-11e5-bb1e-6b18bfdcba09"
7 + },
8 + "IsTruncated": false,
9 + "Policies": [
10 + {
11 + "PolicyName": "kappa-simple_dev",
12 + "CreateDate": {
13 + "hour": 4,
14 + "__class__": "datetime",
15 + "month": 12,
16 + "second": 46,
17 + "microsecond": 0,
18 + "year": 2015,
19 + "day": 14,
20 + "minute": 13
21 + },
22 + "AttachmentCount": 1,
23 + "IsAttachable": true,
24 + "PolicyId": "ANPAJ6USPUIU5QKQ7DWMG",
25 + "DefaultVersionId": "v1",
26 + "Path": "/kappa/",
27 + "Arn": "arn:aws:iam::123456789012:policy/kappa/kappa-simple_dev",
28 + "UpdateDate": {
29 + "hour": 4,
30 + "__class__": "datetime",
31 + "month": 12,
32 + "second": 46,
33 + "microsecond": 0,
34 + "year": 2015,
35 + "day": 14,
36 + "minute": 13
37 + }
38 + },
39 + {
40 + "PolicyName": "FooBar15",
41 + "CreateDate": {
42 + "hour": 19,
43 + "__class__": "datetime",
44 + "month": 12,
45 + "second": 15,
46 + "microsecond": 0,
47 + "year": 2015,
48 + "day": 10,
49 + "minute": 22
50 + },
51 + "AttachmentCount": 1,
52 + "IsAttachable": true,
53 + "PolicyId": "ANPAJ3MM445EFVC6OWPIO",
54 + "DefaultVersionId": "v1",
55 + "Path": "/kappa/",
56 + "Arn": "arn:aws:iam::123456789012:policy/kappa/FooBar15",
57 + "UpdateDate": {
58 + "hour": 19,
59 + "__class__": "datetime",
60 + "month": 12,
61 + "second": 15,
62 + "microsecond": 0,
63 + "year": 2015,
64 + "day": 10,
65 + "minute": 22
66 + }
67 + }
68 + ]
69 + }
70 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 200,
6 + "RequestId": "120be6dd-a219-11e5-ad54-c769aa17a0a1"
7 + },
8 + "IsTruncated": false,
9 + "Roles": [
10 + {
11 + "AssumeRolePolicyDocument": "%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22lambda.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D",
12 + "RoleId": "AROAJC6I44KNC2N4C6DUO",
13 + "CreateDate": {
14 + "hour": 13,
15 + "__class__": "datetime",
16 + "month": 8,
17 + "second": 29,
18 + "microsecond": 0,
19 + "year": 2015,
20 + "day": 12,
21 + "minute": 10
22 + },
23 + "RoleName": "FooBar1",
24 + "Path": "/kappa/",
25 + "Arn": "arn:aws:iam::123456789012:role/kappa/FooBar1"
26 + },
27 + {
28 + "AssumeRolePolicyDocument": "%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22AWS%22%3A%22arn%3Aaws%3Aiam%3A%3A433502988969%3Aroot%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D",
29 + "RoleId": "AROAIPICAZWCWSIUY6WBC",
30 + "CreateDate": {
31 + "hour": 6,
32 + "__class__": "datetime",
33 + "month": 5,
34 + "second": 3,
35 + "microsecond": 0,
36 + "year": 2015,
37 + "day": 5,
38 + "minute": 31
39 + },
40 + "RoleName": "FooBar2",
41 + "Path": "/",
42 + "Arn": "arn:aws:iam::123456789012:role/FooBar2"
43 + }
44 + ]
45 + }
46 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 200,
6 + "RequestId": "1b6a1fab-a219-11e5-bb1e-6b18bfdcba09"
7 + },
8 + "IsTruncated": false,
9 + "Roles": [
10 + {
11 + "AssumeRolePolicyDocument": "%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22Service%22%3A%22lambda.amazonaws.com%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%7D%5D%7D",
12 + "RoleId": "AROAICWPJDQLUTEOHRQZO",
13 + "CreateDate": {
14 + "hour": 4,
15 + "__class__": "datetime",
16 + "month": 12,
17 + "second": 46,
18 + "microsecond": 0,
19 + "year": 2015,
20 + "day": 14,
21 + "minute": 13
22 + },
23 + "RoleName": "kappa-simple_dev",
24 + "Path": "/kappa/",
25 + "Arn": "arn:aws:iam::123456789012:role/kappa/kappa-simple_dev"
26 + },
27 + {
28 + "AssumeRolePolicyDocument": "%7B%22Version%22%3A%222012-10-17%22%2C%22Statement%22%3A%5B%7B%22Sid%22%3A%22%22%2C%22Effect%22%3A%22Allow%22%2C%22Principal%22%3A%7B%22AWS%22%3A%22arn%3Aaws%3Aiam%3A%3A123456789012%3Aroot%22%7D%2C%22Action%22%3A%22sts%3AAssumeRole%22%2C%22Condition%22%3A%7B%22StringEquals%22%3A%7B%22sts%3AExternalId%22%3A%22c196gvft3%22%7D%7D%7D%5D%7D",
29 + "RoleId": "AROAJGQVUYMCJZYCM3MR4",
30 + "CreateDate": {
31 + "hour": 15,
32 + "__class__": "datetime",
33 + "month": 6,
34 + "second": 2,
35 + "microsecond": 0,
36 + "year": 2015,
37 + "day": 12,
38 + "minute": 53
39 + },
40 + "RoleName": "kate-test-policy-role",
41 + "Path": "/",
42 + "Arn": "arn:aws:iam::123456789012:role/kate-test-policy-role"
43 + }
44 + ]
45 + }
46 +}
1 +{
2 + "status_code": 201,
3 + "data": {
4 + "AliasArn": "arn:aws:lambda:us-west-2:123456789012:function:kappa-simple:dev",
5 + "FunctionVersion": "12",
6 + "Name": "dev",
7 + "ResponseMetadata": {
8 + "HTTPStatusCode": 201,
9 + "RequestId": "1872d8ff-a219-11e5-9579-ab6c3f6de03e"
10 + },
11 + "Description": "For stage dev"
12 + }
13 +}
1 +{
2 + "status_code": 400,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 400,
6 + "RequestId": "12ed468e-a219-11e5-89fa-9b1d3e60e617"
7 + },
8 + "Error": {
9 + "Message": "The role defined for the task cannot be assumed by Lambda.",
10 + "Code": "InvalidParameterValueException"
11 + }
12 + }
13 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "status_code": 400,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 400,
6 + "RequestId": "14375279-a219-11e5-b9da-196ca0eccf24"
7 + },
8 + "Error": {
9 + "Message": "The role defined for the task cannot be assumed by Lambda.",
10 + "Code": "InvalidParameterValueException"
11 + }
12 + }
13 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "status_code": 400,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 400,
6 + "RequestId": "158815a1-a219-11e5-b354-111009c28f60"
7 + },
8 + "Error": {
9 + "Message": "The role defined for the task cannot be assumed by Lambda.",
10 + "Code": "InvalidParameterValueException"
11 + }
12 + }
13 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "status_code": 400,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 400,
6 + "RequestId": "16d88a59-a219-11e5-abfc-a3c6c8e4d88f"
7 + },
8 + "Error": {
9 + "Message": "The role defined for the task cannot be assumed by Lambda.",
10 + "Code": "InvalidParameterValueException"
11 + }
12 + }
13 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "status_code": 201,
3 + "data": {
4 + "CodeSha256": "JklpzNjuO6TLDiNe6nVYWeo1Imq6bF5uaMt2L0bqp5Y=",
5 + "FunctionName": "kappa-simple",
6 + "ResponseMetadata": {
7 + "HTTPStatusCode": 201,
8 + "RequestId": "1820256f-a219-11e5-acaa-ebe01320cf02"
9 + },
10 + "CodeSize": 948,
11 + "MemorySize": 256,
12 + "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:kappa-simple",
13 + "Version": "12",
14 + "Role": "arn:aws:iam::123456789012:role/kappa/kappa-simple_dev",
15 + "Timeout": 3,
16 + "LastModified": "2015-12-14T04:13:56.737+0000",
17 + "Handler": "simple.handler",
18 + "Runtime": "python2.7",
19 + "Description": "A very simple Kappa example"
20 + }
21 +}
1 +{
2 + "status_code": 404,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 404,
6 + "RequestId": "12caa276-a219-11e5-bc80-bb0600635952"
7 + },
8 + "Error": {
9 + "Message": "Function not found: arn:aws:lambda:us-west-2:860421987956:function:kappa-simple",
10 + "Code": "ResourceNotFoundException"
11 + }
12 + }
13 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "Code": {
5 + "RepositoryType": "S3",
6 + "Location": "https://awslambda-us-west-2-tasks.s3-us-west-2.amazonaws.com/snapshots/123456789012/kappa-simple-99dba060-c458-48c6-ab7b-501063603e69?x-amz-security-token=AQoDYXdzECQa4AOvxYmkiVqa3ost0drsHs84f3tyUBYSVQUm%2BVvFZgAqx9JDt55l4N4T%2FwH8302pH0ICUZfCRRfc%2FuWtukJsT33XIsG6Xw0Br8w00y07RRpZYQLiJqTXi0i2EFZ6LMIRsGBgKV%2BdufXXu7P9yfzqBiFUrfUD6fYeRNLdv34aXUDto0G0gTj3ZDv9gqO9q7YEXbeu1NI62cIfuEGph2ptFj5V1E%2BijK0h9XEW0mkfuomQt6oeii%2FkkNNm5tEyUlpeX17z1sbX3NYoqJrap0QdoqXkak%2BFPvJQG7hm7eJ40b2ymve9L3gvIOiKNzmQrzay77uEkYDNLxK89QMlYRtRG6vTHppdZzTVIooTFVdA6NSSvYHnjryStLA3VUnDG%2FsL9xAiHH8l4kzq%2ByvatF%2Fg8wTNXOdFxt0VMVkJVbwG%2FUex7juyEcRAJUGNaHBZNLPJVUL%2BfAQljCwJAnjXxD%2FpjEtyLi9YbdfLGywkBKccoKh7AmjJXwzT8TusWNKmmW0XJL%2Fn81NE84Ni9iVB8JHxRbwaJXT2ou0ytwn%2BIIlRcmwXSIwA3xm%2FXynUTfOuXZ3UMGuBlHtt45uKGJvvp5d6RQicK5q5LXFQgGxj5gUqgty0jPhPE%2BN%2BF8WUwSk3eNwPiwMgwOS4swU%3D&AWSAccessKeyId=ASIAIHZZJVPM3RQS3QOQ&Expires=1450067042&Signature=QeC65kDb6N4CNRGn9IiQNBSpl4g%3D"
7 + },
8 + "Configuration": {
9 + "Version": "$LATEST",
10 + "CodeSha256": "JklpzNjuO6TLDiNe6nVYWeo1Imq6bF5uaMt2L0bqp5Y=",
11 + "FunctionName": "kappa-simple",
12 + "MemorySize": 256,
13 + "CodeSize": 948,
14 + "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:kappa-simple",
15 + "Handler": "simple.handler",
16 + "Role": "arn:aws:iam::123456789012:role/kappa/kappa-simple_dev",
17 + "Timeout": 3,
18 + "LastModified": "2015-12-14T04:13:56.737+0000",
19 + "Runtime": "python2.7",
20 + "Description": "A very simple Kappa example"
21 + },
22 + "ResponseMetadata": {
23 + "HTTPStatusCode": 200,
24 + "RequestId": "1bc69855-a219-11e5-990d-c158fa575e6a"
25 + }
26 + }
27 +}
1 +{
2 + "status_code": 200,
3 + "data": {
4 + "ResponseMetadata": {
5 + "HTTPStatusCode": 200,
6 + "RequestId": "1860ff11-a219-11e5-b9da-196ca0eccf24"
7 + },
8 + "Versions": [
9 + {
10 + "Version": "$LATEST",
11 + "CodeSha256": "JklpzNjuO6TLDiNe6nVYWeo1Imq6bF5uaMt2L0bqp5Y=",
12 + "FunctionName": "kappa-simple",
13 + "MemorySize": 256,
14 + "CodeSize": 948,
15 + "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:kappa-simple:$LATEST",
16 + "Handler": "simple.handler",
17 + "Role": "arn:aws:iam::123456789012:role/kappa/kappa-simple_dev",
18 + "Timeout": 3,
19 + "LastModified": "2015-12-14T04:13:56.737+0000",
20 + "Runtime": "python2.7",
21 + "Description": "A very simple Kappa example"
22 + },
23 + {
24 + "Version": "12",
25 + "CodeSha256": "JklpzNjuO6TLDiNe6nVYWeo1Imq6bF5uaMt2L0bqp5Y=",
26 + "FunctionName": "kappa-simple",
27 + "MemorySize": 256,
28 + "CodeSize": 948,
29 + "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:kappa-simple:12",
30 + "Handler": "simple.handler",
31 + "Role": "arn:aws:iam::123456789012:role/kappa/kappa-simple_dev",
32 + "Timeout": 3,
33 + "LastModified": "2015-12-14T04:13:56.737+0000",
34 + "Runtime": "python2.7",
35 + "Description": "A very simple Kappa example"
36 + }
37 + ]
38 + }
39 +}
1 +# Copyright (c) 2015 Mitch Garnaat http://garnaat.org/
2 +#
3 +# Licensed under the Apache License, Version 2.0 (the "License"). You
4 +# may not use this file except in compliance with the License. A copy of
5 +# the License is located at
6 +#
7 +# http://aws.amazon.com/apache2.0/
8 +#
9 +# or in the "license" file accompanying this file. This file is
10 +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 +# ANY KIND, either express or implied. See the License for the specific
12 +# language governing permissions and limitations under the License.
13 +
14 +import unittest
15 +import os
16 +import shutil
17 +
18 +import mock
19 +import placebo
20 +
21 +import kappa.context
22 +import kappa.awsclient
23 +
24 +
25 +class TestLog(unittest.TestCase):
26 +
27 + def setUp(self):
28 + self.environ = {}
29 + self.environ_patch = mock.patch('os.environ', self.environ)
30 + self.environ_patch.start()
31 + credential_path = os.path.join(os.path.dirname(__file__), 'cfg',
32 + 'aws_credentials')
33 + self.environ['AWS_SHARED_CREDENTIALS_FILE'] = credential_path
34 + self.prj_path = os.path.join(os.path.dirname(__file__), 'foobar')
35 + cache_file = os.path.join(self.prj_path, '.kappa')
36 + if os.path.exists(cache_file):
37 + shutil.rmtree(cache_file)
38 + self.data_path = os.path.join(os.path.dirname(__file__), 'responses')
39 + self.data_path = os.path.join(self.data_path, 'deploy')
40 + self.session = kappa.awsclient.create_session('foobar', 'us-west-2')
41 +
42 + def tearDown(self):
43 + pass
44 +
45 + def test_deploy(self):
46 + pill = placebo.attach(self.session, self.data_path)
47 + pill.playback()
48 + os.chdir(self.prj_path)
49 + cfg_filepath = os.path.join(self.prj_path, 'kappa.yml')
50 + cfg_fp = open(cfg_filepath)
51 + ctx = kappa.context.Context(cfg_fp, 'dev')
52 + ctx.deploy()
53 + ctx.deploy()
1 -# Copyright (c) 2014 Mitch Garnaat http://garnaat.org/
2 -#
3 -# Licensed under the Apache License, Version 2.0 (the "License"). You
4 -# may not use this file except in compliance with the License. A copy of
5 -# the License is located at
6 -#
7 -# http://aws.amazon.com/apache2.0/
8 -#
9 -# or in the "license" file accompanying this file. This file is
10 -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 -# ANY KIND, either express or implied. See the License for the specific
12 -# language governing permissions and limitations under the License.
13 -
14 -import unittest
15 -
16 -import mock
17 -
18 -from kappa.log import Log
19 -from tests.unit.mock_aws import get_aws
20 -
21 -
22 -class TestLog(unittest.TestCase):
23 -
24 - def setUp(self):
25 - self.aws_patch = mock.patch('kappa.aws.get_aws', get_aws)
26 - self.mock_aws = self.aws_patch.start()
27 -
28 - def tearDown(self):
29 - self.aws_patch.stop()
30 -
31 - def test_streams(self):
32 - mock_context = mock.Mock()
33 - log = Log(mock_context, 'foo/bar')
34 - streams = log.streams()
35 - self.assertEqual(len(streams), 6)
36 -
37 - def test_tail(self):
38 - mock_context = mock.Mock()
39 - log = Log(mock_context, 'foo/bar')
40 - events = log.tail()
41 - self.assertEqual(len(events), 6)
42 - self.assertEqual(events[0]['ingestionTime'], 1420569036909)
43 - self.assertIn('RequestId: 23007242-95d2-11e4-a10e-7b2ab60a7770',
44 - events[-1]['message'])
1 -# Copyright (c) 2015 Mitch Garnaat http://garnaat.org/
2 -#
3 -# Licensed under the Apache License, Version 2.0 (the "License"). You
4 -# may not use this file except in compliance with the License. A copy of
5 -# the License is located at
6 -#
7 -# http://aws.amazon.com/apache2.0/
8 -#
9 -# or in the "license" file accompanying this file. This file is
10 -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 -# ANY KIND, either express or implied. See the License for the specific
12 -# language governing permissions and limitations under the License.
13 -
14 -import unittest
15 -import os
16 -
17 -import mock
18 -
19 -from kappa.policy import Policy
20 -from tests.unit.mock_aws import get_aws
21 -
22 -Config1 = {
23 - 'name': 'FooPolicy',
24 - 'description': 'This is the Foo policy',
25 - 'document': 'FooPolicy.json'}
26 -
27 -Config2 = {
28 - 'name': 'BazPolicy',
29 - 'description': 'This is the Baz policy',
30 - 'document': 'BazPolicy.json'}
31 -
32 -
33 -def path(filename):
34 - return os.path.join(os.path.dirname(__file__), 'data', filename)
35 -
36 -
37 -class TestPolicy(unittest.TestCase):
38 -
39 - def setUp(self):
40 - self.aws_patch = mock.patch('kappa.aws.get_aws', get_aws)
41 - self.mock_aws = self.aws_patch.start()
42 - Config1['document'] = path(Config1['document'])
43 - Config2['document'] = path(Config2['document'])
44 -
45 - def tearDown(self):
46 - self.aws_patch.stop()
47 -
48 - def test_properties(self):
49 - mock_context = mock.Mock()
50 - policy = Policy(mock_context, Config1)
51 - self.assertEqual(policy.name, Config1['name'])
52 - self.assertEqual(policy.document, Config1['document'])
53 - self.assertEqual(policy.description, Config1['description'])
54 -
55 - def test_exists(self):
56 - mock_context = mock.Mock()
57 - policy = Policy(mock_context, Config1)
58 - self.assertTrue(policy.exists())
59 -
60 - def test_not_exists(self):
61 - mock_context = mock.Mock()
62 - policy = Policy(mock_context, Config2)
63 - self.assertFalse(policy.exists())
64 -
65 - def test_create(self):
66 - mock_context = mock.Mock()
67 - policy = Policy(mock_context, Config2)
68 - policy.create()
69 -
70 - def test_delete(self):
71 - mock_context = mock.Mock()
72 - policy = Policy(mock_context, Config1)
73 - policy.delete()
1 -# Copyright (c) 2015 Mitch Garnaat http://garnaat.org/
2 -#
3 -# Licensed under the Apache License, Version 2.0 (the "License"). You
4 -# may not use this file except in compliance with the License. A copy of
5 -# the License is located at
6 -#
7 -# http://aws.amazon.com/apache2.0/
8 -#
9 -# or in the "license" file accompanying this file. This file is
10 -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 -# ANY KIND, either express or implied. See the License for the specific
12 -# language governing permissions and limitations under the License.
13 -
14 -import unittest
15 -
16 -import mock
17 -
18 -from kappa.role import Role
19 -from tests.unit.mock_aws import get_aws
20 -
21 -Config1 = {'name': 'FooRole'}
22 -
23 -Config2 = {'name': 'BazRole'}
24 -
25 -
26 -class TestRole(unittest.TestCase):
27 -
28 - def setUp(self):
29 - self.aws_patch = mock.patch('kappa.aws.get_aws', get_aws)
30 - self.mock_aws = self.aws_patch.start()
31 -
32 - def tearDown(self):
33 - self.aws_patch.stop()
34 -
35 - def test_properties(self):
36 - mock_context = mock.Mock()
37 - role = Role(mock_context, Config1)
38 - self.assertEqual(role.name, Config1['name'])
39 -
40 - def test_exists(self):
41 - mock_context = mock.Mock()
42 - role = Role(mock_context, Config1)
43 - self.assertTrue(role.exists())
44 -
45 - def test_not_exists(self):
46 - mock_context = mock.Mock()
47 - role = Role(mock_context, Config2)
48 - self.assertFalse(role.exists())
49 -
50 - def test_create(self):
51 - mock_context = mock.Mock()
52 - role = Role(mock_context, Config2)
53 - role.create()
54 -
55 - def test_delete(self):
56 - mock_context = mock.Mock()
57 - role = Role(mock_context, Config1)
58 - role.delete()