From e8ea958444cb4d41d4155438952401b5c3d31b85 Mon Sep 17 00:00:00 2001 From: szopen321 <32538420+szopen321@users.noreply.github.com> Date: Wed, 25 May 2022 16:18:03 +0200 Subject: [PATCH] EC2 - Add keypair validation (#5152) --- moto/ec2/models/instances.py | 2 ++ moto/ec2/models/key_pairs.py | 2 +- moto/settings.py | 4 ++++ tests/test_ec2/test_instances.py | 26 ++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/moto/ec2/models/instances.py b/moto/ec2/models/instances.py index ef5b3ba37..d9de06873 100644 --- a/moto/ec2/models/instances.py +++ b/moto/ec2/models/instances.py @@ -553,6 +553,8 @@ class InstanceBackend(object): def add_instances(self, image_id, count, user_data, security_group_names, **kwargs): location_type = "availability-zone" if kwargs.get("placement") else "region" default_region = "us-east-1" + if settings.ENABLE_KEYPAIR_VALIDATION: + self.describe_key_pairs(key_names=[kwargs.get("key_name")]) valid_instance_types = INSTANCE_TYPE_OFFERINGS[location_type] if "region_name" in kwargs and kwargs.get("placement"): valid_availability_zones = { diff --git a/moto/ec2/models/key_pairs.py b/moto/ec2/models/key_pairs.py index 7075f7e7f..ac9b5f58d 100644 --- a/moto/ec2/models/key_pairs.py +++ b/moto/ec2/models/key_pairs.py @@ -46,7 +46,7 @@ class KeyPairBackend(object): def describe_key_pairs(self, key_names=None, filters=None): results = [] - if key_names: + if any(key_names): results = [ keypair for keypair in self.keypairs.values() diff --git a/moto/settings.py b/moto/settings.py index 8a3bffaa8..de91b5c66 100644 --- a/moto/settings.py +++ b/moto/settings.py @@ -22,6 +22,10 @@ EC2_ENABLE_INSTANCE_TYPE_VALIDATION = bool( os.environ.get("MOTO_EC2_ENABLE_INSTANCE_TYPE_VALIDATION", False) ) +ENABLE_KEYPAIR_VALIDATION = bool( + os.environ.get("MOTO_ENABLE_KEYPAIR_VALIDATION", False) +) + def get_sf_execution_history_type(): """ diff --git a/tests/test_ec2/test_instances.py b/tests/test_ec2/test_instances.py index e0c34cb14..6c416af11 100644 --- a/tests/test_ec2/test_instances.py +++ b/tests/test_ec2/test_instances.py @@ -1561,6 +1561,7 @@ def test_ec2_classic_has_public_ip_address(): @mock_ec2 def test_run_instance_with_keypair(): ec2 = boto3.resource("ec2", region_name="us-east-1") + instance = ec2.create_instances( ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, KeyName="keypair_name" )[0] @@ -1568,6 +1569,30 @@ def test_run_instance_with_keypair(): instance.key_name.should.equal("keypair_name") +@mock_ec2 +@mock.patch( + "moto.ec2.models.instances.settings.ENABLE_KEYPAIR_VALIDATION", + new_callable=mock.PropertyMock(return_value=True), +) +def test_run_instance_with_invalid_keypair(m_flag): + if settings.TEST_SERVER_MODE: + raise SkipTest( + "It is not possible to set the environment variable in server mode" + ) + ec2 = boto3.resource("ec2", region_name="us-east-1") + keypair_name = "keypair_name" + ec2.create_key_pair(KeyName=keypair_name) + + with pytest.raises(ClientError) as ex: + ec2.create_instances( + ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1, KeyName="not a key name" + )[0] + + ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) + ex.value.response["Error"]["Code"].should.equal("InvalidKeyPair.NotFound") + assert m_flag is True + + @mock_ec2 def test_run_instance_with_block_device_mappings(): ec2_client = boto3.client("ec2", region_name="us-east-1") @@ -1684,6 +1709,7 @@ def test_run_instance_with_block_device_mappings_missing_size(): def test_run_instance_with_block_device_mappings_from_snapshot(): ec2_client = boto3.client("ec2", region_name="us-east-1") ec2_resource = boto3.resource("ec2", region_name="us-east-1") + volume_details = { "AvailabilityZone": "1a", "Size": 30,