From 945b9845382c2cd4d87380f96e72be0964c5ef96 Mon Sep 17 00:00:00 2001 From: Daniel Lutsch Date: Wed, 23 Aug 2017 01:39:50 -0700 Subject: [PATCH] Add private-dns-name filter and fix regional DNS (#1076) * add private-dns-name to filter_dict_attribute_mapping * add region_name attribute to Instance and InstanceResponse * set dns name based on region * test private-dns-name and network-interface.private-dns-name filters. checking both regional dns formats * update test_ec2_classic_has_public_ip_address to use correct dns values --- moto/ec2/models.py | 13 +++++++++++-- moto/ec2/responses/instances.py | 3 ++- moto/ec2/utils.py | 4 +++- tests/test_ec2/test_instances.py | 33 ++++++++++++++++++++++++++++---- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/moto/ec2/models.py b/moto/ec2/models.py index 6c35093e2..fca84f0a5 100755 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -366,6 +366,7 @@ class Instance(TaggedEC2Resource, BotoInstance): self.user_data = user_data self.security_groups = security_groups self.instance_type = kwargs.get("instance_type", "m1.small") + self.region_name = kwargs.get("region_name", "us-east-1") placement = kwargs.get("placement", None) self.vpc_id = None self.subnet_id = kwargs.get("subnet_id") @@ -433,7 +434,11 @@ class Instance(TaggedEC2Resource, BotoInstance): @property def private_dns(self): - return "ip-{0}.ec2.internal".format(self.private_ip) + formatted_ip = self.private_ip.replace('.', '-') + if self.region_name == "us-east-1": + return "ip-{0}.ec2.internal".format(formatted_ip) + else: + return "ip-{0}.{1}.compute.internal".format(formatted_ip, self.region_name) @property def public_ip(self): @@ -442,7 +447,11 @@ class Instance(TaggedEC2Resource, BotoInstance): @property def public_dns(self): if self.public_ip: - return "ec2-{0}.compute-1.amazonaws.com".format(self.public_ip) + formatted_ip = self.public_ip.replace('.', '-') + if self.region_name == "us-east-1": + return "ec2-{0}.compute-1.amazonaws.com".format(formatted_ip) + else: + return "ec2-{0}.{1}.compute.amazonaws.com".format(formatted_ip, self.region_name) @classmethod def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name): diff --git a/moto/ec2/responses/instances.py b/moto/ec2/responses/instances.py index 09ecb172b..ea70b85b1 100644 --- a/moto/ec2/responses/instances.py +++ b/moto/ec2/responses/instances.py @@ -48,11 +48,12 @@ class InstanceResponse(BaseResponse): "AssociatePublicIpAddress", [None])[0] key_name = self.querystring.get("KeyName", [None])[0] tags = self._parse_tag_specification("TagSpecification") + region_name = self.region if self.is_not_dryrun('RunInstance'): new_reservation = self.ec2_backend.add_instances( image_id, min_count, user_data, security_group_names, - instance_type=instance_type, placement=placement, subnet_id=subnet_id, + instance_type=instance_type, placement=placement, region_name=region_name, subnet_id=subnet_id, key_name=key_name, security_group_ids=security_group_ids, nics=nics, private_ip=private_ip, associate_public_ip=associate_public_ip, tags=tags) diff --git a/moto/ec2/utils.py b/moto/ec2/utils.py index 0e1a19bd1..365632abd 100644 --- a/moto/ec2/utils.py +++ b/moto/ec2/utils.py @@ -392,7 +392,9 @@ filter_dict_attribute_mapping = { 'ip-address': 'public_ip', 'availability-zone': 'placement', 'architecture': 'architecture', - 'image-id': 'image_id' + 'image-id': 'image_id', + 'network-interface.private-dns-name': 'private_dns', + 'private-dns-name': 'private_dns' } diff --git a/tests/test_ec2/test_instances.py b/tests/test_ec2/test_instances.py index cb953f8cf..75f759c0f 100644 --- a/tests/test_ec2/test_instances.py +++ b/tests/test_ec2/test_instances.py @@ -409,6 +409,33 @@ def test_get_instances_filtering_by_image_id(): 'Values': [image_id]}])['Reservations'] reservations[0]['Instances'].should.have.length_of(1) +@mock_ec2 +def test_get_instances_filtering_by_private_dns(): + image_id = 'ami-1234abcd' + client = boto3.client('ec2', region_name='us-east-1') + conn = boto3.resource('ec2', 'us-east-1') + conn.create_instances(ImageId=image_id, + MinCount=1, + MaxCount=1, + PrivateIpAddress='10.0.0.1') + reservations = client.describe_instances(Filters=[ + {'Name': 'private-dns-name', 'Values': ['ip-10-0-0-1.ec2.internal']} + ])['Reservations'] + reservations[0]['Instances'].should.have.length_of(1) + +@mock_ec2 +def test_get_instances_filtering_by_ni_private_dns(): + image_id = 'ami-1234abcd' + client = boto3.client('ec2', region_name='us-west-2') + conn = boto3.resource('ec2', 'us-west-2') + conn.create_instances(ImageId=image_id, + MinCount=1, + MaxCount=1, + PrivateIpAddress='10.0.0.1') + reservations = client.describe_instances(Filters=[ + {'Name': 'network-interface.private-dns-name', 'Values': ['ip-10-0-0-1.us-west-2.compute.internal']} + ])['Reservations'] + reservations[0]['Instances'].should.have.length_of(1) @mock_ec2_deprecated def test_get_instances_filtering_by_tag(): @@ -943,11 +970,9 @@ def test_ec2_classic_has_public_ip_address(): reservation = conn.run_instances('ami-1234abcd', key_name="keypair_name") instance = reservation.instances[0] instance.ip_address.should_not.equal(None) - instance.public_dns_name.should.contain(instance.ip_address) - + instance.public_dns_name.should.contain(instance.ip_address.replace('.', '-')) instance.private_ip_address.should_not.equal(None) - instance.private_dns_name.should.contain(instance.private_ip_address) - + instance.private_dns_name.should.contain(instance.private_ip_address.replace('.', '-')) @mock_ec2_deprecated def test_run_instance_with_keypair():