Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: openapiversion bails if it is not a string #1104

Merged
merged 1 commit into from
Sep 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions samtranslator/model/api/api_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from collections import namedtuple
from six import string_types
import re

from samtranslator.model.intrinsics import ref
from samtranslator.model.apigateway import (ApiGatewayDeployment, ApiGatewayRestApi,
ApiGatewayStage, ApiGatewayAuthorizer,
Expand Down Expand Up @@ -107,9 +105,10 @@ def _construct_rest_api(self):
"Specify either 'DefinitionUri' or 'DefinitionBody' property and not both")

if self.open_api_version:
if re.match(SwaggerEditor.get_openapi_versions_supported_regex(), self.open_api_version) is None:
raise InvalidResourceException(
self.logical_id, "The OpenApiVersion value must be of the format 3.0.0")
if not SwaggerEditor.safe_compare_regex_with_string(SwaggerEditor.get_openapi_versions_supported_regex(),
self.open_api_version):
raise InvalidResourceException(self.logical_id,
"The OpenApiVersion value must be of the format \"3.0.0\"")

self._add_cors()
self._add_auth()
Expand Down Expand Up @@ -412,11 +411,12 @@ def _openapi_postprocess(self, definition_body):
if definition_body.get('swagger') is not None:
return definition_body

if definition_body.get('openapi') is not None:
if self.open_api_version is None:
self.open_api_version = definition_body.get('openapi')
if definition_body.get('openapi') is not None and self.open_api_version is None:
self.open_api_version = definition_body.get('openapi')

if self.open_api_version and re.match(SwaggerEditor.get_openapi_version_3_regex(), self.open_api_version):
if self.open_api_version and \
SwaggerEditor.safe_compare_regex_with_string(SwaggerEditor.get_openapi_version_3_regex(),
self.open_api_version):
if definition_body.get('securityDefinitions'):
components = definition_body.get('components', {})
components['securitySchemes'] = definition_body['securityDefinitions']
Expand Down
9 changes: 6 additions & 3 deletions samtranslator/plugins/globals/globals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from samtranslator.public.sdk.resource import SamResourceType
from samtranslator.public.intrinsics import is_intrinsics
from samtranslator.swagger.swagger import SwaggerEditor
import re
from six import string_types


class Globals(object):
Expand Down Expand Up @@ -135,8 +135,11 @@ def fix_openapi_definitions(cls, template):
if ("Type" in resource) and (resource["Type"] == cls._API_TYPE):
properties = resource["Properties"]
if (cls._OPENAPIVERSION in properties) and (cls._MANAGE_SWAGGER in properties) and \
(re.match(SwaggerEditor.get_openapi_version_3_regex(),
properties[cls._OPENAPIVERSION]) is not None):
SwaggerEditor.safe_compare_regex_with_string(
SwaggerEditor.get_openapi_version_3_regex(), properties[cls._OPENAPIVERSION]):
if not isinstance(properties[cls._OPENAPIVERSION], string_types):
properties[cls._OPENAPIVERSION] = str(properties[cls._OPENAPIVERSION])
resource["Properties"] = properties
if "DefinitionBody" in properties:
definition_body = properties['DefinitionBody']
definition_body['openapi'] = properties[cls._OPENAPIVERSION]
Expand Down
12 changes: 8 additions & 4 deletions samtranslator/swagger/swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -740,8 +740,8 @@ def add_request_model_to_method(self, path, method_name, request_model):
method_definition['parameters'] = existing_parameters

elif self._doc.get("openapi") and \
re.search(SwaggerEditor.get_openapi_version_3_regex(), self._doc["openapi"]) is not None:

