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: Ensure template output is actually parsable data #6005

Merged
merged 3 commits into from
Oct 3, 2023
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
6 changes: 6 additions & 0 deletions samcli/lib/delete/cfn_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Delete Cloudformation stacks and s3 files
"""

import json
import logging
from typing import List, Optional

Expand Down Expand Up @@ -110,6 +111,11 @@ def get_stack_template(self, stack_name: str, stage: str) -> str:
)
template = resp.get("TemplateBody", "")

# template variable can be of type string or of type dict which does not return
# nicely as a string, so it is dumped instead
if isinstance(template, dict):
return json.dumps(template)

return str(template)

except (ClientError, BotoCoreError) as e:
Expand Down
21 changes: 21 additions & 0 deletions tests/integration/delete/test_delete_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,27 @@ def test_delete_stack_review_in_progress(self):
self.validate_delete_process(delete_result)
self._validate_stack_deleted(stack_name=stack_name)

def test_delete_stack_with_companion_ecr_stack(self):
test_folder = self.delete_test_data_path.joinpath("companion-ecr")

stack_name = self._method_to_stack_name(self.id())

build_command = self.get_minimal_build_command_list()
deploy_command = self.get_deploy_command_list(stack_name=stack_name)
delete_command = self.get_delete_command_list(stack_name=stack_name)

run_command(build_command, cwd=test_folder)
run_command(deploy_command, cwd=test_folder)
result = run_command_with_input(delete_command, "y\ny\ny\n".encode(), cwd=test_folder)

self.validate_delete_process(result)
self._validate_stack_deleted(stack_name=stack_name)

output = str(result.stdout)

self.assertIn("Deleting ECR Companion Stack", output)
self.assertIn("Deleting ECR repository", output)

def validate_delete_process(self, command_result: CommandResult):
self.assertEqual(command_result.process.returncode, 0)
self.assertNotIn(b"Could not find and delete the S3 object with the key", command_result.stderr)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM public.ecr.aws/lambda/python:3.8

COPY requirements.txt ./
RUN python3.8 -m pip install -r requirements.txt -t .

COPY app.py ./

# Command can be overwritten by providing a different command in the template directly.
CMD ["app.lambda_handler"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import json


def lambda_handler(event, context):
return {
"statusCode": 200,
"body": json.dumps(
{
"message": "hello world",
}
),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: 0.1
default:
deploy:
parameters:
resolve_image_repos: true
resolve_s3: true
confirm_changeset: false
capabilities:
- "CAPABILITY_IAM"
14 changes: 14 additions & 0 deletions tests/integration/testdata/delete/companion-ecr/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
Architectures:
- x86_64
Metadata:
Dockerfile: Dockerfile
DockerContext: ./hello_world
DockerTag: python3.8-v1
13 changes: 13 additions & 0 deletions tests/unit/lib/delete/test_cfn_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,16 @@ def test_get_change_set_reraises_exceptions(self, caught_exception):

with self.assertRaises(FetchTemplateFailedError):
self.cf_utils.get_stack_template(MagicMock(), MagicMock())

@parameterized.expand(
[
({"hello": "world"}, '{"hello": "world"}'),
("hello world", "hello world"),
]
)
def test_cf_utils_get_stack_template_returns_correct_string(self, template_response, expected_string):
self.cf_utils._client.get_template = MagicMock()
self.cf_utils._client.get_template.return_value = {"TemplateBody": template_response}

output_template = self.cf_utils.get_stack_template("test", "Original")
self.assertEqual(output_template, expected_string)
Loading