Add availability zone check on add instance (#5129)

This commit is contained in:
szopen321 2022-05-16 18:58:14 +02:00 committed by GitHub
parent 8bbd242d75
commit c59583c15b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 4 deletions

View File

@ -586,6 +586,14 @@ class InvalidAvailabilityZoneError(EC2ClientError):
)
class AvailabilityZoneNotFromRegionError(EC2ClientError):
def __init__(self, availability_zone_value):
super().__init__(
"InvalidParameterValue",
"Invalid Availability Zone ({0})".format(availability_zone_value),
)
class NetworkAclEntryAlreadyExistsError(EC2ClientError):
def __init__(self, rule_number):
super().__init__(

View File

@ -6,24 +6,28 @@ from datetime import datetime
from moto.core import get_account_id
from moto.core import CloudFormationModel
from moto.core.utils import camelcase_to_underscores
from moto.ec2.models.instance_types import INSTANCE_TYPE_OFFERINGS
from moto.packages.boto.ec2.blockdevicemapping import BlockDeviceMapping
from moto.packages.boto.ec2.instance import Instance as BotoInstance, Reservation
from moto.packages.boto.ec2.instance import Instance as BotoInstance
from moto.packages.boto.ec2.instance import Reservation
from ..exceptions import (
AvailabilityZoneNotFromRegionError,
EC2ClientError,
InvalidInstanceIdError,
InvalidParameterValueErrorUnknownAttribute,
OperationNotPermitted4,
)
from .core import TaggedEC2Resource
from ..utils import (
convert_tag_spec,
filter_reservations,
random_eni_attach_id,
random_instance_id,
random_private_ip,
random_reservation_id,
filter_reservations,
utc_date_and_time,
convert_tag_spec,
)
from .core import TaggedEC2Resource
class InstanceState(object):
@ -538,6 +542,15 @@ class InstanceBackend(object):
raise InvalidInstanceIdError(instance_id)
def add_instances(self, image_id, count, user_data, security_group_names, **kwargs):
location_type = "availability-zone" if kwargs.get("placement") else "region"
valid_instance_types = INSTANCE_TYPE_OFFERINGS[location_type]
if "region_name" in kwargs and kwargs.get("placement"):
valid_availability_zones = {
instance["Location"]
for instance in valid_instance_types[kwargs["region_name"]]
}
if kwargs["placement"] not in valid_availability_zones:
raise AvailabilityZoneNotFromRegionError(kwargs["placement"])
new_reservation = Reservation()
new_reservation.id = random_reservation_id()

View File

@ -1162,6 +1162,24 @@ def test_run_instance_with_placement():
instance.placement.should.have.key("AvailabilityZone").equal("us-east-1b")
@mock_ec2
def test_run_instance_with_availability_zone_not_from_region():
ec2 = boto3.resource("ec2", region_name="us-east-1")
with pytest.raises(ClientError) as ex:
ec2.create_instances(
ImageId=EXAMPLE_AMI_ID,
InstanceType="t2.nano",
MinCount=1,
MaxCount=1,
Placement={"AvailabilityZone": "us-west-1b"},
)
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.value.response["Error"]["Message"].should.equal(
"Invalid Availability Zone (us-west-1b)"
)
@mock_ec2
def test_run_instance_with_subnet():
client = boto3.client("ec2", region_name="eu-central-1")