From ced5f966f6a110e8ee28688a2338e9d05a67ad68 Mon Sep 17 00:00:00 2001 From: Mohit Date: Fri, 20 Nov 2020 16:24:12 +0530 Subject: [PATCH 1/4] Add content base filters in events --- localstack/services/events/events_starter.py | 156 ++++++++++++++++- tests/integration/test_events.py | 166 ++++++++++++++++--- 2 files changed, 299 insertions(+), 23 deletions(-) diff --git a/localstack/services/events/events_starter.py b/localstack/services/events/events_starter.py index 47740b10aa1a7..0b62578f3c10a 100644 --- a/localstack/services/events/events_starter.py +++ b/localstack/services/events/events_starter.py @@ -1,7 +1,9 @@ +import re import datetime import json import uuid import logging +import ipaddress from moto.events.models import Rule as rule_model from moto.events.responses import EventsHandler as events_handler from localstack import config @@ -24,6 +26,10 @@ DEFAULT_EVENT_BUS_NAME: set() } +CONTENT_BASE_FILTER_KEYWORDS = [ + 'prefix', 'anything-but', 'numeric', 'cidr', 'exists' +] + def send_event_to_sqs(event, arn): region = arn.split(':')[3] @@ -52,12 +58,40 @@ def filter_event_with_target_input_path(target, event): def filter_event_based_on_event_format(self, rule, event): + def filter_event(event_pattern, event): + for key, value in event_pattern.items(): + event_value = event.get(key.lower()) + if not event_value: + return False + + if isinstance(value, list) and not identify_content_base_parameter_in_pattern(value): + if isinstance(event_value, list) and \ + get_two_lists_intersection(value, event_value) == []: + return False + elif not isinstance(event_value, list) and \ + (isinstance(event_value, str) or isinstance(event_value, int)) and \ + event_value not in value: + return False + + elif isinstance(value, list) and identify_content_base_parameter_in_pattern(value): + if not filter_event_with_content_base_parameter(value, event_value): + return False + + elif isinstance(value, str) or isinstance(value, int): + try: + if isinstance(json.loads(value), dict) and \ + not filter_event(json.loads(value), event_value): + return False + except json.decoder.JSONDecodeError: + return False + return True + rule_information = self.events_backend.describe_rule(rule) if rule_information.event_pattern: event_pattern = json.loads(rule_information.event_pattern) - for key, value in event_pattern.items(): - if event.get(key.lower()) and event.get(key.lower()) not in value and event.get(key) != value: - return False + event_pattern = {k.lower(): v for k, v in event_pattern.items()} + if not filter_event(event_pattern, event): + return False return True @@ -198,3 +232,119 @@ def start_events(port=None, asynchronous=None, update_listener=None): asynchronous=asynchronous, update_listener=update_listener ) + + +# --------------- +# HELPER METHODS +# --------------- + + +def get_two_lists_intersection(lst1, lst2): + lst3 = [value for value in lst1 if value in lst2] + return lst3 + + +def identify_content_base_parameter_in_pattern(parameters): + if any([list(param.keys())[0] in CONTENT_BASE_FILTER_KEYWORDS for param in parameters if isinstance(param, dict)]): + return True + + +def filter_event_with_content_base_parameter(pattern_value, event_value): + evaluated_result = [] + for element in pattern_value: + if (isinstance(element, str) or isinstance(element, int)) \ + and (event_value == element or element in event_value): + evaluated_result.append(True) + elif isinstance(element, dict): + element_key = list(element.keys())[0] + element_value = element.get(element_key) + if element_key.lower() == 'prefix': + if not re.match(r'^{}'.format(element_value), event_value): + evaluated_result.append(False) + else: + evaluated_result.append(True) + elif element_key.lower() == 'exists': + if element_value and not event_value: + evaluated_result.append(False) + elif not element_value and event_value: + evaluated_result.append(False) + else: + evaluated_result.append(True) + elif element_key.lower() == 'cidr': + ips = [str(ip) for ip in ipaddress.IPv4Network(element_value)] + if event_value not in ips: + evaluated_result.append(False) + else: + evaluated_result.append(True) + elif element_key.lower() == 'numeric': + list_of_operators = element_value + check_valid_numeric_content_base_rule(list_of_operators) + for index in range(len(list_of_operators)): + + if list_of_operators[index] == '>' and \ + isinstance(list_of_operators[index + 1], int) and \ + event_value <= list_of_operators[index + 1]: + evaluated_result.append(False) + + elif list_of_operators[index] == '>=' and \ + isinstance(list_of_operators[index + 1], int) and \ + event_value < list_of_operators[index + 1]: + evaluated_result.append(False) + + elif list_of_operators[index] == '<' and \ + isinstance(list_of_operators[index + 1], int) and \ + event_value >= list_of_operators[index + 1]: + evaluated_result.append(False) + + elif list_of_operators[index] == '<=' and \ + isinstance(list_of_operators[index + 1], int) and \ + event_value > list_of_operators[index + 1]: + evaluated_result.append(False) + + else: + evaluated_result.append(True) + index = index + 1 + + elif element_key.lower() == 'anything-but': + if isinstance(element_value, list) and \ + event_value in element_value: + evaluated_result.append(False) + elif (isinstance(element_value, str) or isinstance(element_value, int)) and \ + event_value == element_value: + evaluated_result.append(False) + elif isinstance(element_value, dict): + nested_key = list(element_value)[0] + if nested_key == 'prefix' and re.match(r'^{}'.format(element_value.get(nested_key)), event_value): + evaluated_result.append(False) + else: + evaluated_result.append(True) + else: + evaluated_result.append(True) + else: + evaluated_result.append(True) + if any(evaluated_result) or evaluated_result == []: + return True + elif not all(evaluated_result): + return False + + +def check_valid_numeric_content_base_rule(list_of_operators): + if len(list_of_operators) > 4: + return False + + if '=' in list_of_operators: + return False + + if len(list_of_operators) > 2: + upper_limit = None + lower_limit = None + for index in range(len(list_of_operators)): + if not isinstance(list_of_operators[index], int) and \ + '<' in list_of_operators[index]: + upper_limit = list_of_operators[index + 1] + if not isinstance(list_of_operators[index], int) and \ + '>' in list_of_operators[index]: + lower_limit = list_of_operators[index + 1] + if upper_limit and lower_limit and upper_limit < lower_limit: + return False + index = index + 1 diff --git a/tests/integration/test_events.py b/tests/integration/test_events.py index 1c17700ac5294..fe6fe03d5f9ea 100644 --- a/tests/integration/test_events.py +++ b/tests/integration/test_events.py @@ -22,9 +22,9 @@ EVENT_DETAIL = '{\"command\":\"update-account\",\"payload\":{\"acc_id\":\"0a787ecb-4015\",\"sf_id\":\"baz\"}}' TEST_EVENT_PATTERN = { - 'Source': 'core.update-account-command', - 'DetailType': 'core.update-account-command', - 'Detail': EVENT_DETAIL + 'Source': ['core.update-account-command'], + 'detail-type': ['core.update-account-command'], + 'Detail': [EVENT_DETAIL] } @@ -113,6 +113,7 @@ def test_put_events_with_target_sqs(self): queue_name = 'queue-{}'.format(short_uid()) rule_name = 'rule-{}'.format(short_uid()) target_id = 'target-{}'.format(short_uid()) + TEST_EVENT_BUS_NAME = 'bus-{}'.format(short_uid()) sqs_client = aws_stack.connect_to_service('sqs') queue_url = sqs_client.create_queue(QueueName=queue_name)['QueueUrl'] @@ -147,9 +148,9 @@ def test_put_events_with_target_sqs(self): self.events_client.put_events( Entries=[{ 'EventBusName': TEST_EVENT_BUS_NAME, - 'Source': TEST_EVENT_PATTERN['Source'], - 'DetailType': TEST_EVENT_PATTERN['DetailType'], - 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail']) + 'Source': TEST_EVENT_PATTERN['Source'][0], + 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], + 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) }] ) @@ -162,7 +163,7 @@ def get_message(queue_url): actual_event = json.loads(messages[0]['Body']) self.assertIsValidEvent(actual_event) - self.assertEqual(actual_event['detail'], TEST_EVENT_PATTERN['Detail']) + self.assertEqual(actual_event['detail'], TEST_EVENT_PATTERN['Detail'][0]) # clean up sqs_client.delete_queue(QueueUrl=queue_url) @@ -186,6 +187,7 @@ def test_put_events_with_target_lambda(self): rule_name = 'rule-{}'.format(short_uid()) function_name = 'lambda-func-{}'.format(short_uid()) target_id = 'target-{}'.format(short_uid()) + TEST_EVENT_BUS_NAME = 'bus-{}'.format(short_uid()) rs = testutil.create_lambda_function(handler_file=os.path.join(THIS_FOLDER, 'lambdas', 'lambda_echo.py'), func_name=function_name, @@ -222,9 +224,9 @@ def test_put_events_with_target_lambda(self): self.events_client.put_events( Entries=[{ 'EventBusName': TEST_EVENT_BUS_NAME, - 'Source': TEST_EVENT_PATTERN['Source'], - 'DetailType': TEST_EVENT_PATTERN['DetailType'], - 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail']) + 'Source': TEST_EVENT_PATTERN['Source'][0], + 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], + 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) }] ) @@ -233,7 +235,7 @@ def test_put_events_with_target_lambda(self): sleep=1, function_name=function_name, expected_length=1) actual_event = events[0] self.assertIsValidEvent(actual_event) - self.assertDictEqual(json.loads(actual_event['detail']), json.loads(TEST_EVENT_PATTERN['Detail'])) + self.assertDictEqual(json.loads(actual_event['detail']), json.loads(TEST_EVENT_PATTERN['Detail'][0])) # clean up testutil.delete_lambda_function(function_name) @@ -378,6 +380,7 @@ def test_put_events_with_target_firehose(self): stream_name = 'firehose-{}'.format(short_uid()) rule_name = 'rule-{}'.format(short_uid()) target_id = 'target-{}'.format(short_uid()) + TEST_EVENT_BUS_NAME = 'bus-{}'.format(short_uid()) # create firehose target bucket s3_client = aws_stack.connect_to_service('s3') @@ -424,9 +427,9 @@ def test_put_events_with_target_firehose(self): self.events_client.put_events( Entries=[{ 'EventBusName': TEST_EVENT_BUS_NAME, - 'Source': TEST_EVENT_PATTERN['Source'], - 'DetailType': TEST_EVENT_PATTERN['DetailType'], - 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail']) + 'Source': TEST_EVENT_PATTERN['Source'][0], + 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], + 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) }] ) @@ -437,7 +440,7 @@ def test_put_events_with_target_firehose(self): s3_object = s3_client.get_object(Bucket=s3_bucket, Key=key) actual_event = json.loads(s3_object['Body'].read().decode()) self.assertIsValidEvent(actual_event) - self.assertEqual(actual_event['detail'], TEST_EVENT_PATTERN['Detail']) + self.assertEqual(actual_event['detail'], TEST_EVENT_PATTERN['Detail'][0]) # clean up firehose_client.delete_delivery_stream(DeliveryStreamName=stream_name) @@ -499,6 +502,7 @@ def test_put_events_with_input_path(self): queue_name = 'queue-{}'.format(short_uid()) rule_name = 'rule-{}'.format(short_uid()) target_id = 'target-{}'.format(short_uid()) + TEST_EVENT_BUS_NAME = 'bus-{}'.format(short_uid()) sqs_client = aws_stack.connect_to_service('sqs') queue_url = sqs_client.create_queue(QueueName=queue_name)['QueueUrl'] @@ -529,9 +533,9 @@ def test_put_events_with_input_path(self): self.events_client.put_events( Entries=[{ 'EventBusName': TEST_EVENT_BUS_NAME, - 'Source': TEST_EVENT_PATTERN['Source'], - 'DetailType': TEST_EVENT_PATTERN['DetailType'], - 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail']) + 'Source': TEST_EVENT_PATTERN['Source'][0], + 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], + 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) }] ) @@ -547,8 +551,8 @@ def get_message(queue_url): Entries=[{ 'EventBusName': TEST_EVENT_BUS_NAME, 'Source': 'dummySource', - 'DetailType': TEST_EVENT_PATTERN['DetailType'], - 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail']) + 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], + 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) }] ) @@ -585,3 +589,125 @@ def test_put_event_without_source(self): ] ) self.assertIn('Entries', response) + + def test_put_event_with_content_base_rule_in_pattern(self): + queue_name = 'queue-{}'.format(short_uid()) + rule_name = 'rule-{}'.format(short_uid()) + target_id = 'target-{}'.format(short_uid()) + + sqs_client = aws_stack.connect_to_service('sqs') + queue_url = sqs_client.create_queue(QueueName=queue_name)['QueueUrl'] + queue_arn = aws_stack.sqs_queue_arn(queue_name) + + TEST_EVENT_PATTERN = { + 'Source': [{'exists': True}], + 'detail-type': [{'prefix': 'core.app'}], + 'Detail': json.dumps({ + 'decription': ['this-is-event-details'], + 'amount': [200], + 'salary': [2000, 4000], + 'env': ['dev', 'prod'], + 'user': ['user1', 'user2', 'user3'], + 'admins': ['skyli', {'prefix': 'hey'}, {'prefix': 'ad'}], + 'test1': [{'anything-but': 200}], + 'test2': [{'anything-but': 'test2'}], + 'test3': [{'anything-but': ['test3', 'test33']}], + 'test4': [{'anything-but': {'prefix': 'test4'}}], + 'ip': [{'cidr': '10.102.1.0/24'}], + 'num-test1': [{'numeric': ['<', 200]}], + 'num-test2': [{'numeric': ['<=', 200]}], + 'num-test3': [{'numeric': ['>', 200]}], + 'num-test4': [{'numeric': ['>=', 200]}], + 'num-test5': [{'numeric': ['>=', 200, '<=', 500]}], + 'num-test6': [{'numeric': ['>', 200, '<', 500]}], + 'num-test7': [{'numeric': ['>=', 200, '<', 500]}] + }) + } + + EVENT = { + 'EventBusName': TEST_EVENT_BUS_NAME, + 'Source': 'core.update-account-command', + 'DetailType': 'core.app.backend', + 'Detail': json.dumps({ + 'decription': 'this-is-event-details', + 'amount': 200, + 'salary': 2000, + 'env': 'prod', + 'user': ['user4', 'user3'], + 'admins': 'admin', + 'test1': 300, + 'test2': 'test22', + 'test3': 'test333', + 'test4': 'this test4', + 'ip': '10.102.1.100', + 'num-test1': 100, + 'num-test2': 200, + 'num-test3': 300, + 'num-test4': 200, + 'num-test5': 500, + 'num-test6': 300, + 'num-test7': 300 + }) + } + + self.events_client.create_event_bus( + Name=TEST_EVENT_BUS_NAME + ) + + self.events_client.put_rule( + Name=rule_name, + EventBusName=TEST_EVENT_BUS_NAME, + EventPattern=json.dumps(TEST_EVENT_PATTERN) + ) + + self.events_client.put_targets( + Rule=rule_name, + EventBusName=TEST_EVENT_BUS_NAME, + Targets=[ + { + 'Id': target_id, + 'Arn': queue_arn, + 'InputPath': '$.detail' + } + ] + ) + self.events_client.put_events( + Entries=[EVENT] + ) + + def get_message(queue_url): + resp = sqs_client.receive_message(QueueUrl=queue_url) + return resp.get('Messages') + + messages = retry(get_message, retries=3, sleep=1, queue_url=queue_url) + self.assertEqual(len(messages), 1) + self.assertEqual(json.loads(messages[0].get('Body')), json.loads(EVENT['Detail'])) + + EVENT_DETAIL = json.loads(EVENT['Detail']) + EVENT_DETAIL['admins'] = 'not_admin' + EVENT['Detail'] = json.dumps(EVENT_DETAIL) + + self.events_client.put_events( + Entries=[EVENT] + ) + + messages = retry(get_message, retries=3, sleep=1, queue_url=queue_url) + self.assertEqual(messages, None) + + # clean up + sqs_client.delete_queue(QueueUrl=queue_url) + + self.events_client.remove_targets( + Rule=rule_name, + EventBusName=TEST_EVENT_BUS_NAME, + Ids=[target_id], + Force=True + ) + self.events_client.delete_rule( + Name=rule_name, + EventBusName=TEST_EVENT_BUS_NAME, + Force=True + ) + self.events_client.delete_event_bus( + Name=TEST_EVENT_BUS_NAME + ) From b54bbe7c657b67c4dd347d69c7cec64189c1c4ca Mon Sep 17 00:00:00 2001 From: Mohit Date: Fri, 20 Nov 2020 21:04:05 +0530 Subject: [PATCH 2/4] minor fix --- localstack/services/events/events_starter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localstack/services/events/events_starter.py b/localstack/services/events/events_starter.py index 0b62578f3c10a..a56e36db94bd8 100644 --- a/localstack/services/events/events_starter.py +++ b/localstack/services/events/events_starter.py @@ -60,7 +60,7 @@ def filter_event_with_target_input_path(target, event): def filter_event_based_on_event_format(self, rule, event): def filter_event(event_pattern, event): for key, value in event_pattern.items(): - event_value = event.get(key.lower()) + event_value = event.get(key) if not event_value: return False From 146f13f3d58c33e11cd8f7a8ae8a92c6237894a1 Mon Sep 17 00:00:00 2001 From: Mohit Date: Thu, 26 Nov 2020 23:32:00 +0530 Subject: [PATCH 3/4] improved and simplified the main logic --- localstack/services/events/events_starter.py | 108 ++++++++----------- 1 file changed, 44 insertions(+), 64 deletions(-) diff --git a/localstack/services/events/events_starter.py b/localstack/services/events/events_starter.py index a56e36db94bd8..19c568366be47 100644 --- a/localstack/services/events/events_starter.py +++ b/localstack/services/events/events_starter.py @@ -60,7 +60,7 @@ def filter_event_with_target_input_path(target, event): def filter_event_based_on_event_format(self, rule, event): def filter_event(event_pattern, event): for key, value in event_pattern.items(): - event_value = event.get(key) + event_value = event.get(key.lower()) if not event_value: return False @@ -69,7 +69,7 @@ def filter_event(event_pattern, event): get_two_lists_intersection(value, event_value) == []: return False elif not isinstance(event_value, list) and \ - (isinstance(event_value, str) or isinstance(event_value, int)) and \ + isinstance(event_value, (str, int)) and \ event_value not in value: return False @@ -77,7 +77,7 @@ def filter_event(event_pattern, event): if not filter_event_with_content_base_parameter(value, event_value): return False - elif isinstance(value, str) or isinstance(value, int): + elif isinstance(value, (str, int)): try: if isinstance(json.loads(value), dict) and \ not filter_event(json.loads(value), event_value): @@ -89,7 +89,6 @@ def filter_event(event_pattern, event): rule_information = self.events_backend.describe_rule(rule) if rule_information.event_pattern: event_pattern = json.loads(rule_information.event_pattern) - event_pattern = {k.lower(): v for k, v in event_pattern.items()} if not filter_event(event_pattern, event): return False return True @@ -250,82 +249,62 @@ def identify_content_base_parameter_in_pattern(parameters): def filter_event_with_content_base_parameter(pattern_value, event_value): - evaluated_result = [] for element in pattern_value: - if (isinstance(element, str) or isinstance(element, int)) \ + if (isinstance(element, (str, int))) \ and (event_value == element or element in event_value): - evaluated_result.append(True) + return True elif isinstance(element, dict): element_key = list(element.keys())[0] element_value = element.get(element_key) if element_key.lower() == 'prefix': - if not re.match(r'^{}'.format(element_value), event_value): - evaluated_result.append(False) - else: - evaluated_result.append(True) + if re.match(r'^{}'.format(element_value), event_value): + return True elif element_key.lower() == 'exists': - if element_value and not event_value: - evaluated_result.append(False) - elif not element_value and event_value: - evaluated_result.append(False) - else: - evaluated_result.append(True) + if element_value and event_value: + return True + elif not element_value and not event_value: + return True elif element_key.lower() == 'cidr': ips = [str(ip) for ip in ipaddress.IPv4Network(element_value)] - if event_value not in ips: - evaluated_result.append(False) - else: - evaluated_result.append(True) + if event_value in ips: + return True elif element_key.lower() == 'numeric': - list_of_operators = element_value - check_valid_numeric_content_base_rule(list_of_operators) - for index in range(len(list_of_operators)): - - if list_of_operators[index] == '>' and \ - isinstance(list_of_operators[index + 1], int) and \ - event_value <= list_of_operators[index + 1]: - evaluated_result.append(False) - - elif list_of_operators[index] == '>=' and \ - isinstance(list_of_operators[index + 1], int) and \ - event_value < list_of_operators[index + 1]: - evaluated_result.append(False) - - elif list_of_operators[index] == '<' and \ - isinstance(list_of_operators[index + 1], int) and \ - event_value >= list_of_operators[index + 1]: - evaluated_result.append(False) - - elif list_of_operators[index] == '<=' and \ - isinstance(list_of_operators[index + 1], int) and \ - event_value > list_of_operators[index + 1]: - evaluated_result.append(False) - + if check_valid_numeric_content_base_rule(element_value): + for index in range(len(element_value)): + if isinstance(element_value[index], int): + continue + if element_value[index] == '>' and \ + isinstance(element_value[index + 1], int) and \ + event_value <= element_value[index + 1]: + break + elif element_value[index] == '>=' and \ + isinstance(element_value[index + 1], int) and \ + event_value < element_value[index + 1]: + break + elif element_value[index] == '<' and \ + isinstance(element_value[index + 1], int) and \ + event_value >= element_value[index + 1]: + break + elif element_value[index] == '<=' and \ + isinstance(element_value[index + 1], int) and \ + event_value > element_value[index + 1]: + break else: - evaluated_result.append(True) - index = index + 1 + return True elif element_key.lower() == 'anything-but': if isinstance(element_value, list) and \ - event_value in element_value: - evaluated_result.append(False) - elif (isinstance(element_value, str) or isinstance(element_value, int)) and \ - event_value == element_value: - evaluated_result.append(False) + event_value not in element_value: + return True + elif (isinstance(element_value, (str, int))) and \ + event_value != element_value: + return True elif isinstance(element_value, dict): nested_key = list(element_value)[0] - if nested_key == 'prefix' and re.match(r'^{}'.format(element_value.get(nested_key)), event_value): - evaluated_result.append(False) - else: - evaluated_result.append(True) - else: - evaluated_result.append(True) - else: - evaluated_result.append(True) - if any(evaluated_result) or evaluated_result == []: - return True - elif not all(evaluated_result): - return False + if nested_key == 'prefix' and \ + not re.match(r'^{}'.format(element_value.get(nested_key)), event_value): + return True + return False def check_valid_numeric_content_base_rule(list_of_operators): @@ -348,3 +327,4 @@ def check_valid_numeric_content_base_rule(list_of_operators): if upper_limit and lower_limit and upper_limit < lower_limit: return False index = index + 1 + return True From 72e21a39139a4a17d4887f32bfa48515b9586d4e Mon Sep 17 00:00:00 2001 From: Mohit Date: Thu, 26 Nov 2020 23:32:18 +0530 Subject: [PATCH 4/4] fix: test cases --- tests/integration/test_events.py | 84 ++++++++++++++++---------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/integration/test_events.py b/tests/integration/test_events.py index fe6fe03d5f9ea..7110f82430562 100644 --- a/tests/integration/test_events.py +++ b/tests/integration/test_events.py @@ -113,25 +113,25 @@ def test_put_events_with_target_sqs(self): queue_name = 'queue-{}'.format(short_uid()) rule_name = 'rule-{}'.format(short_uid()) target_id = 'target-{}'.format(short_uid()) - TEST_EVENT_BUS_NAME = 'bus-{}'.format(short_uid()) + bus_name = 'bus-{}'.format(short_uid()) sqs_client = aws_stack.connect_to_service('sqs') queue_url = sqs_client.create_queue(QueueName=queue_name)['QueueUrl'] queue_arn = aws_stack.sqs_queue_arn(queue_name) self.events_client.create_event_bus( - Name=TEST_EVENT_BUS_NAME + Name=bus_name ) self.events_client.put_rule( Name=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, EventPattern=json.dumps(TEST_EVENT_PATTERN) ) rs = self.events_client.put_targets( Rule=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Targets=[ { 'Id': target_id, @@ -147,7 +147,7 @@ def test_put_events_with_target_sqs(self): self.events_client.put_events( Entries=[{ - 'EventBusName': TEST_EVENT_BUS_NAME, + 'EventBusName': bus_name, 'Source': TEST_EVENT_PATTERN['Source'][0], 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) @@ -170,24 +170,24 @@ def get_message(queue_url): self.events_client.remove_targets( Rule=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Ids=[target_id], Force=True ) self.events_client.delete_rule( Name=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Force=True ) self.events_client.delete_event_bus( - Name=TEST_EVENT_BUS_NAME + Name=bus_name ) def test_put_events_with_target_lambda(self): rule_name = 'rule-{}'.format(short_uid()) function_name = 'lambda-func-{}'.format(short_uid()) target_id = 'target-{}'.format(short_uid()) - TEST_EVENT_BUS_NAME = 'bus-{}'.format(short_uid()) + bus_name = 'bus-{}'.format(short_uid()) rs = testutil.create_lambda_function(handler_file=os.path.join(THIS_FOLDER, 'lambdas', 'lambda_echo.py'), func_name=function_name, @@ -196,18 +196,18 @@ def test_put_events_with_target_lambda(self): func_arn = rs['CreateFunctionResponse']['FunctionArn'] self.events_client.create_event_bus( - Name=TEST_EVENT_BUS_NAME + Name=bus_name ) self.events_client.put_rule( Name=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, EventPattern=json.dumps(TEST_EVENT_PATTERN) ) rs = self.events_client.put_targets( Rule=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Targets=[ { 'Id': target_id, @@ -223,7 +223,7 @@ def test_put_events_with_target_lambda(self): self.events_client.put_events( Entries=[{ - 'EventBusName': TEST_EVENT_BUS_NAME, + 'EventBusName': bus_name, 'Source': TEST_EVENT_PATTERN['Source'][0], 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) @@ -242,17 +242,17 @@ def test_put_events_with_target_lambda(self): self.events_client.remove_targets( Rule=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Ids=[target_id], Force=True ) self.events_client.delete_rule( Name=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Force=True ) self.events_client.delete_event_bus( - Name=TEST_EVENT_BUS_NAME + Name=bus_name ) def test_scheduled_expression_events(self): @@ -380,7 +380,7 @@ def test_put_events_with_target_firehose(self): stream_name = 'firehose-{}'.format(short_uid()) rule_name = 'rule-{}'.format(short_uid()) target_id = 'target-{}'.format(short_uid()) - TEST_EVENT_BUS_NAME = 'bus-{}'.format(short_uid()) + bus_name = 'bus-{}'.format(short_uid()) # create firehose target bucket s3_client = aws_stack.connect_to_service('s3') @@ -399,18 +399,18 @@ def test_put_events_with_target_firehose(self): stream_arn = stream['DeliveryStreamARN'] self.events_client.create_event_bus( - Name=TEST_EVENT_BUS_NAME + Name=bus_name ) self.events_client.put_rule( Name=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, EventPattern=json.dumps(TEST_EVENT_PATTERN) ) rs = self.events_client.put_targets( Rule=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Targets=[ { 'Id': target_id, @@ -426,7 +426,7 @@ def test_put_events_with_target_firehose(self): self.events_client.put_events( Entries=[{ - 'EventBusName': TEST_EVENT_BUS_NAME, + 'EventBusName': bus_name, 'Source': TEST_EVENT_PATTERN['Source'][0], 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) @@ -450,17 +450,17 @@ def test_put_events_with_target_firehose(self): self.events_client.remove_targets( Rule=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Ids=[target_id], Force=True ) self.events_client.delete_rule( Name=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Force=True ) self.events_client.delete_event_bus( - Name=TEST_EVENT_BUS_NAME + Name=bus_name ) def test_put_events_with_target_sqs_new_region(self): @@ -502,25 +502,25 @@ def test_put_events_with_input_path(self): queue_name = 'queue-{}'.format(short_uid()) rule_name = 'rule-{}'.format(short_uid()) target_id = 'target-{}'.format(short_uid()) - TEST_EVENT_BUS_NAME = 'bus-{}'.format(short_uid()) + bus_name = 'bus-{}'.format(short_uid()) sqs_client = aws_stack.connect_to_service('sqs') queue_url = sqs_client.create_queue(QueueName=queue_name)['QueueUrl'] queue_arn = aws_stack.sqs_queue_arn(queue_name) self.events_client.create_event_bus( - Name=TEST_EVENT_BUS_NAME + Name=bus_name ) self.events_client.put_rule( Name=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, EventPattern=json.dumps(TEST_EVENT_PATTERN) ) self.events_client.put_targets( Rule=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Targets=[ { 'Id': target_id, @@ -532,7 +532,7 @@ def test_put_events_with_input_path(self): self.events_client.put_events( Entries=[{ - 'EventBusName': TEST_EVENT_BUS_NAME, + 'EventBusName': bus_name, 'Source': TEST_EVENT_PATTERN['Source'][0], 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) @@ -549,7 +549,7 @@ def get_message(queue_url): self.events_client.put_events( Entries=[{ - 'EventBusName': TEST_EVENT_BUS_NAME, + 'EventBusName': bus_name, 'Source': 'dummySource', 'DetailType': TEST_EVENT_PATTERN['detail-type'][0], 'Detail': json.dumps(TEST_EVENT_PATTERN['Detail'][0]) @@ -564,17 +564,17 @@ def get_message(queue_url): self.events_client.remove_targets( Rule=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Ids=[target_id], Force=True ) self.events_client.delete_rule( Name=rule_name, - EventBusName=TEST_EVENT_BUS_NAME, + EventBusName=bus_name, Force=True ) self.events_client.delete_event_bus( - Name=TEST_EVENT_BUS_NAME + Name=bus_name ) def test_put_event_without_source(self): @@ -599,7 +599,7 @@ def test_put_event_with_content_base_rule_in_pattern(self): queue_url = sqs_client.create_queue(QueueName=queue_name)['QueueUrl'] queue_arn = aws_stack.sqs_queue_arn(queue_name) - TEST_EVENT_PATTERN = { + pattern = { 'Source': [{'exists': True}], 'detail-type': [{'prefix': 'core.app'}], 'Detail': json.dumps({ @@ -624,7 +624,7 @@ def test_put_event_with_content_base_rule_in_pattern(self): }) } - EVENT = { + event = { 'EventBusName': TEST_EVENT_BUS_NAME, 'Source': 'core.update-account-command', 'DetailType': 'core.app.backend', @@ -657,7 +657,7 @@ def test_put_event_with_content_base_rule_in_pattern(self): self.events_client.put_rule( Name=rule_name, EventBusName=TEST_EVENT_BUS_NAME, - EventPattern=json.dumps(TEST_EVENT_PATTERN) + EventPattern=json.dumps(pattern) ) self.events_client.put_targets( @@ -672,7 +672,7 @@ def test_put_event_with_content_base_rule_in_pattern(self): ] ) self.events_client.put_events( - Entries=[EVENT] + Entries=[event] ) def get_message(queue_url): @@ -681,14 +681,14 @@ def get_message(queue_url): messages = retry(get_message, retries=3, sleep=1, queue_url=queue_url) self.assertEqual(len(messages), 1) - self.assertEqual(json.loads(messages[0].get('Body')), json.loads(EVENT['Detail'])) + self.assertEqual(json.loads(messages[0].get('Body')), json.loads(event['Detail'])) - EVENT_DETAIL = json.loads(EVENT['Detail']) - EVENT_DETAIL['admins'] = 'not_admin' - EVENT['Detail'] = json.dumps(EVENT_DETAIL) + event_details = json.loads(event['Detail']) + event_details['admins'] = 'not_admin' + event['Detail'] = json.dumps(event_details) self.events_client.put_events( - Entries=[EVENT] + Entries=[event] ) messages = retry(get_message, retries=3, sleep=1, queue_url=queue_url)