Autoscaling - create custom BlockDevice in addition to default image block device (#5050)
This commit is contained in:
parent
61a5d5ca3b
commit
752eee1941
@ -131,6 +131,10 @@ class FakeLaunchConfiguration(CloudFormationModel):
|
|||||||
ebs_optimized,
|
ebs_optimized,
|
||||||
associate_public_ip_address,
|
associate_public_ip_address,
|
||||||
block_device_mapping_dict,
|
block_device_mapping_dict,
|
||||||
|
region_name,
|
||||||
|
metadata_options,
|
||||||
|
classic_link_vpc_id,
|
||||||
|
classic_link_vpc_security_groups,
|
||||||
):
|
):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.image_id = image_id
|
self.image_id = image_id
|
||||||
@ -146,6 +150,10 @@ class FakeLaunchConfiguration(CloudFormationModel):
|
|||||||
self.ebs_optimized = ebs_optimized
|
self.ebs_optimized = ebs_optimized
|
||||||
self.associate_public_ip_address = associate_public_ip_address
|
self.associate_public_ip_address = associate_public_ip_address
|
||||||
self.block_device_mapping_dict = block_device_mapping_dict
|
self.block_device_mapping_dict = block_device_mapping_dict
|
||||||
|
self.metadata_options = metadata_options
|
||||||
|
self.classic_link_vpc_id = classic_link_vpc_id
|
||||||
|
self.classic_link_vpc_security_groups = classic_link_vpc_security_groups
|
||||||
|
self.arn = f"arn:aws:autoscaling:{region_name}:{ACCOUNT_ID}:launchConfiguration:9dbbbf87-6141-428a-a409-0752edbe6cad:launchConfigurationName/{self.name}"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_from_instance(cls, name, instance, backend):
|
def create_from_instance(cls, name, instance, backend):
|
||||||
@ -253,6 +261,8 @@ class FakeLaunchConfiguration(CloudFormationModel):
|
|||||||
mount_point = mapping.get("DeviceName")
|
mount_point = mapping.get("DeviceName")
|
||||||
if mapping.get("VirtualName") and "ephemeral" in mapping.get("VirtualName"):
|
if mapping.get("VirtualName") and "ephemeral" in mapping.get("VirtualName"):
|
||||||
block_type.ephemeral_name = mapping.get("VirtualName")
|
block_type.ephemeral_name = mapping.get("VirtualName")
|
||||||
|
elif mapping.get("NoDevice", "false") == "true":
|
||||||
|
block_type.no_device = "true"
|
||||||
else:
|
else:
|
||||||
ebs = mapping.get("Ebs", {})
|
ebs = mapping.get("Ebs", {})
|
||||||
block_type.volume_type = ebs.get("VolumeType")
|
block_type.volume_type = ebs.get("VolumeType")
|
||||||
@ -260,6 +270,8 @@ class FakeLaunchConfiguration(CloudFormationModel):
|
|||||||
block_type.delete_on_termination = ebs.get("DeleteOnTermination")
|
block_type.delete_on_termination = ebs.get("DeleteOnTermination")
|
||||||
block_type.size = ebs.get("VolumeSize")
|
block_type.size = ebs.get("VolumeSize")
|
||||||
block_type.iops = ebs.get("Iops")
|
block_type.iops = ebs.get("Iops")
|
||||||
|
block_type.throughput = ebs.get("Throughput")
|
||||||
|
block_type.encrypted = ebs.get("Encrypted")
|
||||||
block_device_map[mount_point] = block_type
|
block_device_map[mount_point] = block_type
|
||||||
return block_device_map
|
return block_device_map
|
||||||
|
|
||||||
@ -678,6 +690,9 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
associate_public_ip_address,
|
associate_public_ip_address,
|
||||||
block_device_mappings,
|
block_device_mappings,
|
||||||
instance_id=None,
|
instance_id=None,
|
||||||
|
metadata_options=None,
|
||||||
|
classic_link_vpc_id=None,
|
||||||
|
classic_link_vpc_security_groups=None,
|
||||||
):
|
):
|
||||||
valid_requests = [
|
valid_requests = [
|
||||||
instance_id is not None,
|
instance_id is not None,
|
||||||
@ -705,6 +720,10 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
ebs_optimized=ebs_optimized,
|
ebs_optimized=ebs_optimized,
|
||||||
associate_public_ip_address=associate_public_ip_address,
|
associate_public_ip_address=associate_public_ip_address,
|
||||||
block_device_mapping_dict=block_device_mappings,
|
block_device_mapping_dict=block_device_mappings,
|
||||||
|
region_name=self.region,
|
||||||
|
metadata_options=metadata_options,
|
||||||
|
classic_link_vpc_id=classic_link_vpc_id,
|
||||||
|
classic_link_vpc_security_groups=classic_link_vpc_security_groups,
|
||||||
)
|
)
|
||||||
self.launch_configurations[name] = launch_configuration
|
self.launch_configurations[name] = launch_configuration
|
||||||
return launch_configuration
|
return launch_configuration
|
||||||
|
@ -37,6 +37,9 @@ class AutoScalingResponse(BaseResponse):
|
|||||||
associate_public_ip_address=params.get("AssociatePublicIpAddress"),
|
associate_public_ip_address=params.get("AssociatePublicIpAddress"),
|
||||||
block_device_mappings=params.get("BlockDeviceMappings"),
|
block_device_mappings=params.get("BlockDeviceMappings"),
|
||||||
instance_id=params.get("InstanceId"),
|
instance_id=params.get("InstanceId"),
|
||||||
|
metadata_options=params.get("MetadataOptions"),
|
||||||
|
classic_link_vpc_id=params.get("ClassicLinkVPCId"),
|
||||||
|
classic_link_vpc_security_groups=params.get("ClassicLinkVPCSecurityGroups"),
|
||||||
)
|
)
|
||||||
template = self.response_template(CREATE_LAUNCH_CONFIGURATION_TEMPLATE)
|
template = self.response_template(CREATE_LAUNCH_CONFIGURATION_TEMPLATE)
|
||||||
return template.render()
|
return template.render()
|
||||||
@ -449,13 +452,27 @@ DESCRIBE_LAUNCH_CONFIGURATIONS_TEMPLATE = """<DescribeLaunchConfigurationsRespon
|
|||||||
{% for launch_configuration in launch_configurations %}
|
{% for launch_configuration in launch_configurations %}
|
||||||
<member>
|
<member>
|
||||||
<AssociatePublicIpAddress>{{ 'true' if launch_configuration.associate_public_ip_address else 'false' }}</AssociatePublicIpAddress>
|
<AssociatePublicIpAddress>{{ 'true' if launch_configuration.associate_public_ip_address else 'false' }}</AssociatePublicIpAddress>
|
||||||
|
{% if launch_configuration.classic_link_vpc_id %}
|
||||||
|
<ClassicLinkVPCId>{{ launch_configuration.classic_link_vpc_id }}</ClassicLinkVPCId>
|
||||||
|
{% endif %}
|
||||||
|
{% if launch_configuration.classic_link_vpc_security_groups %}
|
||||||
|
<ClassicLinkVPCSecurityGroups>
|
||||||
|
{% for sg in launch_configuration.classic_link_vpc_security_groups %}
|
||||||
|
<member>{{ sg }}</member>
|
||||||
|
{% endfor %}
|
||||||
|
</ClassicLinkVPCSecurityGroups>
|
||||||
|
{% endif %}
|
||||||
<SecurityGroups>
|
<SecurityGroups>
|
||||||
{% for security_group in launch_configuration.security_groups %}
|
{% for security_group in launch_configuration.security_groups %}
|
||||||
<member>{{ security_group }}</member>
|
<member>{{ security_group }}</member>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</SecurityGroups>
|
</SecurityGroups>
|
||||||
<CreatedTime>2013-01-21T23:04:42.200Z</CreatedTime>
|
<CreatedTime>2013-01-21T23:04:42.200Z</CreatedTime>
|
||||||
|
{% if launch_configuration.kernel_id %}
|
||||||
<KernelId>{{ launch_configuration.kernel_id }}</KernelId>
|
<KernelId>{{ launch_configuration.kernel_id }}</KernelId>
|
||||||
|
{% else %}
|
||||||
|
<KernelId/>
|
||||||
|
{% endif %}
|
||||||
{% if launch_configuration.instance_profile_name %}
|
{% if launch_configuration.instance_profile_name %}
|
||||||
<IamInstanceProfile>{{ launch_configuration.instance_profile_name }}</IamInstanceProfile>
|
<IamInstanceProfile>{{ launch_configuration.instance_profile_name }}</IamInstanceProfile>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -466,7 +483,7 @@ DESCRIBE_LAUNCH_CONFIGURATIONS_TEMPLATE = """<DescribeLaunchConfigurationsRespon
|
|||||||
<UserData/>
|
<UserData/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<InstanceType>{{ launch_configuration.instance_type }}</InstanceType>
|
<InstanceType>{{ launch_configuration.instance_type }}</InstanceType>
|
||||||
<LaunchConfigurationARN>arn:aws:autoscaling:us-east-1:803981987763:launchConfiguration:9dbbbf87-6141-428a-a409-0752edbe6cad:launchConfigurationName/{{ launch_configuration.name }}</LaunchConfigurationARN>
|
<LaunchConfigurationARN>{{ launch_configuration.arn }}</LaunchConfigurationARN>
|
||||||
{% if launch_configuration.block_device_mappings %}
|
{% if launch_configuration.block_device_mappings %}
|
||||||
<BlockDeviceMappings>
|
<BlockDeviceMappings>
|
||||||
{% for mount_point, mapping in launch_configuration.block_device_mappings.items() %}
|
{% for mount_point, mapping in launch_configuration.block_device_mappings.items() %}
|
||||||
@ -474,6 +491,8 @@ DESCRIBE_LAUNCH_CONFIGURATIONS_TEMPLATE = """<DescribeLaunchConfigurationsRespon
|
|||||||
<DeviceName>{{ mount_point }}</DeviceName>
|
<DeviceName>{{ mount_point }}</DeviceName>
|
||||||
{% if mapping.ephemeral_name %}
|
{% if mapping.ephemeral_name %}
|
||||||
<VirtualName>{{ mapping.ephemeral_name }}</VirtualName>
|
<VirtualName>{{ mapping.ephemeral_name }}</VirtualName>
|
||||||
|
{% elif mapping.no_device %}
|
||||||
|
<NoDevice>true</NoDevice>
|
||||||
{% else %}
|
{% else %}
|
||||||
<Ebs>
|
<Ebs>
|
||||||
{% if mapping.snapshot_id %}
|
{% if mapping.snapshot_id %}
|
||||||
@ -485,8 +504,18 @@ DESCRIBE_LAUNCH_CONFIGURATIONS_TEMPLATE = """<DescribeLaunchConfigurationsRespon
|
|||||||
{% if mapping.iops %}
|
{% if mapping.iops %}
|
||||||
<Iops>{{ mapping.iops }}</Iops>
|
<Iops>{{ mapping.iops }}</Iops>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if mapping.throughput %}
|
||||||
|
<Throughput>{{ mapping.throughput }}</Throughput>
|
||||||
|
{% endif %}
|
||||||
|
{% if mapping.delete_on_termination is not none %}
|
||||||
<DeleteOnTermination>{{ mapping.delete_on_termination }}</DeleteOnTermination>
|
<DeleteOnTermination>{{ mapping.delete_on_termination }}</DeleteOnTermination>
|
||||||
|
{% endif %}
|
||||||
|
{% if mapping.volume_type %}
|
||||||
<VolumeType>{{ mapping.volume_type }}</VolumeType>
|
<VolumeType>{{ mapping.volume_type }}</VolumeType>
|
||||||
|
{% endif %}
|
||||||
|
{% if mapping.encrypted %}
|
||||||
|
<Encrypted>{{ mapping.encrypted }}</Encrypted>
|
||||||
|
{% endif %}
|
||||||
</Ebs>
|
</Ebs>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</member>
|
</member>
|
||||||
@ -501,7 +530,11 @@ DESCRIBE_LAUNCH_CONFIGURATIONS_TEMPLATE = """<DescribeLaunchConfigurationsRespon
|
|||||||
{% else %}
|
{% else %}
|
||||||
<KeyName/>
|
<KeyName/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if launch_configuration.ramdisk_id %}
|
||||||
<RamdiskId>{{ launch_configuration.ramdisk_id }}</RamdiskId>
|
<RamdiskId>{{ launch_configuration.ramdisk_id }}</RamdiskId>
|
||||||
|
{% else %}
|
||||||
|
<RamdiskId/>
|
||||||
|
{% endif %}
|
||||||
<EbsOptimized>{{ launch_configuration.ebs_optimized }}</EbsOptimized>
|
<EbsOptimized>{{ launch_configuration.ebs_optimized }}</EbsOptimized>
|
||||||
<InstanceMonitoring>
|
<InstanceMonitoring>
|
||||||
<Enabled>{{ launch_configuration.instance_monitoring_enabled }}</Enabled>
|
<Enabled>{{ launch_configuration.instance_monitoring_enabled }}</Enabled>
|
||||||
@ -509,6 +542,13 @@ DESCRIBE_LAUNCH_CONFIGURATIONS_TEMPLATE = """<DescribeLaunchConfigurationsRespon
|
|||||||
{% if launch_configuration.spot_price %}
|
{% if launch_configuration.spot_price %}
|
||||||
<SpotPrice>{{ launch_configuration.spot_price }}</SpotPrice>
|
<SpotPrice>{{ launch_configuration.spot_price }}</SpotPrice>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if launch_configuration.metadata_options %}
|
||||||
|
<MetadataOptions>
|
||||||
|
<HttpTokens>{{ launch_configuration.metadata_options.get("HttpTokens") }}</HttpTokens>
|
||||||
|
<HttpPutResponseHopLimit>{{ launch_configuration.metadata_options.get("HttpPutResponseHopLimit") }}</HttpPutResponseHopLimit>
|
||||||
|
<HttpEndpoint>{{ launch_configuration.metadata_options.get("HttpEndpoint") }}</HttpEndpoint>
|
||||||
|
</MetadataOptions>
|
||||||
|
{% endif %}
|
||||||
</member>
|
</member>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</LaunchConfigurations>
|
</LaunchConfigurations>
|
||||||
|
@ -8,6 +8,7 @@ from ..exceptions import (
|
|||||||
InvalidAMIAttributeItemValueError,
|
InvalidAMIAttributeItemValueError,
|
||||||
MalformedAMIIdError,
|
MalformedAMIIdError,
|
||||||
InvalidTaggableResourceType,
|
InvalidTaggableResourceType,
|
||||||
|
UnvailableAMIIdError,
|
||||||
)
|
)
|
||||||
from .core import TaggedEC2Resource
|
from .core import TaggedEC2Resource
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
@ -146,6 +147,7 @@ class AmiBackend(object):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.amis = {}
|
self.amis = {}
|
||||||
|
self.deleted_amis = list()
|
||||||
self._load_amis()
|
self._load_amis()
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
@ -216,6 +218,7 @@ class AmiBackend(object):
|
|||||||
if len(ami_ids):
|
if len(ami_ids):
|
||||||
# boto3 seems to default to just searching based on ami ids if that parameter is passed
|
# boto3 seems to default to just searching based on ami ids if that parameter is passed
|
||||||
# and if no images are found, it raises an errors
|
# and if no images are found, it raises an errors
|
||||||
|
# Note that we can search for images that have been previously deleted, without raising any errors
|
||||||
malformed_ami_ids = [
|
malformed_ami_ids = [
|
||||||
ami_id for ami_id in ami_ids if not ami_id.startswith("ami-")
|
ami_id for ami_id in ami_ids if not ami_id.startswith("ami-")
|
||||||
]
|
]
|
||||||
@ -223,7 +226,10 @@ class AmiBackend(object):
|
|||||||
raise MalformedAMIIdError(malformed_ami_ids)
|
raise MalformedAMIIdError(malformed_ami_ids)
|
||||||
|
|
||||||
images = [ami for ami in images if ami.id in ami_ids]
|
images = [ami for ami in images if ami.id in ami_ids]
|
||||||
if len(images) == 0:
|
deleted_images = [
|
||||||
|
ami_id for ami_id in ami_ids if ami_id in self.deleted_amis
|
||||||
|
]
|
||||||
|
if len(images) + len(deleted_images) == 0:
|
||||||
raise InvalidAMIIdError(ami_ids)
|
raise InvalidAMIIdError(ami_ids)
|
||||||
else:
|
else:
|
||||||
# Limit images by launch permissions
|
# Limit images by launch permissions
|
||||||
@ -257,7 +263,10 @@ class AmiBackend(object):
|
|||||||
def deregister_image(self, ami_id):
|
def deregister_image(self, ami_id):
|
||||||
if ami_id in self.amis:
|
if ami_id in self.amis:
|
||||||
self.amis.pop(ami_id)
|
self.amis.pop(ami_id)
|
||||||
|
self.deleted_amis.append(ami_id)
|
||||||
return True
|
return True
|
||||||
|
elif ami_id in self.deleted_amis:
|
||||||
|
raise UnvailableAMIIdError(ami_id)
|
||||||
raise InvalidAMIIdError(ami_id)
|
raise InvalidAMIIdError(ami_id)
|
||||||
|
|
||||||
def get_launch_permission_groups(self, ami_id):
|
def get_launch_permission_groups(self, ami_id):
|
||||||
|
@ -557,6 +557,8 @@ class InstanceBackend(object):
|
|||||||
new_reservation.instances.append(new_instance)
|
new_reservation.instances.append(new_instance)
|
||||||
new_instance.add_tags(instance_tags)
|
new_instance.add_tags(instance_tags)
|
||||||
block_device_mappings = None
|
block_device_mappings = None
|
||||||
|
if "block_device_mappings" not in kwargs:
|
||||||
|
new_instance.setup_defaults()
|
||||||
if "block_device_mappings" in kwargs:
|
if "block_device_mappings" in kwargs:
|
||||||
block_device_mappings = kwargs["block_device_mappings"]
|
block_device_mappings = kwargs["block_device_mappings"]
|
||||||
elif kwargs.get("launch_template"):
|
elif kwargs.get("launch_template"):
|
||||||
@ -590,8 +592,6 @@ class InstanceBackend(object):
|
|||||||
kms_key_id,
|
kms_key_id,
|
||||||
volume_type=volume_type,
|
volume_type=volume_type,
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
new_instance.setup_defaults()
|
|
||||||
if kwargs.get("instance_market_options"):
|
if kwargs.get("instance_market_options"):
|
||||||
new_instance.lifecycle = "spot"
|
new_instance.lifecycle = "spot"
|
||||||
# Tag all created volumes.
|
# Tag all created volumes.
|
||||||
|
@ -258,6 +258,14 @@ class InvalidAMIIdError(EC2ClientError):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UnvailableAMIIdError(EC2ClientError):
|
||||||
|
def __init__(self, ami_id):
|
||||||
|
super().__init__(
|
||||||
|
"InvalidAMIID.Unavailable",
|
||||||
|
"The image id '[{0}]' is no longer available".format(ami_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class InvalidAMIAttributeItemValueError(EC2ClientError):
|
class InvalidAMIAttributeItemValueError(EC2ClientError):
|
||||||
def __init__(self, attribute, value):
|
def __init__(self, attribute, value):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
@ -661,5 +661,22 @@
|
|||||||
"root_device_type": "ebs",
|
"root_device_type": "ebs",
|
||||||
"sriov": "simple",
|
"sriov": "simple",
|
||||||
"virtualization_type": "hvm"
|
"virtualization_type": "hvm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"architecture": "x86_64",
|
||||||
|
"ami_id": "ami-04681a1dbd79675b6",
|
||||||
|
"image_location": "amazon/amzn2-ami-minimal-pv-2.0.20180810-x86_64-gp2",
|
||||||
|
"image_type": "machine",
|
||||||
|
"public": true,
|
||||||
|
"owner_id": "137112412989",
|
||||||
|
"platform": "Linux/UNIX",
|
||||||
|
"state": "available",
|
||||||
|
"description": "Example InstanceStore AMI used by AutoScaling tests",
|
||||||
|
"hypervisor": "xen",
|
||||||
|
"name": "amzn-ami-minimal-pv-2.0.20180810-x86_64-gp2",
|
||||||
|
"root_device_name": "/dev/xvda",
|
||||||
|
"root_device_type": "instance-store",
|
||||||
|
"sriov": "simple",
|
||||||
|
"virtualization_type": "hvm"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -8,8 +8,11 @@ apigatewayv2:
|
|||||||
- TestAccAPIGatewayV2RouteResponse
|
- TestAccAPIGatewayV2RouteResponse
|
||||||
- TestAccAPIGatewayV2VPCLink
|
- TestAccAPIGatewayV2VPCLink
|
||||||
autoscaling:
|
autoscaling:
|
||||||
- TestAccAutoScalingGroupDataSource
|
|
||||||
- TestAccAutoScalingAttachment
|
- TestAccAutoScalingAttachment
|
||||||
|
- TestAccAutoScalingGroupDataSource
|
||||||
|
- TestAccAutoScalingGroupTag
|
||||||
|
- TestAccAutoScalingLaunchConfigurationDataSource
|
||||||
|
- TestAccAutoScalingLaunchConfiguration_
|
||||||
batch:
|
batch:
|
||||||
- TestAccBatchJobDefinition
|
- TestAccBatchJobDefinition
|
||||||
cloudtrail:
|
cloudtrail:
|
||||||
|
@ -2810,5 +2810,9 @@ def test_create_template_with_block_device():
|
|||||||
)
|
)
|
||||||
ec2_client = boto3.client("ec2", region_name="ap-southeast-2")
|
ec2_client = boto3.client("ec2", region_name="ap-southeast-2")
|
||||||
volumes = ec2_client.describe_volumes()["Volumes"]
|
volumes = ec2_client.describe_volumes()["Volumes"]
|
||||||
volumes[0]["VolumeType"].should.equal("gp3")
|
# The standard root volume
|
||||||
volumes[0]["Size"].should.equal(20)
|
volumes[0]["VolumeType"].should.equal("gp2")
|
||||||
|
volumes[0]["Size"].should.equal(8)
|
||||||
|
# Our Ebs-volume
|
||||||
|
volumes[1]["VolumeType"].should.equal("gp3")
|
||||||
|
volumes[1]["Size"].should.equal(20)
|
||||||
|
@ -99,7 +99,6 @@ def test_create_launch_configuration_with_block_device_mappings():
|
|||||||
xvdp.should.have.key("Ebs")
|
xvdp.should.have.key("Ebs")
|
||||||
xvdp["Ebs"]["SnapshotId"].should.equal("snap-1234abcd")
|
xvdp["Ebs"]["SnapshotId"].should.equal("snap-1234abcd")
|
||||||
xvdp["Ebs"]["VolumeType"].should.equal("standard")
|
xvdp["Ebs"]["VolumeType"].should.equal("standard")
|
||||||
xvdp["Ebs"]["DeleteOnTermination"].should.equal(False)
|
|
||||||
|
|
||||||
xvdb["VirtualName"].should.equal("ephemeral0")
|
xvdb["VirtualName"].should.equal("ephemeral0")
|
||||||
xvdb.shouldnt.have.key("Ebs")
|
xvdb.shouldnt.have.key("Ebs")
|
||||||
@ -109,16 +108,32 @@ def test_create_launch_configuration_with_block_device_mappings():
|
|||||||
def test_create_launch_configuration_additional_parameters():
|
def test_create_launch_configuration_additional_parameters():
|
||||||
client = boto3.client("autoscaling", region_name="us-east-1")
|
client = boto3.client("autoscaling", region_name="us-east-1")
|
||||||
client.create_launch_configuration(
|
client.create_launch_configuration(
|
||||||
|
ClassicLinkVPCId="vpc_id",
|
||||||
|
ClassicLinkVPCSecurityGroups=["classic_sg1"],
|
||||||
LaunchConfigurationName="tester",
|
LaunchConfigurationName="tester",
|
||||||
ImageId=EXAMPLE_AMI_ID,
|
ImageId=EXAMPLE_AMI_ID,
|
||||||
InstanceType="t1.micro",
|
InstanceType="t1.micro",
|
||||||
EbsOptimized=True,
|
EbsOptimized=True,
|
||||||
AssociatePublicIpAddress=True,
|
AssociatePublicIpAddress=True,
|
||||||
|
MetadataOptions={
|
||||||
|
"HttpTokens": "optional",
|
||||||
|
"HttpPutResponseHopLimit": 123,
|
||||||
|
"HttpEndpoint": "disabled",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
launch_config = client.describe_launch_configurations()["LaunchConfigurations"][0]
|
launch_config = client.describe_launch_configurations()["LaunchConfigurations"][0]
|
||||||
|
launch_config["ClassicLinkVPCId"].should.equal("vpc_id")
|
||||||
|
launch_config["ClassicLinkVPCSecurityGroups"].should.equal(["classic_sg1"])
|
||||||
launch_config["EbsOptimized"].should.equal(True)
|
launch_config["EbsOptimized"].should.equal(True)
|
||||||
launch_config["AssociatePublicIpAddress"].should.equal(True)
|
launch_config["AssociatePublicIpAddress"].should.equal(True)
|
||||||
|
launch_config["MetadataOptions"].should.equal(
|
||||||
|
{
|
||||||
|
"HttpTokens": "optional",
|
||||||
|
"HttpPutResponseHopLimit": 123,
|
||||||
|
"HttpEndpoint": "disabled",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_autoscaling
|
@mock_autoscaling
|
||||||
@ -287,7 +302,10 @@ def test_launch_config_with_block_device_mappings__volumes_are_created():
|
|||||||
volumes = ec2_client.describe_volumes(
|
volumes = ec2_client.describe_volumes(
|
||||||
Filters=[{"Name": "attachment.instance-id", "Values": [instance_id]}]
|
Filters=[{"Name": "attachment.instance-id", "Values": [instance_id]}]
|
||||||
)["Volumes"]
|
)["Volumes"]
|
||||||
volumes.should.have.length_of(1)
|
volumes.should.have.length_of(2)
|
||||||
volumes[0].should.have.key("Size").equals(10)
|
volumes[0].should.have.key("Size").equals(8)
|
||||||
volumes[0].should.have.key("Encrypted").equals(False)
|
volumes[0].should.have.key("Encrypted").equals(False)
|
||||||
volumes[0].should.have.key("VolumeType").equals("standard")
|
volumes[0].should.have.key("VolumeType").equals("gp2")
|
||||||
|
volumes[1].should.have.key("Size").equals(10)
|
||||||
|
volumes[1].should.have.key("Encrypted").equals(False)
|
||||||
|
volumes[1].should.have.key("VolumeType").equals("standard")
|
||||||
|
@ -117,10 +117,41 @@ def test_ami_create_and_delete():
|
|||||||
ec2.deregister_image(ImageId=image_id)
|
ec2.deregister_image(ImageId=image_id)
|
||||||
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||||
err = ex.value.response["Error"]
|
err = ex.value.response["Error"]
|
||||||
|
err["Code"].should.equal("InvalidAMIID.Unavailable")
|
||||||
|
ex.value.response["ResponseMetadata"]["RequestId"].should_not.equal(None)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_deregister_image__unknown():
|
||||||
|
ec2 = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as ex:
|
||||||
|
ec2.deregister_image(ImageId="ami-unknown-ami")
|
||||||
|
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||||
|
err = ex.value.response["Error"]
|
||||||
err["Code"].should.equal("InvalidAMIID.NotFound")
|
err["Code"].should.equal("InvalidAMIID.NotFound")
|
||||||
ex.value.response["ResponseMetadata"]["RequestId"].should_not.equal(None)
|
ex.value.response["ResponseMetadata"]["RequestId"].should_not.equal(None)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_deregister_image__and_describe():
|
||||||
|
ec2 = boto3.client("ec2", region_name="us-east-1")
|
||||||
|
|
||||||
|
reservation = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)
|
||||||
|
instance = reservation["Instances"][0]
|
||||||
|
instance_id = instance["InstanceId"]
|
||||||
|
|
||||||
|
image_id = ec2.create_image(
|
||||||
|
InstanceId=instance_id, Name="test-ami", Description="this is a test ami"
|
||||||
|
)["ImageId"]
|
||||||
|
|
||||||
|
ec2.deregister_image(ImageId=image_id)
|
||||||
|
|
||||||
|
# Searching for a deleted image ID should not throw an error
|
||||||
|
# It should simply not return this image
|
||||||
|
ec2.describe_images(ImageIds=[image_id])["Images"].should.have.length_of(0)
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ami_copy_dryrun():
|
def test_ami_copy_dryrun():
|
||||||
ec2 = boto3.client("ec2", region_name="us-west-1")
|
ec2 = boto3.client("ec2", region_name="us-west-1")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user