diff --git a/samtranslator/model/api/api_generator.py b/samtranslator/model/api/api_generator.py index b9fe23e4d..1dd6f436e 100644 --- a/samtranslator/model/api/api_generator.py +++ b/samtranslator/model/api/api_generator.py @@ -535,13 +535,13 @@ def _construct_api_domain( # noqa: PLR0912, PLR0915 self._set_optional_domain_properties(domain) - basepaths: Optional[List[str]] + basepaths: Optional[List[Any]] basepath_value = self.domain.get("BasePath") # Create BasepathMappings - if self.domain.get("BasePath") and isinstance(basepath_value, str): + if isinstance(basepath_value, str) or is_intrinsic(basepath_value): basepaths = [basepath_value] - elif self.domain.get("BasePath") and isinstance(basepath_value, list): - basepaths = cast(Optional[List[Any]], basepath_value) + elif isinstance(basepath_value, list): + basepaths = basepath_value else: basepaths = None @@ -554,13 +554,19 @@ def _construct_api_domain( # noqa: PLR0912, PLR0915 basepath_mapping = self._create_basepath_mapping(api_domain_name, rest_api, None, None) basepath_resource_list.extend([basepath_mapping]) else: - sam_expect(basepaths, self.logical_id, "Domain.BasePath").to_be_a_list_of(ExpectedType.STRING) + if not is_intrinsic(basepaths[0]): + sam_expect(basepaths, self.logical_id, "Domain.BasePath").to_be_a_list_of(ExpectedType.STRING) for basepath in basepaths: - # Remove possible leading and trailing '/' because a base path may only - # contain letters, numbers, and one of "$-_.+!*'()" - path = "".join(e for e in basepath if e.isalnum()) - mapping_basepath = path if normalize_basepath else basepath - logical_id = "{}{}{}".format(self.logical_id, path, "BasePathMapping") + if is_intrinsic(basepath): + mapping_basepath = basepath + logical_id = self.logical_id + "BasePathMapping" + else: + # Remove possible leading and trailing '/' because a base path may only + # contain letters, numbers, and one of "$-_.+!*'()" + path = "".join(e for e in basepath if e.isalnum()) + mapping_basepath = path if normalize_basepath else basepath + logical_id = "{}{}{}".format(self.logical_id, path, "BasePathMapping") + basepath_mapping = self._create_basepath_mapping( api_domain_name, rest_api, logical_id, mapping_basepath ) @@ -810,7 +816,7 @@ def _create_basepath_mapping( api_domain_name: PassThrough, rest_api: ApiGatewayRestApi, logical_id: Optional[str], - basepath: Optional[str], + basepath: Optional[Any], ) -> ApiGatewayBasePathMapping: basepath_mapping: ApiGatewayBasePathMapping diff --git a/tests/translator/input/api_with_basic_custom_domain_intrinsics.yaml b/tests/translator/input/api_with_basic_custom_domain_intrinsics.yaml index f2350ea83..bcf820139 100644 --- a/tests/translator/input/api_with_basic_custom_domain_intrinsics.yaml +++ b/tests/translator/input/api_with_basic_custom_domain_intrinsics.yaml @@ -58,7 +58,7 @@ Resources: DomainName: !Sub 'example-${AWS::Region}.com' CertificateArn: !Ref MyDomainCert EndpointConfiguration: !Ref EndpointConf - BasePath: [/get, /fetch] + BasePath: !Sub '${AWS::Region}-api' MutualTlsAuthentication: TruststoreUri: !Ref MyMTLSUri TruststoreVersion: !Ref MyMTLSVersion diff --git a/tests/translator/output/api_with_basic_custom_domain_intrinsics.json b/tests/translator/output/api_with_basic_custom_domain_intrinsics.json index 69df9e3fc..890a76422 100644 --- a/tests/translator/output/api_with_basic_custom_domain_intrinsics.json +++ b/tests/translator/output/api_with_basic_custom_domain_intrinsics.json @@ -99,33 +99,12 @@ }, "Type": "AWS::ApiGateway::RestApi" }, - "MyApiDeployment19c8cf5c63": { + "MyApiBasePathMapping": { "Condition": "C1", "Properties": { - "Description": "RestApi deployment id: 19c8cf5c63090f12c5a96f6f57162495bed446c7", - "RestApiId": { - "Ref": "MyApi" - } - }, - "Type": "AWS::ApiGateway::Deployment" - }, - "MyApiProdStage": { - "Condition": "C1", - "Properties": { - "DeploymentId": { - "Ref": "MyApiDeployment19c8cf5c63" + "BasePath": { + "Fn::Sub": "ap-southeast-1-api" }, - "RestApiId": { - "Ref": "MyApi" - }, - "StageName": "Prod" - }, - "Type": "AWS::ApiGateway::Stage" - }, - "MyApifetchBasePathMapping": { - "Condition": "C1", - "Properties": { - "BasePath": "fetch", "DomainName": { "Ref": "ApiGatewayDomainNamec0ed6fae34" }, @@ -138,21 +117,28 @@ }, "Type": "AWS::ApiGateway::BasePathMapping" }, - "MyApigetBasePathMapping": { + "MyApiDeployment651fe13005": { "Condition": "C1", "Properties": { - "BasePath": "get", - "DomainName": { - "Ref": "ApiGatewayDomainNamec0ed6fae34" + "Description": "RestApi deployment id: 651fe13005fac4c7c7f2fe93b77c7ef2c6c3e746", + "RestApiId": { + "Ref": "MyApi" + } + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "MyApiProdStage": { + "Condition": "C1", + "Properties": { + "DeploymentId": { + "Ref": "MyApiDeployment651fe13005" }, "RestApiId": { "Ref": "MyApi" }, - "Stage": { - "Ref": "MyApiProdStage" - } + "StageName": "Prod" }, - "Type": "AWS::ApiGateway::BasePathMapping" + "Type": "AWS::ApiGateway::Stage" }, "MyFunction": { "Condition": "C1", diff --git a/tests/translator/output/aws-cn/api_with_basic_custom_domain_intrinsics.json b/tests/translator/output/aws-cn/api_with_basic_custom_domain_intrinsics.json index 230575039..354aa9d9d 100644 --- a/tests/translator/output/aws-cn/api_with_basic_custom_domain_intrinsics.json +++ b/tests/translator/output/aws-cn/api_with_basic_custom_domain_intrinsics.json @@ -107,33 +107,12 @@ }, "Type": "AWS::ApiGateway::RestApi" }, - "MyApiDeployment4f2c19d290": { + "MyApiBasePathMapping": { "Condition": "C1", "Properties": { - "Description": "RestApi deployment id: 4f2c19d290875d88d8e30124f0953f1784e1b54d", - "RestApiId": { - "Ref": "MyApi" - } - }, - "Type": "AWS::ApiGateway::Deployment" - }, - "MyApiProdStage": { - "Condition": "C1", - "Properties": { - "DeploymentId": { - "Ref": "MyApiDeployment4f2c19d290" + "BasePath": { + "Fn::Sub": "cn-north-1-api" }, - "RestApiId": { - "Ref": "MyApi" - }, - "StageName": "Prod" - }, - "Type": "AWS::ApiGateway::Stage" - }, - "MyApifetchBasePathMapping": { - "Condition": "C1", - "Properties": { - "BasePath": "fetch", "DomainName": { "Ref": "ApiGatewayDomainNamec0cd2d9dfc" }, @@ -146,21 +125,28 @@ }, "Type": "AWS::ApiGateway::BasePathMapping" }, - "MyApigetBasePathMapping": { + "MyApiDeploymente1e3e9b849": { "Condition": "C1", "Properties": { - "BasePath": "get", - "DomainName": { - "Ref": "ApiGatewayDomainNamec0cd2d9dfc" + "Description": "RestApi deployment id: e1e3e9b849803f87115b2cb8fcdf5d144342aaa4", + "RestApiId": { + "Ref": "MyApi" + } + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "MyApiProdStage": { + "Condition": "C1", + "Properties": { + "DeploymentId": { + "Ref": "MyApiDeploymente1e3e9b849" }, "RestApiId": { "Ref": "MyApi" }, - "Stage": { - "Ref": "MyApiProdStage" - } + "StageName": "Prod" }, - "Type": "AWS::ApiGateway::BasePathMapping" + "Type": "AWS::ApiGateway::Stage" }, "MyFunction": { "Condition": "C1", diff --git a/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_intrinsics.json b/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_intrinsics.json index 142c16774..3538689e3 100644 --- a/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_intrinsics.json +++ b/tests/translator/output/aws-us-gov/api_with_basic_custom_domain_intrinsics.json @@ -107,33 +107,12 @@ }, "Type": "AWS::ApiGateway::RestApi" }, - "MyApiDeployment32e59613e2": { + "MyApiBasePathMapping": { "Condition": "C1", "Properties": { - "Description": "RestApi deployment id: 32e59613e2e02a1f1d264849167ea359f10342f0", - "RestApiId": { - "Ref": "MyApi" - } - }, - "Type": "AWS::ApiGateway::Deployment" - }, - "MyApiProdStage": { - "Condition": "C1", - "Properties": { - "DeploymentId": { - "Ref": "MyApiDeployment32e59613e2" + "BasePath": { + "Fn::Sub": "us-gov-west-1-api" }, - "RestApiId": { - "Ref": "MyApi" - }, - "StageName": "Prod" - }, - "Type": "AWS::ApiGateway::Stage" - }, - "MyApifetchBasePathMapping": { - "Condition": "C1", - "Properties": { - "BasePath": "fetch", "DomainName": { "Ref": "ApiGatewayDomainName9c93aac102" }, @@ -146,21 +125,28 @@ }, "Type": "AWS::ApiGateway::BasePathMapping" }, - "MyApigetBasePathMapping": { + "MyApiDeployment9d140ab9b8": { "Condition": "C1", "Properties": { - "BasePath": "get", - "DomainName": { - "Ref": "ApiGatewayDomainName9c93aac102" + "Description": "RestApi deployment id: 9d140ab9b8b8ee141d5cd2d4a90a374c37a10db7", + "RestApiId": { + "Ref": "MyApi" + } + }, + "Type": "AWS::ApiGateway::Deployment" + }, + "MyApiProdStage": { + "Condition": "C1", + "Properties": { + "DeploymentId": { + "Ref": "MyApiDeployment9d140ab9b8" }, "RestApiId": { "Ref": "MyApi" }, - "Stage": { - "Ref": "MyApiProdStage" - } + "StageName": "Prod" }, - "Type": "AWS::ApiGateway::BasePathMapping" + "Type": "AWS::ApiGateway::Stage" }, "MyFunction": { "Condition": "C1",