EC2 - Pass LaunchTemplate tags to new Instances (#5085)

This commit is contained in:
Bert Blommers 2022-05-01 19:27:25 +00:00 committed by GitHub
parent 6b70cd1b6b
commit 3b68be55d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 28 deletions

View File

@ -725,20 +725,6 @@ class BaseResponse(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
return results
def _parse_tag_specification(self):
# [{"ResourceType": _type, "Tag": [{"Key": k, "Value": v}, ..]}]
tag_spec = self._get_multi_param("TagSpecification")
# {_type: {k: v, ..}}
tags = {}
for spec in tag_spec:
if spec["ResourceType"] not in tags:
tags[spec["ResourceType"]] = {}
tags[spec["ResourceType"]].update(
{tag["Key"]: tag["Value"] for tag in spec["Tag"]}
)
return tags
def _get_object_map(self, prefix, name="Name", value="Value"):
"""
Given a query dict like

View File

@ -22,6 +22,7 @@ from ..utils import (
random_reservation_id,
filter_reservations,
utc_date_and_time,
convert_tag_spec,
)
@ -70,6 +71,13 @@ class Instance(TaggedEC2Resource, BotoInstance, CloudFormationModel):
self.image_id = template_version.image_id
else:
self.image_id = image_id
# Check if we have tags to process
if launch_template_arg:
template_version = ec2_backend._get_template_from_args(launch_template_arg)
tag_spec_set = template_version.data.get("TagSpecification", {})
tags = convert_tag_spec(tag_spec_set)
instance_tags = tags.get("instance", {})
self.add_tags(instance_tags)
self._state = InstanceState("running", 16)
self._reason = ""

View File

@ -11,6 +11,7 @@ from ..utils import (
random_spot_fleet_request_id,
random_spot_request_id,
generic_filter,
convert_tag_spec,
)
@ -249,7 +250,8 @@ class SpotFleetRequest(TaggedEC2Resource, CloudFormationModel):
launch_specs_from_config.append(new_launch_template)
for spec in (launch_specs or []) + launch_specs_from_config:
tags = self._extract_tags(spec)
tag_spec_set = spec.get("TagSpecificationSet", [])
tags = convert_tag_spec(tag_spec_set)
self.launch_specs.append(
SpotFleetLaunchSpec(
ebs_optimized=spec.get("EbsOptimized"),
@ -270,19 +272,6 @@ class SpotFleetRequest(TaggedEC2Resource, CloudFormationModel):
self.spot_requests = []
self.create_spot_requests(self.target_capacity)
def _extract_tags(self, spec):
# IN: [{"ResourceType": _type, "Tag": [{"Key": k, "Value": v}, ..]}]
# OUT: {_type: {k: v, ..}}
tag_spec_set = spec.get("TagSpecificationSet", [])
tags = {}
for tag_spec in tag_spec_set:
if tag_spec["ResourceType"] not in tags:
tags[tag_spec["ResourceType"]] = {}
tags[tag_spec["ResourceType"]].update(
{tag["Key"]: tag["Value"] for tag in tag_spec["Tag"]}
)
return tags
@property
def physical_resource_id(self):
return self.id

View File

@ -1,4 +1,5 @@
from moto.core.responses import BaseResponse
from ..utils import convert_tag_spec
class EC2BaseResponse(BaseResponse):
@ -7,3 +8,9 @@ class EC2BaseResponse(BaseResponse):
_filters = self._get_multi_param("Filter.")
# return {x1: y1, ...}
return {f["Name"]: f["Value"] for f in _filters}
def _parse_tag_specification(self):
# [{"ResourceType": _type, "Tag": [{"Key": k, "Value": v}, ..]}]
tag_spec_set = self._get_multi_param("TagSpecification")
# {_type: {k: v, ..}}
return convert_tag_spec(tag_spec_set)

View File

@ -773,3 +773,16 @@ def gen_moto_amis(described_images, drop_images_missing_keys=True):
raise err
return result
def convert_tag_spec(tag_spec_set):
# IN: [{"ResourceType": _type, "Tag": [{"Key": k, "Value": v}, ..]}]
# OUT: {_type: {k: v, ..}}
tags = {}
for tag_spec in tag_spec_set:
if tag_spec["ResourceType"] not in tags:
tags[tag_spec["ResourceType"]] = {}
tags[tag_spec["ResourceType"]].update(
{tag["Key"]: tag["Value"] for tag in tag_spec["Tag"]}
)
return tags

View File

@ -2170,6 +2170,29 @@ def test_create_instance_with_launch_template_id_produces_no_warning(
assert len(captured_warnings) == 0
@mock_ec2
def test_create_instance_from_launch_template__process_tags():
client = boto3.client("ec2", region_name="us-west-1")
template = client.create_launch_template(
LaunchTemplateName=str(uuid4()),
LaunchTemplateData={
"ImageId": EXAMPLE_AMI_ID,
"TagSpecifications": [
{"ResourceType": "instance", "Tags": [{"Key": "k", "Value": "v"}]}
],
},
)["LaunchTemplate"]
instance = client.run_instances(
MinCount=1,
MaxCount=1,
LaunchTemplate={"LaunchTemplateId": template["LaunchTemplateId"]},
)["Instances"][0]
instance.should.have.key("Tags").equals([{"Key": "k", "Value": "v"}])
@mock_ec2
def test_run_instance_and_associate_public_ip():
ec2 = boto3.resource("ec2", "us-west-1")