From e35dbca854b724aea2cd1d9f7cf7bd584be8265c Mon Sep 17 00:00:00 2001 From: Ahmed Elbayaa Date: Tue, 23 Feb 2021 12:58:16 -0800 Subject: [PATCH 1/3] Raise an InvalidEventException if api-event's properties is not a dictionalry --- .../plugins/api/implicit_http_api_plugin.py | 4 ++++ .../plugins/api/implicit_rest_api_plugin.py | 3 +++ .../input/error_function_invalid_api_event.yaml | 11 +++++++++++ .../input/error_implicit_http_api_properties.yaml | 12 ++++++++++++ .../output/error_function_invalid_api_event.json | 4 ++-- .../output/error_implicit_http_api_properties.json | 8 ++++++++ tests/translator/test_translator.py | 1 + 7 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/translator/input/error_implicit_http_api_properties.yaml create mode 100644 tests/translator/output/error_implicit_http_api_properties.json diff --git a/samtranslator/plugins/api/implicit_http_api_plugin.py b/samtranslator/plugins/api/implicit_http_api_plugin.py index 3f8849dbc1..29a4fba605 100644 --- a/samtranslator/plugins/api/implicit_http_api_plugin.py +++ b/samtranslator/plugins/api/implicit_http_api_plugin.py @@ -57,6 +57,10 @@ def _process_api_events(self, function, api_events, template, condition=None): for logicalId, event in api_events.items(): # api_events only contains HttpApi events event_properties = event.get("Properties", {}) + + if event_properties and not isinstance(event_properties, dict): + raise InvalidEventException(logicalId, "Event Properties is invalid.") + if not event_properties: event["Properties"] = event_properties self._add_implicit_api_id_if_necessary(event_properties) diff --git a/samtranslator/plugins/api/implicit_rest_api_plugin.py b/samtranslator/plugins/api/implicit_rest_api_plugin.py index 3a6461928c..b972a38973 100644 --- a/samtranslator/plugins/api/implicit_rest_api_plugin.py +++ b/samtranslator/plugins/api/implicit_rest_api_plugin.py @@ -63,6 +63,9 @@ def _process_api_events(self, function, api_events, template, condition=None): if not event_properties: continue + if not isinstance(event_properties, dict): + raise InvalidEventException(logicalId, "Event Properties is invalid.") + self._add_implicit_api_id_if_necessary(event_properties) api_id = self._get_api_id(event_properties) diff --git a/tests/translator/input/error_function_invalid_api_event.yaml b/tests/translator/input/error_function_invalid_api_event.yaml index 98b7aa5f01..03a98c2a04 100644 --- a/tests/translator/input/error_function_invalid_api_event.yaml +++ b/tests/translator/input/error_function_invalid_api_event.yaml @@ -1,4 +1,15 @@ Resources: + FunctionApiInvalidProperties: + Type: 'AWS::Serverless::Function' + Properties: + CodeUri: s3://sam-demo-bucket/hello.zip + Handler: hello.handler + Runtime: python2.7 + Events: + ApiEvent: + Type: Api + Properties: '/hello' # NOTE: Should be an object no a string + FunctionApiNoMethod: Type: 'AWS::Serverless::Function' Properties: diff --git a/tests/translator/input/error_implicit_http_api_properties.yaml b/tests/translator/input/error_implicit_http_api_properties.yaml new file mode 100644 index 0000000000..33770f00d1 --- /dev/null +++ b/tests/translator/input/error_implicit_http_api_properties.yaml @@ -0,0 +1,12 @@ +Resources: + HttpApiFunction: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://sam-demo-bucket/todo_list.zip + Handler: index.restapi + Runtime: nodejs12.x + Policies: AmazonDynamoDBFullAccess + Events: + Basic: + Type: HttpApi + Properties: /basic diff --git a/tests/translator/output/error_function_invalid_api_event.json b/tests/translator/output/error_function_invalid_api_event.json index 01b123ed8e..ebaf259a98 100644 --- a/tests/translator/output/error_function_invalid_api_event.json +++ b/tests/translator/output/error_function_invalid_api_event.json @@ -4,5 +4,5 @@ "errorMessage": "Resource with id [FunctionApiNoMethod] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Path'." } ], - "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 4. Resource with id [FunctionApiMethodArray] is invalid. Event with id [ApiEvent] is invalid. Api Event must have a String specified for 'Method'. Resource with id [FunctionApiNoMethod] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Method'. Resource with id [FunctionApiNoPath] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Path'. Resource with id [FunctionApiPathArray] is invalid. Event with id [ApiEvent] is invalid. Api Event must have a String specified for 'Path'." -} \ No newline at end of file + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 5. Resource with id [FunctionApiInvalidProperties] is invalid. Event with id [ApiEvent] is invalid. Event Properties is invalid. Resource with id [FunctionApiMethodArray] is invalid. Event with id [ApiEvent] is invalid. Api Event must have a String specified for 'Method'. Resource with id [FunctionApiNoMethod] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Method'. Resource with id [FunctionApiNoPath] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Path'. Resource with id [FunctionApiPathArray] is invalid. Event with id [ApiEvent] is invalid. Api Event must have a String specified for 'Path'." +} diff --git a/tests/translator/output/error_implicit_http_api_properties.json b/tests/translator/output/error_implicit_http_api_properties.json new file mode 100644 index 0000000000..e99710ce43 --- /dev/null +++ b/tests/translator/output/error_implicit_http_api_properties.json @@ -0,0 +1,8 @@ +{ + "errors": [ + { + "errorMessage": "Resource with id [HttpApiFunction] is invalid. Event with id [Basic] is invalid. Event Properties is invalid." + } + ], + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [HttpApiFunction] is invalid. Event with id [Basic] is invalid. Event Properties is invalid." +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index 07f2016023..541fbaf62c 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -675,6 +675,7 @@ def _generate_new_deployment_hash(self, logical_id, dict_to_hash, rest_api_to_sw "error_http_api_invalid_openapi", "error_http_api_tags", "error_http_api_tags_def_uri", + "error_implicit_http_api_properties", "error_implicit_http_api_method", "error_implicit_http_api_path", "error_http_api_event_multiple_same_path", From 6290345648cedc9a61b653e460eef198c8674aaf Mon Sep 17 00:00:00 2001 From: Ahmed Elbayaa Date: Tue, 23 Feb 2021 20:59:45 -0800 Subject: [PATCH 2/3] Make a cleaner error message --- samtranslator/plugins/api/implicit_http_api_plugin.py | 5 ++++- samtranslator/plugins/api/implicit_rest_api_plugin.py | 5 ++++- .../translator/output/error_function_invalid_api_event.json | 2 +- .../output/error_implicit_http_api_properties.json | 6 +++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/samtranslator/plugins/api/implicit_http_api_plugin.py b/samtranslator/plugins/api/implicit_http_api_plugin.py index 29a4fba605..e19cf20d4c 100644 --- a/samtranslator/plugins/api/implicit_http_api_plugin.py +++ b/samtranslator/plugins/api/implicit_http_api_plugin.py @@ -59,7 +59,10 @@ def _process_api_events(self, function, api_events, template, condition=None): event_properties = event.get("Properties", {}) if event_properties and not isinstance(event_properties, dict): - raise InvalidEventException(logicalId, "Event Properties is invalid.") + raise InvalidEventException( + logicalId, + "Event 'Properties' must be an Object. " "If you're using YAML, this may be an indentation issue.", + ) if not event_properties: event["Properties"] = event_properties diff --git a/samtranslator/plugins/api/implicit_rest_api_plugin.py b/samtranslator/plugins/api/implicit_rest_api_plugin.py index b972a38973..92ecf8d86d 100644 --- a/samtranslator/plugins/api/implicit_rest_api_plugin.py +++ b/samtranslator/plugins/api/implicit_rest_api_plugin.py @@ -64,7 +64,10 @@ def _process_api_events(self, function, api_events, template, condition=None): continue if not isinstance(event_properties, dict): - raise InvalidEventException(logicalId, "Event Properties is invalid.") + raise InvalidEventException( + logicalId, + "Event 'Properties' must be an Object. If you're using YAML, this may be an indentation issue.", + ) self._add_implicit_api_id_if_necessary(event_properties) diff --git a/tests/translator/output/error_function_invalid_api_event.json b/tests/translator/output/error_function_invalid_api_event.json index ebaf259a98..48027216a9 100644 --- a/tests/translator/output/error_function_invalid_api_event.json +++ b/tests/translator/output/error_function_invalid_api_event.json @@ -4,5 +4,5 @@ "errorMessage": "Resource with id [FunctionApiNoMethod] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Path'." } ], - "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 5. Resource with id [FunctionApiInvalidProperties] is invalid. Event with id [ApiEvent] is invalid. Event Properties is invalid. Resource with id [FunctionApiMethodArray] is invalid. Event with id [ApiEvent] is invalid. Api Event must have a String specified for 'Method'. Resource with id [FunctionApiNoMethod] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Method'. Resource with id [FunctionApiNoPath] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Path'. Resource with id [FunctionApiPathArray] is invalid. Event with id [ApiEvent] is invalid. Api Event must have a String specified for 'Path'." + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 5. Resource with id [FunctionApiInvalidProperties] is invalid. Event with id [ApiEvent] is invalid. Event 'Properties' must be an Object. If you're using YAML, this may be an indentation issue. Resource with id [FunctionApiMethodArray] is invalid. Event with id [ApiEvent] is invalid. Api Event must have a String specified for 'Method'. Resource with id [FunctionApiNoMethod] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Method'. Resource with id [FunctionApiNoPath] is invalid. Event with id [ApiEvent] is invalid. Event is missing key 'Path'. Resource with id [FunctionApiPathArray] is invalid. Event with id [ApiEvent] is invalid. Api Event must have a String specified for 'Path'." } diff --git a/tests/translator/output/error_implicit_http_api_properties.json b/tests/translator/output/error_implicit_http_api_properties.json index e99710ce43..833d80e03f 100644 --- a/tests/translator/output/error_implicit_http_api_properties.json +++ b/tests/translator/output/error_implicit_http_api_properties.json @@ -1,8 +1,8 @@ { "errors": [ { - "errorMessage": "Resource with id [HttpApiFunction] is invalid. Event with id [Basic] is invalid. Event Properties is invalid." + "errorMessage": "Resource with id [HttpApiFunction] is invalid. Event with id [Basic] is invalid. Event 'Properties' must be an Object. If you're using YAML, this may be an indentation issue." } ], - "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [HttpApiFunction] is invalid. Event with id [Basic] is invalid. Event Properties is invalid." -} \ No newline at end of file + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [HttpApiFunction] is invalid. Event with id [Basic] is invalid. Event 'Properties' must be an Object. If you're using YAML, this may be an indentation issue." +} From ca59c89e0d2926954e3d442ec0d9162871937204 Mon Sep 17 00:00:00 2001 From: Ahmed Elbayaa Date: Tue, 23 Feb 2021 21:01:57 -0800 Subject: [PATCH 3/3] typo --- samtranslator/plugins/api/implicit_http_api_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samtranslator/plugins/api/implicit_http_api_plugin.py b/samtranslator/plugins/api/implicit_http_api_plugin.py index e19cf20d4c..83c078ea15 100644 --- a/samtranslator/plugins/api/implicit_http_api_plugin.py +++ b/samtranslator/plugins/api/implicit_http_api_plugin.py @@ -61,7 +61,7 @@ def _process_api_events(self, function, api_events, template, condition=None): if event_properties and not isinstance(event_properties, dict): raise InvalidEventException( logicalId, - "Event 'Properties' must be an Object. " "If you're using YAML, this may be an indentation issue.", + "Event 'Properties' must be an Object. If you're using YAML, this may be an indentation issue.", ) if not event_properties: