Extend filtering support for elastic network interfaces

This commit is contained in:
Yann Lambret 2016-05-08 00:19:01 +02:00
parent 68de6feb01
commit fdadd24ad3
2 changed files with 49 additions and 10 deletions

View File

@ -152,7 +152,7 @@ class TaggedEC2Resource(object):
return [tag['value'] for tag in tags] 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, def __init__(self, ec2_backend, subnet, private_ip_address, device_index=0,
public_ip_auto_assign=True, group_ids=None): public_ip_auto_assign=True, group_ids=None):
self.ec2_backend = ec2_backend self.ec2_backend = ec2_backend
@ -236,6 +236,27 @@ class NetworkInterface(object):
def physical_resource_id(self): def physical_resource_id(self):
return self.id 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): class NetworkInterfaceBackend(object):
def __init__(self): def __init__(self):
@ -301,6 +322,18 @@ class NetworkInterfaceBackend(object):
group = self.get_security_group_from_id(group_id) group = self.get_security_group_from_id(group_id)
eni._group_set = [group] 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): class Instance(BotoInstance, TaggedEC2Resource):
def __init__(self, ec2_backend, image_id, user_data, security_groups, **kwargs): def __init__(self, ec2_backend, image_id, user_data, security_groups, **kwargs):

View File

@ -23,14 +23,9 @@ class ElasticNetworkInterfaces(BaseResponse):
raise NotImplementedError('ElasticNetworkInterfaces(AmazonVPC).describe_network_interface_attribute is not yet implemented') raise NotImplementedError('ElasticNetworkInterfaces(AmazonVPC).describe_network_interface_attribute is not yet implemented')
def describe_network_interfaces(self): 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) filters = filters_from_querystring(self.querystring)
eni_ids = self._get_multi_param('NetworkInterfaceId.') enis = self.ec2_backend.get_all_network_interfaces(eni_ids, filters)
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)
template = self.response_template(DESCRIBE_NETWORK_INTERFACES_RESPONSE) template = self.response_template(DESCRIBE_NETWORK_INTERFACES_RESPONSE)
return template.render(enis=enis) return template.render(enis=enis)
@ -112,7 +107,11 @@ DESCRIBE_NETWORK_INTERFACES_RESPONSE = """<DescribeNetworkInterfacesResponse xml
<description>Primary network interface</description> <description>Primary network interface</description>
<ownerId>190610284047</ownerId> <ownerId>190610284047</ownerId>
<requesterManaged>false</requesterManaged> <requesterManaged>false</requesterManaged>
{% if eni.attachment_id %}
<status>in-use</status> <status>in-use</status>
{% else %}
<status>available</status>
{% endif %}
<macAddress>0e:a3:a7:7b:95:a7</macAddress> <macAddress>0e:a3:a7:7b:95:a7</macAddress>
{% if eni.private_ip_address %} {% if eni.private_ip_address %}
<privateIpAddress>{{ eni.private_ip_address }}</privateIpAddress> <privateIpAddress>{{ eni.private_ip_address }}</privateIpAddress>
@ -129,6 +128,14 @@ DESCRIBE_NETWORK_INTERFACES_RESPONSE = """<DescribeNetworkInterfacesResponse xml
</item> </item>
{% endfor %} {% endfor %}
</groupSet> </groupSet>
<tagSet>
{% for tag in eni.get_tags() %}
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
{% endfor %}
</tagSet>
{% if eni.instance %} {% if eni.instance %}
<attachment> <attachment>
<attachmentId>{{ eni.attachment_id }}</attachmentId> <attachmentId>{{ eni.attachment_id }}</attachmentId>
@ -145,7 +152,6 @@ DESCRIBE_NETWORK_INTERFACES_RESPONSE = """<DescribeNetworkInterfacesResponse xml
<publicDnsName>ec2-54-200-86-47.us-west-2.compute.amazonaws.com</publicDnsName> <publicDnsName>ec2-54-200-86-47.us-west-2.compute.amazonaws.com</publicDnsName>
<ipOwnerId>amazon</ipOwnerId> <ipOwnerId>amazon</ipOwnerId>
</association> </association>
<tagSet/>
{% if eni.private_ip_address %} {% if eni.private_ip_address %}
<privateIpAddressesSet> <privateIpAddressesSet>
<item> <item>