Merge branch 'feature/vpc-filters'

This commit is contained in:
Omer Katz 2014-10-01 15:56:23 +03:00
commit 4ec95bac74
3 changed files with 111 additions and 9 deletions

View File

@ -1,9 +1,9 @@
from __future__ import unicode_literals
import six
import copy
import itertools
from collections import defaultdict
import six
import boto
from boto.ec2.instance import Instance as BotoInstance, Reservation
from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
@ -70,7 +70,7 @@ from .utils import (
random_volume_id,
random_vpc_id,
random_vpc_peering_connection_id,
)
generic_filter)
class InstanceState(object):
@ -93,6 +93,12 @@ class TaggedEC2Instance(object):
if tag['key'] == tagname:
return tag['value']
if filter_name == 'tag-key':
return [tag['key'] for tag in tags]
if filter_name == 'tag-value':
return [tag['value'] for tag in tags]
class NetworkInterface(object):
def __init__(self, subnet, private_ip_address, device_index=0, public_ip_auto_assign=True, group_ids=None):
@ -1159,7 +1165,7 @@ class VPC(TaggedEC2Instance):
filter_value = super(VPC, self).get_filter_value(filter_name)
if not filter_value:
if filter_value is None:
msg = "The filter '{0}' for DescribeVPCs has not been" \
" implemented in Moto yet. Feel free to open an issue at" \
" https://github.com/spulec/moto/issues".format(filter_name)
@ -1198,11 +1204,7 @@ class VPCBackend(object):
else:
vpcs = self.vpcs.values()
if filters:
for (_filter, _filter_value) in filters.items():
vpcs = [ vpc for vpc in vpcs if vpc.get_filter_value(_filter) in _filter_value ]
return vpcs
return generic_filter(filters, vpcs)
def delete_vpc(self, vpc_id):
# Delete route table if only main route table remains.

View File

@ -278,6 +278,27 @@ def filter_reservations(reservations, filter_dict):
return result
def is_filter_matching(obj, filter, filter_value):
value = obj.get_filter_value(filter)
if isinstance(value, six.string_types):
return value in filter_value
try:
value = set(value)
return (value and value.issubset(filter_value)) or value.issuperset(filter_value)
except TypeError:
return value in filter_value
def generic_filter(filters, objects):
if filters:
for (_filter, _filter_value) in filters.items():
objects = [obj for obj in objects if is_filter_matching(obj, _filter, _filter_value)]
return objects
# not really random ( http://xkcd.com/221/ )
def random_key_pair():
return {

View File

@ -1,6 +1,6 @@
from __future__ import unicode_literals
# Ensure 'assert_raises' context manager support for Python 2.6
#import tests.backport_assert_raises
# import tests.backport_assert_raises
from nose.tools import assert_raises
import boto
@ -128,4 +128,83 @@ def test_vpc_get_by_tag():
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v.id, vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_key_superset():
conn = boto.connect_vpc()
vpc1 = conn.create_vpc("10.0.0.0/16")
vpc2 = conn.create_vpc("10.0.0.0/16")
vpc3 = conn.create_vpc("10.0.0.0/24")
vpc1.add_tag('Name', 'TestVPC')
vpc1.add_tag('Key', 'TestVPC2')
vpc2.add_tag('Name', 'TestVPC')
vpc2.add_tag('Key', 'TestVPC2')
vpc3.add_tag('Key', 'TestVPC2')
vpcs = conn.get_all_vpcs(filters={'tag-key': 'Name'})
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v.id, vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_key_subset():
conn = boto.connect_vpc()
vpc1 = conn.create_vpc("10.0.0.0/16")
vpc2 = conn.create_vpc("10.0.0.0/16")
vpc3 = conn.create_vpc("10.0.0.0/24")
vpc1.add_tag('Name', 'TestVPC')
vpc1.add_tag('Key', 'TestVPC2')
vpc2.add_tag('Name', 'TestVPC')
vpc2.add_tag('Key', 'TestVPC2')
vpc3.add_tag('Test', 'TestVPC2')
vpcs = conn.get_all_vpcs(filters={'tag-key': ['Name', 'Key']})
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v.id, vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_value_superset():
conn = boto.connect_vpc()
vpc1 = conn.create_vpc("10.0.0.0/16")
vpc2 = conn.create_vpc("10.0.0.0/16")
vpc3 = conn.create_vpc("10.0.0.0/24")
vpc1.add_tag('Name', 'TestVPC')
vpc1.add_tag('Key', 'TestVPC2')
vpc2.add_tag('Name', 'TestVPC')
vpc2.add_tag('Key', 'TestVPC2')
vpc3.add_tag('Key', 'TestVPC2')
vpcs = conn.get_all_vpcs(filters={'tag-value': 'TestVPC'})
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v.id, vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)
@mock_ec2
def test_vpc_get_by_tag_value_subset():
conn = boto.connect_vpc()
vpc1 = conn.create_vpc("10.0.0.0/16")
vpc2 = conn.create_vpc("10.0.0.0/16")
vpc3 = conn.create_vpc("10.0.0.0/24")
vpc1.add_tag('Name', 'TestVPC')
vpc1.add_tag('Key', 'TestVPC2')
vpc2.add_tag('Name', 'TestVPC')
vpc2.add_tag('Key', 'TestVPC2')
vpcs = conn.get_all_vpcs(filters={'tag-value': ['TestVPC', 'TestVPC2']})
vpcs.should.have.length_of(2)
vpc_ids = tuple(map(lambda v: v.id, vpcs))
vpc1.id.should.be.within(vpc_ids)
vpc2.id.should.be.within(vpc_ids)