From d4e39146b70d78d198041012a3b4f05e4f14cf0b Mon Sep 17 00:00:00 2001 From: Hugo Lopes Tavares Date: Wed, 27 Mar 2019 16:23:49 -0400 Subject: [PATCH 1/2] Make sure every NetworkInterface has a private IP AWS always assigns a primary IP address to Network Interfaces. Using a test account (modified the IP): >>> import boto >>> vpc = boto.connect_vpc() >>> eni = vpc.create_network_interface(subnet_id) >>> eni.private_ip_addresses [PrivateIPAddress(10.1.2.3, primary=True)] --- moto/ec2/models.py | 2 +- tests/test_ec2/test_elastic_network_interfaces.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/moto/ec2/models.py b/moto/ec2/models.py index ff766d7b8..ef1425ea7 100644 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -189,7 +189,7 @@ class NetworkInterface(TaggedEC2Resource): self.ec2_backend = ec2_backend self.id = random_eni_id() self.device_index = device_index - self.private_ip_address = private_ip_address + self.private_ip_address = private_ip_address or random_private_ip() self.subnet = subnet self.instance = None self.attachment_id = None diff --git a/tests/test_ec2/test_elastic_network_interfaces.py b/tests/test_ec2/test_elastic_network_interfaces.py index 828f9d917..581106b42 100644 --- a/tests/test_ec2/test_elastic_network_interfaces.py +++ b/tests/test_ec2/test_elastic_network_interfaces.py @@ -36,7 +36,8 @@ def test_elastic_network_interfaces(): all_enis.should.have.length_of(1) eni = all_enis[0] eni.groups.should.have.length_of(0) - eni.private_ip_addresses.should.have.length_of(0) + eni.private_ip_addresses.should.have.length_of(1) + eni.private_ip_addresses[0].private_ip_address.startswith('10.').should.be.true with assert_raises(EC2ResponseError) as ex: conn.delete_network_interface(eni.id, dry_run=True) From 7c62f4a75c3ae3e9ae22e009793d3578c143bb0b Mon Sep 17 00:00:00 2001 From: Hugo Lopes Tavares Date: Wed, 27 Mar 2019 16:28:18 -0400 Subject: [PATCH 2/2] Add test to CloudFormation and PrimaryPrivateIpAddress GetAtt This test would raise an error before d4e39146b70d78d198041012a3b4f05e4f14cf0b --- tests/test_cloudformation/fixtures/vpc_eni.py | 4 ++++ tests/test_ec2/test_elastic_network_interfaces.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/test_cloudformation/fixtures/vpc_eni.py b/tests/test_cloudformation/fixtures/vpc_eni.py index ef9eb1d08..3f8eb2d03 100644 --- a/tests/test_cloudformation/fixtures/vpc_eni.py +++ b/tests/test_cloudformation/fixtures/vpc_eni.py @@ -29,6 +29,10 @@ template = { "NinjaENI": { "Description": "Elastic IP mapping to Auto-Scaling Group", "Value": {"Ref": "ENI"} + }, + "ENIIpAddress": { + "Description": "ENI's Private IP address", + "Value": {"Fn::GetAtt": ["ENI", "PrimaryPrivateIpAddress"]} } } } diff --git a/tests/test_ec2/test_elastic_network_interfaces.py b/tests/test_ec2/test_elastic_network_interfaces.py index 581106b42..70e78ae12 100644 --- a/tests/test_ec2/test_elastic_network_interfaces.py +++ b/tests/test_ec2/test_elastic_network_interfaces.py @@ -355,9 +355,13 @@ def test_elastic_network_interfaces_cloudformation(): ) ec2_conn = boto.ec2.connect_to_region("us-west-1") eni = ec2_conn.get_all_network_interfaces()[0] + eni.private_ip_addresses.should.have.length_of(1) stack = conn.describe_stacks()[0] resources = stack.describe_resources() cfn_eni = [resource for resource in resources if resource.resource_type == 'AWS::EC2::NetworkInterface'][0] cfn_eni.physical_resource_id.should.equal(eni.id) + + outputs = {output.key: output.value for output in stack.outputs} + outputs['ENIIpAddress'].should.equal(eni.private_ip_addresses[0].private_ip_address)