From fdadd24ad3a019e867dbfd635d02afc31d3bd95b Mon Sep 17 00:00:00 2001 From: Yann Lambret Date: Sun, 8 May 2016 00:19:01 +0200 Subject: [PATCH] Extend filtering support for elastic network interfaces --- moto/ec2/models.py | 35 ++++++++++++++++++- .../responses/elastic_network_interfaces.py | 24 ++++++++----- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/moto/ec2/models.py b/moto/ec2/models.py index 23083b327..d6088144b 100644 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -152,7 +152,7 @@ class TaggedEC2Resource(object): return [tag['value'] for tag in tags] -class NetworkInterface(object): +class NetworkInterface(TaggedEC2Resource): def __init__(self, ec2_backend, subnet, private_ip_address, device_index=0, public_ip_auto_assign=True, group_ids=None): self.ec2_backend = ec2_backend @@ -236,6 +236,27 @@ class NetworkInterface(object): def physical_resource_id(self): return self.id + def get_filter_value(self, filter_name): + if filter_name == 'network-interface-id': + return self.id + elif filter_name in ('addresses.private-ip-address', 'private-ip-address'): + return self.private_ip_address + elif filter_name == 'subnet-id': + return self.subnet.id + elif filter_name == 'vpc-id': + return self.subnet.vpc_id + elif filter_name == 'group-id': + return [group.id for group in self._group_set] + + filter_value = super(NetworkInterface, self).get_filter_value(filter_name) + + if filter_value is None: + self.ec2_backend.raise_not_implemented_error( + "The filter '{0}' for DescribeNetworkInterfaces".format(filter_name) + ) + + return filter_value + class NetworkInterfaceBackend(object): def __init__(self): @@ -301,6 +322,18 @@ class NetworkInterfaceBackend(object): group = self.get_security_group_from_id(group_id) eni._group_set = [group] + def get_all_network_interfaces(self, eni_ids=None, filters=None): + enis = self.enis.values() + + if eni_ids: + enis = [eni for eni in enis if eni.id in eni_ids] + if len(enis) != len(eni_ids): + invalid_id = list(set(eni_ids).difference(set([eni.id for eni in enis])))[0] + raise InvalidNetworkInterfaceIdError(invalid_id) + + return generic_filter(filters, enis) + + class Instance(BotoInstance, TaggedEC2Resource): def __init__(self, ec2_backend, image_id, user_data, security_groups, **kwargs): diff --git a/moto/ec2/responses/elastic_network_interfaces.py b/moto/ec2/responses/elastic_network_interfaces.py index 09d10f451..75391b6d2 100644 --- a/moto/ec2/responses/elastic_network_interfaces.py +++ b/moto/ec2/responses/elastic_network_interfaces.py @@ -23,14 +23,9 @@ class ElasticNetworkInterfaces(BaseResponse): raise NotImplementedError('ElasticNetworkInterfaces(AmazonVPC).describe_network_interface_attribute is not yet implemented') def describe_network_interfaces(self): - # Partially implemented. Supports only network-interface-id and group-id filters + eni_ids = sequence_from_querystring('NetworkInterfaceId', self.querystring) filters = filters_from_querystring(self.querystring) - eni_ids = self._get_multi_param('NetworkInterfaceId.') - if 'network-interface-id' not in filters and eni_ids: - # Network interfaces can be filtered by passing the 'network-interface-id' - # filter or by passing the NetworkInterfaceId parameter - filters['network-interface-id'] = eni_ids - enis = self.ec2_backend.describe_network_interfaces(filters) + enis = self.ec2_backend.get_all_network_interfaces(eni_ids, filters) template = self.response_template(DESCRIBE_NETWORK_INTERFACES_RESPONSE) return template.render(enis=enis) @@ -112,7 +107,11 @@ DESCRIBE_NETWORK_INTERFACES_RESPONSE = """Primary network interface 190610284047 false - in-use + {% if eni.attachment_id %} + in-use + {% else %} + available + {% endif %} 0e:a3:a7:7b:95:a7 {% if eni.private_ip_address %} {{ eni.private_ip_address }} @@ -129,6 +128,14 @@ DESCRIBE_NETWORK_INTERFACES_RESPONSE = """ {% endfor %} + + {% for tag in eni.get_tags() %} + + {{ tag.key }} + {{ tag.value }} + + {% endfor %} + {% if eni.instance %} {{ eni.attachment_id }} @@ -145,7 +152,6 @@ DESCRIBE_NETWORK_INTERFACES_RESPONSE = """ec2-54-200-86-47.us-west-2.compute.amazonaws.com amazon - {% if eni.private_ip_address %}