import boto3 import sure # noqa # pylint: disable=unused-import import pytest from botocore.client import ClientError from moto import mock_ec2, settings from uuid import uuid4 @mock_ec2 def test_launch_template_create(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) resp = cli.create_launch_template( LaunchTemplateName=template_name, # the absolute minimum needed to create a template without other resources LaunchTemplateData={ "TagSpecifications": [ { "ResourceType": "instance", "Tags": [{"Key": "test", "Value": "value"}], } ] }, ) resp.should.have.key("LaunchTemplate") lt = resp["LaunchTemplate"] lt["LaunchTemplateName"].should.equal(template_name) lt["DefaultVersionNumber"].should.equal(1) lt["LatestVersionNumber"].should.equal(1) with pytest.raises(ClientError) as ex: cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={ "TagSpecifications": [ { "ResourceType": "instance", "Tags": [{"Key": "test", "Value": "value"}], } ] }, ) str(ex.value).should.equal( "An error occurred (InvalidLaunchTemplateName.AlreadyExistsException) when calling the CreateLaunchTemplate operation: Launch template name already in use." ) @mock_ec2 def test_describe_launch_template_versions(): template_data = { "ImageId": "ami-abc123", "DisableApiTermination": False, "TagSpecifications": [ {"ResourceType": "instance", "Tags": [{"Key": "test", "Value": "value"}]} ], "SecurityGroupIds": ["sg-1234", "sg-ab5678"], } cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) create_resp = cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData=template_data ) # test using name resp = cli.describe_launch_template_versions( LaunchTemplateName=template_name, Versions=["1"] ) templ = resp["LaunchTemplateVersions"][0]["LaunchTemplateData"] templ.should.equal(template_data) # test using id resp = cli.describe_launch_template_versions( LaunchTemplateId=create_resp["LaunchTemplate"]["LaunchTemplateId"], Versions=["1"], ) templ = resp["LaunchTemplateVersions"][0]["LaunchTemplateData"] templ.should.equal(template_data) # test using $Latest version resp = cli.describe_launch_template_versions( LaunchTemplateName=template_name, Versions=["$Latest"] ) templ = resp["LaunchTemplateVersions"][0]["LaunchTemplateData"] templ.should.equal(template_data) # test using $Default version resp = cli.describe_launch_template_versions( LaunchTemplateName=template_name, Versions=["$Default"] ) templ = resp["LaunchTemplateVersions"][0]["LaunchTemplateData"] templ.should.equal(template_data) @mock_ec2 def test_describe_launch_template_versions_by_name_when_absent(): cli = boto3.client("ec2", region_name="us-east-1") template_name = "foo" # test using name with pytest.raises( ClientError, match=f"The specified launch template, with template name {template_name}, does not exist", ): cli.describe_launch_template_versions(LaunchTemplateName=template_name) @mock_ec2 def test_create_launch_template_version(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) create_resp = cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) version_resp = cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-def456"}, VersionDescription="new ami", ) version_resp.should.have.key("LaunchTemplateVersion") version = version_resp["LaunchTemplateVersion"] version["DefaultVersion"].should.equal(False) version["LaunchTemplateId"].should.equal( create_resp["LaunchTemplate"]["LaunchTemplateId"] ) version["VersionDescription"].should.equal("new ami") version["VersionNumber"].should.equal(2) @mock_ec2 def test_create_launch_template_version_by_id(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) create_resp = cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) version_resp = cli.create_launch_template_version( LaunchTemplateId=create_resp["LaunchTemplate"]["LaunchTemplateId"], LaunchTemplateData={"ImageId": "ami-def456"}, VersionDescription="new ami", ) version_resp.should.have.key("LaunchTemplateVersion") version = version_resp["LaunchTemplateVersion"] version["DefaultVersion"].should.equal(False) version["LaunchTemplateId"].should.equal( create_resp["LaunchTemplate"]["LaunchTemplateId"] ) version["VersionDescription"].should.equal("new ami") version["VersionNumber"].should.equal(2) @mock_ec2 def test_describe_launch_template_versions_with_multiple_versions(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-def456"}, VersionDescription="new ami", ) resp = cli.describe_launch_template_versions(LaunchTemplateName=template_name) resp["LaunchTemplateVersions"].should.have.length_of(2) resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal( "ami-abc123" ) resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal( "ami-def456" ) @mock_ec2 def test_describe_launch_template_versions_with_versions_option(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-def456"}, VersionDescription="new ami", ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-hij789"}, VersionDescription="new ami, again", ) resp = cli.describe_launch_template_versions( LaunchTemplateName=template_name, Versions=["2", "3"] ) resp["LaunchTemplateVersions"].should.have.length_of(2) resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal( "ami-def456" ) resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal( "ami-hij789" ) @mock_ec2 def test_describe_launch_template_versions_with_min(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-def456"}, VersionDescription="new ami", ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-hij789"}, VersionDescription="new ami, again", ) resp = cli.describe_launch_template_versions( LaunchTemplateName=template_name, MinVersion="2" ) resp["LaunchTemplateVersions"].should.have.length_of(2) resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal( "ami-def456" ) resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal( "ami-hij789" ) @mock_ec2 def test_describe_launch_template_versions_with_max(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-def456"}, VersionDescription="new ami", ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-hij789"}, VersionDescription="new ami, again", ) resp = cli.describe_launch_template_versions( LaunchTemplateName=template_name, MaxVersion="2" ) resp["LaunchTemplateVersions"].should.have.length_of(2) resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal( "ami-abc123" ) resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal( "ami-def456" ) @mock_ec2 def test_describe_launch_template_versions_with_min_and_max(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-def456"}, VersionDescription="new ami", ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-hij789"}, VersionDescription="new ami, again", ) cli.create_launch_template_version( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-345abc"}, VersionDescription="new ami, because why not", ) resp = cli.describe_launch_template_versions( LaunchTemplateName=template_name, MinVersion="2", MaxVersion="3" ) resp["LaunchTemplateVersions"].should.have.length_of(2) resp["LaunchTemplateVersions"][0]["LaunchTemplateData"]["ImageId"].should.equal( "ami-def456" ) resp["LaunchTemplateVersions"][1]["LaunchTemplateData"]["ImageId"].should.equal( "ami-hij789" ) @mock_ec2 def test_describe_launch_templates_with_non_existent_name(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) with pytest.raises(ClientError) as ex: cli.describe_launch_templates(LaunchTemplateNames=[template_name]) str(ex.value).should.equal( "An error occurred (InvalidLaunchTemplateName.NotFoundException) when calling the DescribeLaunchTemplates operation: At least one of the launch templates specified in the request does not exist." ) @mock_ec2 def test_describe_launch_templates(): cli = boto3.client("ec2", region_name="us-east-1") lt_ids = [] template_name = str(uuid4()) r = cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) lt_ids.append(r["LaunchTemplate"]["LaunchTemplateId"]) template_name2 = str(uuid4()) r = cli.create_launch_template( LaunchTemplateName=template_name2, LaunchTemplateData={"ImageId": "ami-abc123"} ) lt_ids.append(r["LaunchTemplate"]["LaunchTemplateId"]) # general call, all templates if not settings.TEST_SERVER_MODE: # Bug: Only 15 launch templates are returned, ever # ServerMode may have many more templates, created in parallel all_templates = retrieve_all_templates(cli) my_templates = [t for t in all_templates if t["LaunchTemplateId"] in lt_ids] my_templates[0]["LaunchTemplateName"].should.equal(template_name) my_templates[1]["LaunchTemplateName"].should.equal(template_name2) # filter by names resp = cli.describe_launch_templates( LaunchTemplateNames=[template_name2, template_name] ) resp.should.have.key("LaunchTemplates") resp["LaunchTemplates"].should.have.length_of(2) resp["LaunchTemplates"][0]["LaunchTemplateName"].should.equal(template_name2) resp["LaunchTemplates"][1]["LaunchTemplateName"].should.equal(template_name) # filter by ids resp = cli.describe_launch_templates(LaunchTemplateIds=lt_ids) resp.should.have.key("LaunchTemplates") resp["LaunchTemplates"].should.have.length_of(2) resp["LaunchTemplates"][0]["LaunchTemplateName"].should.equal(template_name) resp["LaunchTemplates"][1]["LaunchTemplateName"].should.equal(template_name2) @mock_ec2 def test_describe_launch_templates_with_filters(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) r = cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) tag_value = str(uuid4()) cli.create_tags( Resources=[r["LaunchTemplate"]["LaunchTemplateId"]], Tags=[ {"Key": "tag1", "Value": tag_value}, {"Key": "another-key", "Value": "this value"}, ], ) template_name_no_tags = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name_no_tags, LaunchTemplateData={"ImageId": "ami-abc123"}, ) resp = cli.describe_launch_templates( Filters=[{"Name": "tag:tag1", "Values": [tag_value]}] ) resp["LaunchTemplates"].should.have.length_of(1) resp["LaunchTemplates"][0]["LaunchTemplateName"].should.equal(template_name) resp = cli.describe_launch_templates( Filters=[{"Name": "launch-template-name", "Values": [template_name_no_tags]}] ) resp["LaunchTemplates"].should.have.length_of(1) resp["LaunchTemplates"][0]["LaunchTemplateName"].should.equal(template_name_no_tags) @mock_ec2 def test_create_launch_template_with_tag_spec(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"}, TagSpecifications=[ {"ResourceType": "instance", "Tags": [{"Key": "key", "Value": "value"}]} ], ) resp = cli.describe_launch_template_versions( LaunchTemplateName=template_name, Versions=["1"] ) version = resp["LaunchTemplateVersions"][0] version["LaunchTemplateData"].should.have.key("TagSpecifications") version["LaunchTemplateData"]["TagSpecifications"].should.have.length_of(1) version["LaunchTemplateData"]["TagSpecifications"][0].should.equal( {"ResourceType": "instance", "Tags": [{"Key": "key", "Value": "value"}]} ) @mock_ec2 def test_delete_launch_template__dryrun(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"}, TagSpecifications=[ {"ResourceType": "instance", "Tags": [{"Key": "key", "Value": "value"}]} ], ) cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ "LaunchTemplates" ].should.have.length_of(1) with pytest.raises(ClientError) as exc: cli.delete_launch_template(DryRun=True, LaunchTemplateName=template_name) err = exc.value.response["Error"] err.should.have.key("Code").equals("DryRunOperation") # Template still exists cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ "LaunchTemplates" ].should.have.length_of(1) @mock_ec2 def test_delete_launch_template__by_name(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"ImageId": "ami-abc123"} ) cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ "LaunchTemplates" ].should.have.length_of(1) cli.delete_launch_template(LaunchTemplateName=template_name) 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 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"] cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ "LaunchTemplates" ].should.have.length_of(1) cli.delete_launch_template(LaunchTemplateId=template_id) 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 resp = client.describe_launch_templates(Filters=filters) all_templates = resp["LaunchTemplates"] next_token = resp.get("NextToken") while next_token: resp = client.describe_launch_templates(Filters=filters, NextToken=next_token) all_templates.extend(resp["LaunchTemplates"]) next_token = resp.get("NextToken") return all_templates @mock_ec2 def test_launch_template_create_with_tags(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) resp = cli.create_launch_template( LaunchTemplateName=template_name, # the absolute minimum needed to create a template without other resources LaunchTemplateData={ "TagSpecifications": [ { "ResourceType": "instance", "Tags": [{"Key": "test", "Value": "value"}], } ] }, TagSpecifications=[ { "ResourceType": "launch-template", "Tags": [{"Key": "test1", "Value": "value1"}], } ], ) resp.should.have.key("LaunchTemplate") lt = resp["LaunchTemplate"] lt["LaunchTemplateName"].should.equal(template_name) lt["DefaultVersionNumber"].should.equal(1) lt["LatestVersionNumber"].should.equal(1) lt["Tags"].should.have.length_of(1) lt["Tags"][0].should.equal({"Key": "test1", "Value": "value1"}) @mock_ec2 def test_launch_template_describe_with_tags(): cli = boto3.client("ec2", region_name="us-east-1") template_name = str(uuid4()) cli.create_launch_template( LaunchTemplateName=template_name, # the absolute minimum needed to create a template without other resources LaunchTemplateData={ "TagSpecifications": [ { "ResourceType": "instance", "Tags": [{"Key": "test", "Value": "value"}], } ] }, TagSpecifications=[ { "ResourceType": "launch-template", "Tags": [{"Key": "test1", "Value": "value1"}], } ], ) lt = cli.describe_launch_templates(LaunchTemplateNames=[template_name])[ "LaunchTemplates" ][0] lt["LaunchTemplateName"].should.equal(template_name) lt["DefaultVersionNumber"].should.equal(1) lt["LatestVersionNumber"].should.equal(1) lt["Tags"].should.have.length_of(1) lt["Tags"][0].should.equal({"Key": "test1", "Value": "value1"})