Implement InternetGateway filters support

More information about IGW filters: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInternetGateways.html#query-DescribeInternetGateways-filters
This commit is contained in:
Hugo Lopes Tavares 2014-11-05 12:11:56 -05:00
parent e92c2ae610
commit 32af875386
4 changed files with 137 additions and 22 deletions

View File

@ -1867,6 +1867,13 @@ class InternetGateway(TaggedEC2Resource):
def physical_resource_id(self):
return self.id
@property
def attachment_state(self):
if self.vpc:
return "available"
else:
return "detached"
class InternetGatewayBackend(object):
def __init__(self):

View File

@ -1,8 +1,13 @@
from __future__ import unicode_literals
from moto.core.responses import BaseResponse
from moto.ec2.utils import sequence_from_querystring
from moto.ec2.utils import (
sequence_from_querystring,
filters_from_querystring,
filter_internet_gateways,
)
from jinja2 import Template
class InternetGateways(BaseResponse):
def attach_internet_gateway(self):
igw_id = self.querystring.get("InternetGatewayId", [None])[0]
@ -23,15 +28,16 @@ class InternetGateways(BaseResponse):
return template.render()
def describe_internet_gateways(self):
if "Filter.1.Name" in self.querystring:
raise NotImplementedError(
"Filtering not supported in describe_internet_gateways.")
elif "InternetGatewayId.1" in self.querystring:
if "InternetGatewayId.1" in self.querystring:
igw_ids = sequence_from_querystring(
"InternetGatewayId", self.querystring)
igws = self.ec2_backend.describe_internet_gateways(igw_ids)
else:
igws = self.ec2_backend.describe_internet_gateways()
filter_dict = filters_from_querystring(self.querystring)
igws = filter_internet_gateways(igws, filter_dict)
template = Template(DESCRIBE_INTERNET_GATEWAYS_RESPONSE)
return template.render(internet_gateways=igws)

View File

@ -269,17 +269,9 @@ def keypair_names_from_querystring(querystring_dict):
return keypair_names
filter_dict_attribute_mapping = {
'instance-state-name': 'state',
'instance-id': 'id',
'state-reason-code': '_state_reason.code',
'source-dest-check': 'source_dest_check',
'vpc-id': 'vpc_id',
}
def get_instance_value(instance, instance_attr):
keys = instance_attr.split('.')
val = instance
def get_object_value(obj, attr):
keys = attr.split('.')
val = obj
for key in keys:
if hasattr(val, key):
val = getattr(val, key)
@ -289,18 +281,40 @@ def get_instance_value(instance, instance_attr):
return None
return val
def is_tag_filter(filter_name):
return filter_name.startswith('tag:')
def get_obj_tag(obj, filter_name):
tag_name = filter_name.replace('tag:', '', 1)
tags = dict((tag['key'], tag['value']) for tag in obj.get_tags())
return tags.get(tag_name)
def tag_filter_matches(obj, filter_name, filter_values):
tag_value = get_obj_tag(obj, filter_name)
return tag_value in filter_values
filter_dict_attribute_mapping = {
'instance-state-name': 'state',
'instance-id': 'id',
'state-reason-code': '_state_reason.code',
'source-dest-check': 'source_dest_check',
'vpc-id': 'vpc_id',
}
def passes_filter_dict(instance, filter_dict):
for filter_name, filter_values in filter_dict.items():
if filter_name in filter_dict_attribute_mapping:
instance_attr = filter_dict_attribute_mapping[filter_name]
instance_value = get_instance_value(instance, instance_attr)
instance_value = get_object_value(instance, instance_attr)
if instance_value not in filter_values:
return False
elif filter_name.startswith('tag:'):
tags = dict((tag['key'], tag['value']) for tag in instance.get_tags())
tag_name = filter_name.replace('tag:', '', 1)
tag_value = tags.get(tag_name)
if tag_value not in filter_values:
elif is_tag_filter(filter_name):
if not tag_filter_matches(instance, filter_name, filter_values):
return False
else:
raise NotImplementedError(
@ -322,6 +336,37 @@ def filter_reservations(reservations, filter_dict):
return result
filter_dict_igw_mapping = {
"attachment.vpc-id": "vpc.id",
"attachment.state": "attachment_state",
"internet-gateway-id": "id",
}
def passes_igw_filter_dict(igw, filter_dict):
for filter_name, filter_values in filter_dict.items():
if filter_name in filter_dict_igw_mapping:
igw_attr = filter_dict_igw_mapping[filter_name]
if get_object_value(igw, igw_attr) not in filter_values:
return False
elif is_tag_filter(filter_name):
if not tag_filter_matches(igw, filter_name, filter_values):
return False
else:
raise NotImplementedError(
"Internet Gateway filter dicts have not been implemented in Moto for '%s' yet. Feel free to open an issue at https://github.com/spulec/moto/issues",
filter_name)
return True
def filter_internet_gateways(igws, filter_dict):
result = []
for igw in igws:
if passes_igw_filter_dict(igw, filter_dict):
result.append(igw)
return result
def is_filter_matching(obj, filter, filter_value):
value = obj.get_filter_value(filter)

View File

@ -163,3 +163,60 @@ def test_igw_desribe_bad_id():
cm.exception.code.should.equal('InvalidInternetGatewayID.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2
def test_igw_filter_by_vpc_id():
""" internet gateway filter by vpc id """
conn = boto.connect_vpc('the_key', 'the_secret')
igw1 = conn.create_internet_gateway()
igw2 = conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw1.id, vpc.id)
result = conn.get_all_internet_gateways(filters={"attachment.vpc-id": vpc.id})
result.should.have.length_of(1)
result[0].id.should.equal(igw1.id)
@mock_ec2
def test_igw_filter_by_tags():
""" internet gateway filter by vpc id """
conn = boto.connect_vpc('the_key', 'the_secret')
igw1 = conn.create_internet_gateway()
igw2 = conn.create_internet_gateway()
igw1.add_tag("tests", "yes")
result = conn.get_all_internet_gateways(filters={"tag:tests": "yes"})
result.should.have.length_of(1)
result[0].id.should.equal(igw1.id)
@mock_ec2
def test_igw_filter_by_internet_gateway_id():
""" internet gateway filter by internet gateway id """
conn = boto.connect_vpc('the_key', 'the_secret')
igw1 = conn.create_internet_gateway()
igw2 = conn.create_internet_gateway()
result = conn.get_all_internet_gateways(filters={"internet-gateway-id": igw1.id})
result.should.have.length_of(1)
result[0].id.should.equal(igw1.id)
@mock_ec2
def test_igw_filter_by_attachment_state():
""" internet gateway filter by attachment state """
conn = boto.connect_vpc('the_key', 'the_secret')
igw1 = conn.create_internet_gateway()
igw2 = conn.create_internet_gateway()
vpc = conn.create_vpc(VPC_CIDR)
conn.attach_internet_gateway(igw1.id, vpc.id)
result = conn.get_all_internet_gateways(filters={"attachment.state": "available"})
result.should.have.length_of(1)
result[0].id.should.equal(igw1.id)