From 08c65a9a3c0e9ff9bf225720349b48ac685ebebe Mon Sep 17 00:00:00 2001 From: Viren Nadkarni Date: Fri, 2 Dec 2022 18:47:06 +0530 Subject: [PATCH] EC2: fix launch template names not being reusable after delete (#5726) --- moto/ec2/models/launch_templates.py | 11 +++++- tests/test_ec2/test_ec2_cloudformation.py | 10 +++-- tests/test_ec2/test_launch_templates.py | 45 ++++++++++++++++++++--- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/moto/ec2/models/launch_templates.py b/moto/ec2/models/launch_templates.py index 69ecf9def..488813043 100644 --- a/moto/ec2/models/launch_templates.py +++ b/moto/ec2/models/launch_templates.py @@ -12,6 +12,7 @@ from ..exceptions import ( InvalidLaunchTemplateNameAlreadyExistsError, InvalidLaunchTemplateNameNotFoundError, InvalidLaunchTemplateNameNotFoundWithNameError, + MissingParameterError, ) @@ -189,8 +190,14 @@ class LaunchTemplateBackend: def delete_launch_template(self, name, tid): if name: - tid = self.launch_template_name_to_ids[name] - return self.launch_templates.pop(tid) + tid = self.launch_template_name_to_ids.get(name) + if tid is None: + raise MissingParameterError("launch template ID or launch template name") + if tid not in self.launch_templates: + raise InvalidLaunchTemplateNameNotFoundError() + template = self.launch_templates.pop(tid) + self.launch_template_name_to_ids.pop(template.name, None) + return template def describe_launch_templates( self, template_names=None, template_ids=None, filters=None diff --git a/tests/test_ec2/test_ec2_cloudformation.py b/tests/test_ec2/test_ec2_cloudformation.py index a3120f663..7b29f6734 100644 --- a/tests/test_ec2/test_ec2_cloudformation.py +++ b/tests/test_ec2/test_ec2_cloudformation.py @@ -938,6 +938,10 @@ def test_launch_template_delete(): cf.delete_stack(StackName=stack_name) - ec2.describe_launch_templates(LaunchTemplateNames=[launch_template_name])[ - "LaunchTemplates" - ].should.have.length_of(0) + with pytest.raises(ClientError) as exc: + ec2.describe_launch_templates(LaunchTemplateNames=[launch_template_name]) + err = exc.value.response["Error"] + err.should.have.key("Code").equals("InvalidLaunchTemplateName.NotFoundException") + err.should.have.key("Message").equals( + "At least one of the launch templates specified in the request does not exist." + ) diff --git a/tests/test_ec2/test_launch_templates.py b/tests/test_ec2/test_launch_templates.py index f6142b0a3..1133ee229 100644 --- a/tests/test_ec2/test_launch_templates.py +++ b/tests/test_ec2/test_launch_templates.py @@ -482,9 +482,21 @@ def test_delete_launch_template__by_name(): cli.delete_launch_template(LaunchTemplateName=template_name) - cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ - "LaunchTemplates" - ].should.have.length_of(0) + with pytest.raises(ClientError) as exc: + cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ + "LaunchTemplates" + ] + err = exc.value.response["Error"] + err.should.have.key("Code").equals("InvalidLaunchTemplateName.NotFoundException") + err.should.have.key("Message").equals( + "At least one of the launch templates specified in the request does not exist." + ) + + # Ensure deleted template name can be reused + cli.create_launch_template( + LaunchTemplateName=template_name, + LaunchTemplateData={"ImageId": "ami-abc123"}, + ) @mock_ec2 @@ -492,6 +504,15 @@ def test_delete_launch_template__by_id(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) + + with pytest.raises(ClientError) as exc: + cli.delete_launch_template() + err = exc.value.response["Error"] + err.should.have.key("Code").equals("MissingParameter") + err.should.have.key("Message").equals( + "The request must contain the parameter launch template ID or launch template name" + ) + template_id = cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} )["LaunchTemplate"]["LaunchTemplateId"] @@ -502,9 +523,21 @@ def test_delete_launch_template__by_id(): cli.delete_launch_template(LaunchTemplateId=template_id) - cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ - "LaunchTemplates" - ].should.have.length_of(0) + with pytest.raises(ClientError) as exc: + cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ + "LaunchTemplates" + ] + err = exc.value.response["Error"] + err.should.have.key("Code").equals("InvalidLaunchTemplateName.NotFoundException") + err.should.have.key("Message").equals( + "At least one of the launch templates specified in the request does not exist." + ) + + # Ensure deleted template name can be reused + cli.create_launch_template( + LaunchTemplateName=template_name, + LaunchTemplateData={"ImageId": "ami-abc123"}, + ) def retrieve_all_templates(client, filters=[]): # pylint: disable=W0102