EC2: Implement GetLaunchTemplateData (#6152)

* EC2: Implement GetLaunchTemplateData

* Update implementation coverage docs

* Fix test
This commit is contained in:
Viren Nadkarni 2023-03-30 21:23:26 +05:30 committed by GitHub
parent 20ea1f43ac
commit d0cfddebfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 133 additions and 2 deletions

View File

@ -2191,7 +2191,7 @@
- [ ] get_ipam_pool_allocations
- [ ] get_ipam_pool_cidrs
- [ ] get_ipam_resource_cidrs
- [ ] get_launch_template_data
- [x] get_launch_template_data
- [ ] get_managed_prefix_list_associations
- [X] get_managed_prefix_list_entries
- [ ] get_network_insights_access_scope_analysis_findings
@ -7056,4 +7056,4 @@
- workspaces
- workspaces-web
- xray
</details>
</details>

View File

@ -258,3 +258,110 @@ class LaunchTemplates(EC2BaseResponse):
)
return pretty_xml(tree)
def get_launch_template_data(self) -> str:
instance_id = self._get_param("InstanceId")
instance = self.ec2_backend.get_instance(instance_id)
template = self.response_template(GET_LAUNCH_TEMPLATE_DATA_RESPONSE)
return template.render(i=instance)
GET_LAUNCH_TEMPLATE_DATA_RESPONSE = """<GetLaunchTemplateDataResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<requestId>801986a5-0ee2-46bd-be02-abcde1234567</requestId>
<launchTemplateData>
<blockDeviceMappingSet>
{% for device_name, device in i.block_device_mapping.items() %}
<item>
<deviceName>{{ device_name }}</deviceName>
<ebs>
<deleteOnTermination>{{ device.delete_on_termination }}</deleteOnTermination>
<encrypted>{{ device.encrypted }}</encrypted>
<snapshotId>{{ device.snapshot_id }}</snapshotId>
<volumeSize>{{ device.size }}</volumeSize>
<volumeType>{{ device.volume_type }}</volumeType>
</ebs>
</item>
{% endfor %}
</blockDeviceMappingSet>
<capacityReservationSpecification>
<capacityReservationPreference>open</capacityReservationPreference>
</capacityReservationSpecification>
<creditSpecification>
<cpuCredits>standard</cpuCredits>
</creditSpecification>
<disableApiStop>{{ i.disable_api_stop }}</disableApiStop>
<disableApiTermination>{{ i.disable_api_termination }}</disableApiTermination>
<ebsOptimized>{{ i.ebs_optimised }}</ebsOptimized>
<enclaveOptions>
<enabled>false</enabled>
</enclaveOptions>
<hibernationOptions>
<configured>false</configured>
</hibernationOptions>
<imageId>{{ i.image_id }}</imageId>
<instanceInitiatedShutdownBehavior>{{ i.instance_initiated_shutdown_behavior }}</instanceInitiatedShutdownBehavior>
<instanceType>{{ i.instance_type }}</instanceType>
<keyName>{{ i.key_name }}</keyName>
<maintenanceOptions>
<autoRecovery>default</autoRecovery>
</maintenanceOptions>
<metadataOptions>
<httpEndpoint>enabled</httpEndpoint>
<httpProtocolIpv6>disabled</httpProtocolIpv6>
<httpPutResponseHopLimit>1</httpPutResponseHopLimit>
<httpTokens>optional</httpTokens>
<instanceMetadataTags>disabled</instanceMetadataTags>
</metadataOptions>
<monitoring>
<enabled>{{ i.monitored }}</enabled>
</monitoring>
<networkInterfaceSet>
{% for nic_index, nic in i.nics.items() %}
<item>
<associatePublicIpAddress>true</associatePublicIpAddress>
<deleteOnTermination>{{ nic.delete_on_termination }}</deleteOnTermination>
<description/>
<deviceIndex>{{ nic.device_index }}</deviceIndex>
<groupSet>
<groupId>{{ nic.group_set[0].group_id if nic.group_set }}</groupId>
</groupSet>
<interfaceType>{{ nic.interface_type }}</interfaceType>
<ipv6AddressesSet/>
<networkCardIndex>{{ nic_index }}</networkCardIndex>
<privateIpAddressesSet>
{% for addr in nic.private_ip_addresses %}
<item>
<primary>{{ addr["Primary"] }}</primary>
<privateIpAddress>{{ addr["PrivateIpAddress"] }}</privateIpAddress>
</item>
{% endfor %}
</privateIpAddressesSet>
<subnetId>{{ nic.subnet.id }}</subnetId>
</item>
{% endfor %}
</networkInterfaceSet>
<placement>
<availabilityZone>{{ i.placement }}</availabilityZone>
<groupName/>
<tenancy>default</tenancy>
</placement>
<privateDnsNameOptions>
<enableResourceNameDnsAAAARecord>false</enableResourceNameDnsAAAARecord>
<enableResourceNameDnsARecord>true</enableResourceNameDnsARecord>
<hostnameType>ip-name</hostnameType>
</privateDnsNameOptions>
<tagSpecificationSet>
{% for tag in i.tags %}
<item>
<resourceType>instance</resourceType>
<tagSet>
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
</tagSet>
</item>
{% endfor %}
</tagSpecificationSet>
</launchTemplateData>
</GetLaunchTemplateDataResponse>"""

View File

@ -7,6 +7,8 @@ from botocore.client import ClientError
from moto import mock_ec2, settings
from uuid import uuid4
from tests import EXAMPLE_AMI_ID
@mock_ec2
def test_launch_template_create():
@ -500,6 +502,28 @@ def test_create_launch_template_with_tag_spec():
)
@mock_ec2
def test_get_launch_template_data():
client = boto3.client("ec2", region_name="us-east-1")
reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
instance = reservation["Instances"][0]
launch_template_data = client.get_launch_template_data(
InstanceId=instance["InstanceId"]
)["LaunchTemplateData"]
# Ensure launch template data matches instance
launch_template_data["ImageId"].should.equal(instance["ImageId"])
launch_template_data["InstanceType"].should.equal(instance["InstanceType"])
# Ensure a launch template can be created from this data
client.create_launch_template(
LaunchTemplateName=str(uuid4()),
LaunchTemplateData=launch_template_data,
)
@mock_ec2
def test_delete_launch_template__dryrun():
cli = boto3.client("ec2", region_name="us-east-1")