diff --git a/src/e3/aws/troposphere/apigateway/__init__.py b/src/e3/aws/troposphere/apigateway/__init__.py index af0b9e9..1bb77db 100644 --- a/src/e3/aws/troposphere/apigateway/__init__.py +++ b/src/e3/aws/troposphere/apigateway/__init__.py @@ -23,7 +23,6 @@ from troposphere import AWSObject from troposphere.certificatemanager import Certificate, DomainValidationOption import json -import re if TYPE_CHECKING: from e3.aws.troposphere import Stack @@ -195,6 +194,9 @@ class _AliasTargetAttributes(TypedDict): DNSName: str HostedZoneId: str + # The default stage name + DEFAULT_STAGE_NAME = "$default" + def __init__( self, name: str, @@ -240,7 +242,9 @@ def __init__( self.authorizers: dict[str, Any] = {} # By default, make sure to have a $default stage self.stages_config = ( - stages_config if stages_config else [StageConfiguration("$default")] + stages_config + if stages_config + else [StageConfiguration(self.DEFAULT_STAGE_NAME)] ) @cached_property @@ -697,6 +701,9 @@ def resources(self, stack: Stack) -> list[AWSObject]: class RestApi(Api): """Rest API support.""" + # Apigateway v1 only allows a-zA-Z0-9_ + DEFAULT_STAGE_NAME = "default" + def __init__( self, name: str, @@ -878,8 +885,7 @@ def declare_stage( DeploymentId=Ref(deployment_name), Description=f"stage {stage_name}", MethodSettings=[method_settings], - # Stage name only allows a-zA-Z0-9_ - StageName=re.sub("[^a-zA-Z0-9_]", "", stage_name), + StageName=stage_name, **parameters, ) ) @@ -948,12 +954,7 @@ def _declare_method( for config in self.stages_config: result.append( awslambda.Permission( - # Retain old behavior for the $default stage - name_to_id( - "{}-{}LambdaPermission".format( - id_prefix, "" if config.name == "$default" else config.name - ) - ), + name_to_id(f"{id_prefix}-{config.name}LambdaPermission"), Action="lambda:InvokeFunction", FunctionName=lambda_arn, Principal="apigateway.amazonaws.com", @@ -1006,11 +1007,7 @@ def _declare_api_mapping( apigateway.BasePathMapping( # Retain old behavior for the $default stage name_to_id( - "{}{}-{}BasePathMapping".format( - self.name, - domain_name.DomainName, - "" if config.name == "$default" else config.name, - ) + f"{self.name}{domain_name.DomainName}-{config.name}BasePathMapping" ), **mapping_params, ) diff --git a/tests/tests_e3_aws/troposphere/apigateway/apigateway_test.py b/tests/tests_e3_aws/troposphere/apigateway/apigateway_test.py index 2584e56..5a94dbe 100644 --- a/tests/tests_e3_aws/troposphere/apigateway/apigateway_test.py +++ b/tests/tests_e3_aws/troposphere/apigateway/apigateway_test.py @@ -529,7 +529,7 @@ def test_rest_api_stages(stack: Stack, lambda_fun: PyFunction) -> None: Method("ANY"), ], stages_config=[ - StageConfiguration("$default"), + StageConfiguration("default"), StageConfiguration( "beta", api_mapping_key="beta", variables={"somevar": "somevalue"} ), @@ -574,7 +574,7 @@ def test_rest_api_lambda_alias(stack: Stack, lambda_fun: PyFunction) -> None: ], stages_config=[ StageConfiguration( - "$default", + "default", lambda_arn_permission=lambda_aliases.blue.ref, variables={"lambdaAlias": lambda_aliases.blue.name}, ), @@ -667,7 +667,7 @@ def test_rest_api_custom_domain_stages(stack: Stack, lambda_fun: PyFunction) -> Method("ANY", authorizer_name="testauthorizer"), ], stages_config=[ - StageConfiguration("$default"), + StageConfiguration("default"), StageConfiguration( "beta", api_mapping_key="beta", variables={"somevar": "somevalue"} ), diff --git a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test.json b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test.json index 0926f11..16abfb8 100644 --- a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test.json +++ b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test.json @@ -45,7 +45,7 @@ }, "TestapiDefaultDeployment": { "Properties": { - "Description": "Deployment resource of $default stage", + "Description": "Deployment resource of default stage", "RestApiId": { "Ref": "Testapi" } @@ -72,7 +72,7 @@ "DeploymentId": { "Ref": "TestapiDefaultDeployment" }, - "Description": "stage $default", + "Description": "stage default", "MethodSettings": [ { "ResourcePath": "/*", @@ -116,7 +116,7 @@ }, "Type": "AWS::ApiGateway::Method" }, - "TestapiANYLambdaPermission": { + "TestapiANYDefaultLambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { @@ -125,7 +125,7 @@ "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/$default/${method}/*", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/default/${method}/*", { "api": { "Ref": "Testapi" diff --git a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_custom_domain.json b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_custom_domain.json index 5d4cf0f..4a4c7a2 100644 --- a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_custom_domain.json +++ b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_custom_domain.json @@ -71,7 +71,7 @@ }, "TestapiDefaultDeployment": { "Properties": { - "Description": "Deployment resource of $default stage", + "Description": "Deployment resource of default stage", "RestApiId": { "Ref": "Testapi" } @@ -98,7 +98,7 @@ "DeploymentId": { "Ref": "TestapiDefaultDeployment" }, - "Description": "stage $default", + "Description": "stage default", "MethodSettings": [ { "ResourcePath": "/*", @@ -145,7 +145,7 @@ }, "Type": "AWS::ApiGateway::Method" }, - "TestapiANYLambdaPermission": { + "TestapiANYDefaultLambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { @@ -154,7 +154,7 @@ "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/$default/${method}/*", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/default/${method}/*", { "api": { "Ref": "Testapi" @@ -188,7 +188,7 @@ }, "Type": "AWS::ApiGateway::DomainName" }, - "TestapiapiexamplecomBasePathMapping": { + "TestapiapiexamplecomDefaultBasePathMapping": { "Properties": { "DomainName": { "Ref": "TestapiapiexamplecomDomain" diff --git a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_custom_domain_stages.json b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_custom_domain_stages.json index 3e6bba8..a09c883 100644 --- a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_custom_domain_stages.json +++ b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_custom_domain_stages.json @@ -71,7 +71,7 @@ }, "TestapiDefaultDeployment": { "Properties": { - "Description": "Deployment resource of $default stage", + "Description": "Deployment resource of default stage", "RestApiId": { "Ref": "Testapi" } @@ -98,7 +98,7 @@ "DeploymentId": { "Ref": "TestapiDefaultDeployment" }, - "Description": "stage $default", + "Description": "stage default", "MethodSettings": [ { "ResourcePath": "/*", @@ -212,7 +212,7 @@ }, "Type": "AWS::Lambda::Permission" }, - "TestapiANYLambdaPermission": { + "TestapiANYDefaultLambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { @@ -221,7 +221,7 @@ "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/$default/${method}/*", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/default/${method}/*", { "api": { "Ref": "Testapi" @@ -255,7 +255,7 @@ }, "Type": "AWS::ApiGateway::DomainName" }, - "TestapiapiexamplecomBasePathMapping": { + "TestapiapiexamplecomDefaultBasePathMapping": { "Properties": { "DomainName": { "Ref": "TestapiapiexamplecomDomain" diff --git a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_lambda_alias.json b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_lambda_alias.json index 3bb7d4f..ac18d39 100644 --- a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_lambda_alias.json +++ b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_lambda_alias.json @@ -91,7 +91,7 @@ }, "TestapiDefaultDeployment": { "Properties": { - "Description": "Deployment resource of $default stage", + "Description": "Deployment resource of default stage", "RestApiId": { "Ref": "Testapi" } @@ -118,7 +118,7 @@ "DeploymentId": { "Ref": "TestapiDefaultDeployment" }, - "Description": "stage $default", + "Description": "stage default", "MethodSettings": [ { "ResourcePath": "/*", @@ -177,7 +177,7 @@ }, "Type": "AWS::Lambda::Permission" }, - "TestapiANYLambdaPermission": { + "TestapiANYDefaultLambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { @@ -186,7 +186,7 @@ "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/$default/${method}/*", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/default/${method}/*", { "api": { "Ref": "Testapi" diff --git a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_nested_resources.json b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_nested_resources.json index 00efe7d..99b437d 100644 --- a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_nested_resources.json +++ b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_nested_resources.json @@ -75,7 +75,7 @@ }, "TestapiDefaultDeployment": { "Properties": { - "Description": "Deployment resource of $default stage", + "Description": "Deployment resource of default stage", "RestApiId": { "Ref": "Testapi" } @@ -104,7 +104,7 @@ "DeploymentId": { "Ref": "TestapiDefaultDeployment" }, - "Description": "stage $default", + "Description": "stage default", "MethodSettings": [ { "ResourcePath": "/*", @@ -208,7 +208,7 @@ }, "Type": "AWS::ApiGateway::Method" }, - "TestapiAccountsANYLambdaPermission": { + "TestapiAccountsANYDefaultLambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { @@ -217,7 +217,7 @@ "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/$default/${method}/accounts", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/default/${method}/accounts", { "api": { "Ref": "Testapi" @@ -229,7 +229,7 @@ }, "Type": "AWS::Lambda::Permission" }, - "TestapiProductsANYLambdaPermission": { + "TestapiProductsANYDefaultLambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { @@ -238,7 +238,7 @@ "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/$default/${method}/products", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/default/${method}/products", { "api": { "Ref": "Testapi" @@ -250,7 +250,7 @@ }, "Type": "AWS::Lambda::Permission" }, - "TestapiProductsAbcdANYLambdaPermission": { + "TestapiProductsAbcdANYDefaultLambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { @@ -259,7 +259,7 @@ "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/$default/${method}/products/abcd", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/default/${method}/products/abcd", { "api": { "Ref": "Testapi" diff --git a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_stages.json b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_stages.json index ea08f6d..1335b15 100644 --- a/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_stages.json +++ b/tests/tests_e3_aws/troposphere/apigateway/apigatewayv1_test_stages.json @@ -91,7 +91,7 @@ }, "TestapiDefaultDeployment": { "Properties": { - "Description": "Deployment resource of $default stage", + "Description": "Deployment resource of default stage", "RestApiId": { "Ref": "Testapi" } @@ -118,7 +118,7 @@ "DeploymentId": { "Ref": "TestapiDefaultDeployment" }, - "Description": "stage $default", + "Description": "stage default", "MethodSettings": [ { "ResourcePath": "/*", @@ -183,7 +183,7 @@ }, "Type": "AWS::Lambda::Permission" }, - "TestapiANYLambdaPermission": { + "TestapiANYDefaultLambdaPermission": { "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { @@ -192,7 +192,7 @@ "Principal": "apigateway.amazonaws.com", "SourceArn": { "Fn::Sub": [ - "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/$default/${method}/*", + "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${api}/default/${method}/*", { "api": { "Ref": "Testapi"