Skip to content

Commit

Permalink
fix: supporting nested apis for v1 method, integration, and integrati…
Browse files Browse the repository at this point in the history
…on response resources. (#5712)
  • Loading branch information
moelasmar authored Aug 4, 2023
1 parent 6733ccd commit 8d67f0d
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 36 deletions.
56 changes: 38 additions & 18 deletions samcli/hook_packages/terraform/hooks/prepare/resource_linking.py
Original file line number Diff line number Diff line change
Expand Up @@ -1205,9 +1205,16 @@ def _link_gateway_resource_to_gateway_resource_call_back(
return

logical_id = referenced_gateway_resource_values[0]
gateway_resource_cfn_resource["Properties"]["ResourceId"] = (
{"Ref": logical_id.value} if isinstance(logical_id, LogicalIdReference) else logical_id.value
)
if isinstance(logical_id, LogicalIdReference):
if logical_id.resource_type == TF_AWS_API_GATEWAY_REST_API:
gateway_resource_cfn_resource["Properties"]["ResourceId"] = {
"Fn::GetAtt": [logical_id.value, "RootResourceId"]
}
else:
gateway_resource_cfn_resource["Properties"]["ResourceId"] = {"Ref": logical_id.value}

else:
gateway_resource_cfn_resource["Properties"]["ResourceId"] = logical_id.value


def _link_gateway_resource_to_parent_resource_call_back(
Expand Down Expand Up @@ -1330,7 +1337,7 @@ def _link_gateway_stage_to_rest_api(
def _link_gateway_method_to_gateway_resource(
gateway_method_config_resources: Dict[str, TFResource],
gateway_method_config_address_cfn_resources_map: Dict[str, List],
gateway_resources_terraform_resources: Dict[str, Dict],
gateway_resources_or_rest_apis_terraform_resources: Dict[str, Dict],
):
"""
Iterate through all the resources and link the corresponding
Expand All @@ -1342,8 +1349,8 @@ def _link_gateway_method_to_gateway_resource(
Dictionary of configuration Gateway Methods
gateway_method_config_address_cfn_resources_map: Dict[str, List]
Dictionary containing resolved configuration addresses matched up to the cfn Gateway Stage
gateway_resources_terraform_resources: Dict[str, Dict]
Dictionary of all actual terraform Rest API resources (not configuration resources).
gateway_resources_or_rest_apis_terraform_resources: Dict[str, Dict]
Dictionary of all actual terraform Rest API or gateway resource resources (not configuration resources).
The dictionary's key is the calculated logical id for each resource.
"""
exceptions = ResourcePairExceptions(
Expand All @@ -1353,12 +1360,16 @@ def _link_gateway_method_to_gateway_resource(
resource_linking_pair = ResourceLinkingPair(
source_resource_cfn_resource=gateway_method_config_address_cfn_resources_map,
source_resource_tf_config=gateway_method_config_resources,
destination_resource_tf=gateway_resources_terraform_resources,
destination_resource_tf=gateway_resources_or_rest_apis_terraform_resources,
expected_destinations=[
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_RESOURCE_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="id",
),
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_REST_API_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="root_resource_id",
),
],
terraform_link_field_name="resource_id",
cfn_link_field_name="ResourceId",
Expand Down Expand Up @@ -1412,7 +1423,7 @@ def _link_gateway_integrations_to_gateway_rest_apis(
def _link_gateway_integrations_to_gateway_resource(
gateway_integrations_config_resources: Dict[str, TFResource],
gateway_integrations_config_address_cfn_resources_map: Dict[str, List],
gateway_resources_terraform_resources: Dict[str, Dict],
gateway_resources_or_rest_apis_terraform_resources: Dict[str, Dict],
):
"""
Iterate through all the resources and link the corresponding
Expand All @@ -1424,9 +1435,9 @@ def _link_gateway_integrations_to_gateway_resource(
Dictionary of configuration Gateway Integrations
gateway_integrations_config_address_cfn_resources_map: Dict[str, List]
Dictionary containing resolved configuration addresses matched up to the cfn Gateway Integration
gateway_resources_terraform_resources: Dict[str, Dict]
Dictionary of all actual terraform Rest API resources (not configuration resources). The dictionary's key is the
calculated logical id for each resource.
gateway_resources_or_rest_apis_terraform_resources: Dict[str, Dict]
Dictionary of all actual terraform Rest API or gateway resource resources (not configuration resources). The
dictionary's key is the calculated logical id for each resource.
"""

exceptions = ResourcePairExceptions(
Expand All @@ -1436,12 +1447,16 @@ def _link_gateway_integrations_to_gateway_resource(
resource_linking_pair = ResourceLinkingPair(
source_resource_cfn_resource=gateway_integrations_config_address_cfn_resources_map,
source_resource_tf_config=gateway_integrations_config_resources,
destination_resource_tf=gateway_resources_terraform_resources,
destination_resource_tf=gateway_resources_or_rest_apis_terraform_resources,
expected_destinations=[
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_RESOURCE_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="id",
),
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_REST_API_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="root_resource_id",
),
],
terraform_link_field_name="resource_id",
cfn_link_field_name="ResourceId",
Expand Down Expand Up @@ -1579,10 +1594,11 @@ def _link_gateway_integration_responses_to_gateway_rest_apis(
def _link_gateway_integration_responses_to_gateway_resource(
gateway_integration_responses_config_resources: Dict[str, TFResource],
gateway_integration_responses_config_address_cfn_resources_map: Dict[str, List],
gateway_resources_terraform_resources: Dict[str, Dict],
gateway_resources_or_rest_apis_terraform_resources: Dict[str, Dict],
):
"""
Iterate through all the resources and link the corresponding Gateway Resource resource to each Gateway Integration
Iterate through all the resour
ces and link the corresponding Gateway Resource resource to each Gateway Integration
Response resource.
Parameters
----------
Expand All @@ -1591,9 +1607,9 @@ def _link_gateway_integration_responses_to_gateway_resource(
gateway_integration_responses_config_address_cfn_resources_map: Dict[str, List]
Dictionary containing resolved configuration addresses matched up to the internal mapped cfn Gateway
Integration Response.
gateway_resources_terraform_resources: Dict[str, Dict]
Dictionary of all actual terraform Rest API resources (not configuration resources). The dictionary's key is the
calculated logical id for each resource.
gateway_resources_or_rest_apis_terraform_resources: Dict[str, Dict]
Dictionary of all actual terraform Rest API or gateway resource resources (not configuration resources). The
dictionary's key is the calculated logical id for each resource.
"""

exceptions = ResourcePairExceptions(
Expand All @@ -1603,12 +1619,16 @@ def _link_gateway_integration_responses_to_gateway_resource(
resource_linking_pair = ResourceLinkingPair(
source_resource_cfn_resource=gateway_integration_responses_config_address_cfn_resources_map,
source_resource_tf_config=gateway_integration_responses_config_resources,
destination_resource_tf=gateway_resources_terraform_resources,
destination_resource_tf=gateway_resources_or_rest_apis_terraform_resources,
expected_destinations=[
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_RESOURCE_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="id",
),
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_REST_API_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="root_resource_id",
),
],
terraform_link_field_name="resource_id",
cfn_link_field_name="ResourceId",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,11 @@
LinkingPairCaller(
source=TF_AWS_API_GATEWAY_STAGE, dest=TF_AWS_API_GATEWAY_REST_API, linking_func=_link_gateway_stage_to_rest_api
),
LinkingPairCaller(
source=TF_AWS_API_GATEWAY_METHOD,
dest=TF_AWS_API_GATEWAY_RESOURCE,
linking_func=_link_gateway_method_to_gateway_resource,
),
LinkingPairCaller(
source=TF_AWS_API_GATEWAY_INTEGRATION,
dest=TF_AWS_API_GATEWAY_REST_API,
linking_func=_link_gateway_integrations_to_gateway_rest_apis,
),
LinkingPairCaller(
source=TF_AWS_API_GATEWAY_INTEGRATION,
dest=TF_AWS_API_GATEWAY_RESOURCE,
linking_func=_link_gateway_integrations_to_gateway_resource,
),
LinkingPairCaller(
source=TF_AWS_API_GATEWAY_INTEGRATION,
dest=TF_AWS_LAMBDA_FUNCTION,
Expand All @@ -74,11 +64,6 @@
dest=TF_AWS_API_GATEWAY_REST_API,
linking_func=_link_gateway_integration_responses_to_gateway_rest_apis,
),
LinkingPairCaller(
source=TF_AWS_API_GATEWAY_INTEGRATION_RESPONSE,
dest=TF_AWS_API_GATEWAY_RESOURCE,
linking_func=_link_gateway_integration_responses_to_gateway_resource,
),
LinkingPairCaller(
source=TF_AWS_API_GATEWAY_AUTHORIZER,
dest=TF_AWS_LAMBDA_FUNCTION,
Expand All @@ -102,4 +87,19 @@
destinations=[TF_AWS_API_GATEWAY_REST_API, TF_AWS_API_GATEWAY_RESOURCE],
linking_func=_link_gateway_resources_to_parents,
),
LinkingMultipleDestinationsOptionsCaller(
source=TF_AWS_API_GATEWAY_METHOD,
destinations=[TF_AWS_API_GATEWAY_REST_API, TF_AWS_API_GATEWAY_RESOURCE],
linking_func=_link_gateway_method_to_gateway_resource,
),
LinkingMultipleDestinationsOptionsCaller(
source=TF_AWS_API_GATEWAY_INTEGRATION,
destinations=[TF_AWS_API_GATEWAY_REST_API, TF_AWS_API_GATEWAY_RESOURCE],
linking_func=_link_gateway_integrations_to_gateway_resource,
),
LinkingMultipleDestinationsOptionsCaller(
source=TF_AWS_API_GATEWAY_INTEGRATION_RESPONSE,
destinations=[TF_AWS_API_GATEWAY_REST_API, TF_AWS_API_GATEWAY_RESOURCE],
linking_func=_link_gateway_integration_responses_to_gateway_resource,
),
]
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def tearDownClass(cls) -> None:
[
{
"terraform_application": "terraform-v1-nested-apis",
"testing_urls": ["parent/hello", "parent"],
"testing_urls": ["", "parent/hello", "parent"],
},
{
"terraform_application": "terraform-v1-api-simple",
Expand Down Expand Up @@ -185,7 +185,7 @@ def test_unsupported_limitations(self):
[
{
"terraform_application": "terraform-v1-nested-apis",
"testing_urls": ["parent/hello", "parent"],
"testing_urls": ["", "parent/hello", "parent"],
},
{
"terraform_application": "terraform-v1-api-simple",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ resource "aws_api_gateway_integration" "MyDemoIntegration" {
depends_on = [aws_api_gateway_method.GetMethod]
}

resource "aws_api_gateway_method_response" "MyDemoIntegration_response_200" {
rest_api_id = aws_api_gateway_rest_api.MyDemoAPI.id
resource_id = aws_api_gateway_resource.ChildResource.id
http_method = aws_api_gateway_method.GetMethod.http_method
status_code = "200"
}

resource "aws_api_gateway_method" "ParentResource_GetMethod" {
rest_api_id = aws_api_gateway_rest_api.MyDemoAPI.id
resource_id = aws_api_gateway_resource.ParentResource.id
Expand All @@ -141,3 +148,35 @@ resource "aws_api_gateway_integration" "ParentResource_GetMethod_Integration" {
uri = aws_lambda_function.HelloWorldFunction.invoke_arn
depends_on = [aws_api_gateway_method.ParentResource_GetMethod]
}

resource "aws_api_gateway_method_response" "ParentResource_GetMethod_Integration_response_200" {
rest_api_id = aws_api_gateway_rest_api.MyDemoAPI.id
resource_id = aws_api_gateway_resource.ParentResource.id
http_method = aws_api_gateway_method.ParentResource_GetMethod.http_method
status_code = "200"
}

resource "aws_api_gateway_method" "API_GetMethod" {
rest_api_id = aws_api_gateway_rest_api.MyDemoAPI.id
resource_id = aws_api_gateway_rest_api.MyDemoAPI.root_resource_id
http_method = "GET"
authorization = "NONE"
}

resource "aws_api_gateway_integration" "API_GetMethod_Integration" {
rest_api_id = aws_api_gateway_rest_api.MyDemoAPI.id
resource_id = aws_api_gateway_rest_api.MyDemoAPI.root_resource_id
http_method = aws_api_gateway_method.ParentResource_GetMethod.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
content_handling = "CONVERT_TO_TEXT"
uri = aws_lambda_function.HelloWorldFunction.invoke_arn
depends_on = [aws_api_gateway_method.ParentResource_GetMethod]
}

resource "aws_api_gateway_method_response" "API_GetMethod_Integration_response_200" {
rest_api_id = aws_api_gateway_rest_api.MyDemoAPI.id
resource_id = aws_api_gateway_rest_api.MyDemoAPI.root_resource_id
http_method = aws_api_gateway_method.ParentResource_GetMethod.http_method
status_code = "200"
}
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,10 @@ def test_link_gateway_methods_to_gateway_resources(
terraform_resource_type_prefix=API_GATEWAY_RESOURCE_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="id",
),
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_REST_API_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="root_resource_id",
),
],
terraform_link_field_name="resource_id",
cfn_link_field_name="ResourceId",
Expand Down Expand Up @@ -1957,6 +1961,10 @@ def test_link_gateway_integrations_to_gateway_resource(
terraform_resource_type_prefix=API_GATEWAY_RESOURCE_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="id",
),
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_REST_API_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="root_resource_id",
),
],
terraform_link_field_name="resource_id",
cfn_link_field_name="ResourceId",
Expand Down Expand Up @@ -2072,6 +2080,14 @@ def test_link_gateway_methods_to_gateway_rest_apis_call_back(
[LogicalIdReference(value="Resource1", resource_type=TF_AWS_API_GATEWAY_RESOURCE)],
{"Ref": "Resource1"},
),
(
{
"Type": "AWS::ApiGateway::Method",
"Properties": {"HttpMethod": "post"},
},
[LogicalIdReference(value="api1", resource_type=TF_AWS_API_GATEWAY_REST_API)],
{"Fn::GetAtt": ["api1", "RootResourceId"]},
),
]
)
def test_link_gateway_method_to_gateway_resource_call_back(
Expand Down Expand Up @@ -2108,9 +2124,17 @@ def test_link_gateway_method_to_gateway_resource_call_back(
[LogicalIdReference(value="RestApi", resource_type=TF_AWS_API_GATEWAY_REST_API)],
{"Fn::GetAtt": ["RestApi", "RootResourceId"]},
),
(
{
"Type": "AWS::ApiGateway::Resource",
"Properties": {},
},
[LogicalIdReference(value="resource1", resource_type=TF_AWS_API_GATEWAY_RESOURCE)],
{"Ref": "resource1"},
),
]
)
def test_link_gateway_resource_to_gateway_rest_api_parent_id_call_back(
def test_link_gateway_resource_to_parent_resource_call_back(
self, input_gateway_resource, logical_ids, expected_rest_api
):
gateway_resource = deepcopy(input_gateway_resource)
Expand Down Expand Up @@ -2280,6 +2304,10 @@ def test_link_gateway_integration_response_to_gateway_resource(
terraform_resource_type_prefix=API_GATEWAY_RESOURCE_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="id",
),
ResourcePairExceptedDestination(
terraform_resource_type_prefix=API_GATEWAY_REST_API_RESOURCE_ADDRESS_PREFIX,
terraform_attribute_name="root_resource_id",
),
],
terraform_link_field_name="resource_id",
cfn_link_field_name="ResourceId",
Expand Down

0 comments on commit 8d67f0d

Please sign in to comment.