SwaggerEditor.safe_compare_regex_with_string(
SwaggerEditor.get_openapi_version_3_regex(), self._doc["openapi"]):
method_definition['requestBody'] = {
'content': {
"application/json": {
Expand Down Expand Up @@ -901,8 +901,8 @@ def is_valid(data):
if bool(data.get("swagger")):
return True
elif bool(data.get("openapi")):
return re.search(SwaggerEditor.get_openapi_version_3_regex(), data["openapi"]) is not None
return False
return SwaggerEditor.safe_compare_regex_with_string(
SwaggerEditor.get_openapi_version_3_regex(), data["openapi"])
return False

@staticmethod
Expand Down Expand Up @@ -951,3 +951,7 @@ def get_openapi_versions_supported_regex():
def get_openapi_version_3_regex():
openapi_version_3_regex = r"\A3(\.\d)(\.\d)?$"
return openapi_version_3_regex

@staticmethod
def safe_compare_regex_with_string(regex, data):
return re.match(regex, str(data)) is not None
1 change: 0 additions & 1 deletion samtranslator/translator/translator.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import copy

from samtranslator.model import ResourceTypeResolver, sam_resources
from samtranslator.translator.verify_logical_id import verify_unique_logical_id
from samtranslator.model.preferences.deployment_preference_collection import DeploymentPreferenceCollection
Expand Down
2 changes: 1 addition & 1 deletion tests/translator/input/api_request_model_openapi_3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Resources:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
OpenApiVersion: '3.0.1'
OpenApiVersion: 3.0
Models:
User:
type: object
Expand Down
2 changes: 1 addition & 1 deletion tests/translator/input/api_with_open_api_version.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Globals:
Api:
OpenApiVersion: '3.0.1'
OpenApiVersion: 3.0.1
Cors: '*'

Resources:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Resources:
MyApi:
Type: AWS::Serverless::Api
Properties:
DefinitionBody: {}
OpenApiVersion: 3
StageName: 'prod'
Function:
Type: AWS::Serverless::Function
Properties:
Handler: lambda.handler
CodeUri: s3://bucket/api
Runtime: nodejs8.10
Events:
ProxyApiRoot:
Type: Api
Properties:
RestApiId:
Ref: MyApi
Path: "/"
Method: ANY
22 changes: 11 additions & 11 deletions tests/translator/output/api_request_model_openapi_3.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@
}
}
},
"HtmlApiDeploymentefb667b26e": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "HtmlApi"
},
"Description": "RestApi deployment id: efb667b26e8a0b0f733f5dfc27d039c1a2867db0"
}
},
"HtmlFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down Expand Up @@ -58,7 +49,7 @@
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "HtmlApiDeploymentefb667b26e"
"Ref": "HtmlApiDeployment59eeb787ee"
},
"RestApiId": {
"Ref": "HtmlApi"
Expand Down Expand Up @@ -149,7 +140,7 @@
}
}
},
"openapi": "3.0.1",
"openapi": "3.0",
"components": {
"securitySchemes": {
"AWS_IAM": {
Expand All @@ -173,6 +164,15 @@
}
}
},
"HtmlApiDeployment59eeb787ee": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "HtmlApi"
},
"Description": "RestApi deployment id: 59eeb787ee1561329a07e10162ac3718998e9f91"
}
},
"HtmlFunctionGetHtmlPermissionTest": {
"Type": "AWS::Lambda::Permission",
"Properties": {
Expand Down
22 changes: 11 additions & 11 deletions tests/translator/output/aws-cn/api_request_model_openapi_3.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
{
"Resources": {
"HtmlApiDeployment5ae7e42cea": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "HtmlApi"
},
"Description": "RestApi deployment id: 5ae7e42cea0640a3318bf508535850cd792a52dc"
}
},
"HtmlFunctionIamPermissionTest": {
"Type": "AWS::Lambda::Permission",
"Properties": {
Expand All @@ -21,15 +30,6 @@
}
}
},
"HtmlApiDeploymentbe02cbff83": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "HtmlApi"
},
"Description": "RestApi deployment id: be02cbff831c2acb5672650bc54b204366bef429"
}
},
"HtmlFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down Expand Up @@ -58,7 +58,7 @@
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "HtmlApiDeploymentbe02cbff83"
"Ref": "HtmlApiDeployment5ae7e42cea"
},
"RestApiId": {
"Ref": "HtmlApi"
Expand Down Expand Up @@ -149,7 +149,7 @@
}
}
},
"openapi": "3.0.1",
"openapi": "3.0",
"components": {
"securitySchemes": {
"AWS_IAM": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@
}
}
},
"HtmlApiDeploymente91bc94e87": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "HtmlApi"
},
"Description": "RestApi deployment id: e91bc94e874a30084312552d628dd248890ad7f9"
}
},
"HtmlFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down Expand Up @@ -58,7 +49,7 @@
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "HtmlApiDeploymente91bc94e87"
"Ref": "HtmlApiDeploymenta488cfa4f9"
},
"RestApiId": {
"Ref": "HtmlApi"
Expand Down Expand Up @@ -149,7 +140,7 @@
}
}
},
"openapi": "3.0.1",
"openapi": "3.0",
"components": {
"securitySchemes": {
"AWS_IAM": {
Expand Down Expand Up @@ -181,6 +172,15 @@
}
}
},
"HtmlApiDeploymenta488cfa4f9": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "HtmlApi"
},
"Description": "RestApi deployment id: a488cfa4f9c73604187a3a5dfa5f333ef2c52e1e"
}
},
"HtmlFunctionGetHtmlPermissionTest": {
"Type": "AWS::Lambda::Permission",
"Properties": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"errors": [
{
"errorMessage": "Resource with id [MyApi] is invalid. The OpenApiVersion value must be of the format 3.0.0"
"errorMessage": "Resource with id [MyApi] is invalid. The OpenApiVersion value must be of the format \"3.0.0\""
}
],
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [MyApi] is invalid. The OpenApiVersion value must be of the format 3.0.0"
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [MyApi] is invalid. The OpenApiVersion value must be of the format \"3.0.0\""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"errors": [
{
"errorMessage": "Resource with id [MyApi] is invalid. Type of property 'OpenApiVersion' is invalid."
}
],
"errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [MyApi] is invalid. Type of property 'OpenApiVersion' is invalid."
}
3 changes: 2 additions & 1 deletion tests/translator/test_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,8 @@ def _generate_new_deployment_hash(self, logical_id, dict_to_hash, rest_api_to_sw
'error_function_with_unknown_policy_template',
'error_function_with_invalid_policy_statement',
'error_function_with_invalid_condition_name',
'error_invalid_document_empty_semantic_version'
'error_invalid_document_empty_semantic_version',
'error_api_with_invalid_open_api_version_type'
])
@patch('boto3.session.Session.region_name', 'ap-southeast-1')
@patch('samtranslator.plugins.application.serverless_app_plugin.ServerlessAppPlugin._sar_service_call', mock_sar_service_call)
Expand Down