diff --git a/moto/ec2/utils.py b/moto/ec2/utils.py index e07367081..d9ebb4258 100644 --- a/moto/ec2/utils.py +++ b/moto/ec2/utils.py @@ -341,15 +341,19 @@ def get_obj_tag_values(obj): return tags def tag_filter_matches(obj, filter_name, filter_values): + regex_filters = [re.compile(simple_aws_filter_to_re(f)) for f in filter_values] if filter_name == 'tag-key': - tag_names = get_obj_tag_names(obj) - return len(set(filter_values).intersection(tag_names)) > 0 + tag_values = get_obj_tag_names(obj) elif filter_name == 'tag-value': tag_values = get_obj_tag_values(obj) - return len(set(filter_values).intersection(tag_values)) > 0 else: - tag_value = get_obj_tag(obj, filter_name) - return tag_value in filter_values + tag_values = [get_obj_tag(obj, filter_name) or ''] + + for tag_value in tag_values: + if any(regex.match(tag_value) for regex in regex_filters): + return True + + return False filter_dict_attribute_mapping = { diff --git a/tests/test_ec2/test_tags.py b/tests/test_ec2/test_tags.py index d8b585842..a25d31e2d 100644 --- a/tests/test_ec2/test_tags.py +++ b/tests/test_ec2/test_tags.py @@ -345,3 +345,23 @@ def test_retrieved_snapshots_must_contain_their_tags(): # Check whether tag is present with correct value retrieved_tags[tag_key].should.equal(tag_value) + + +@mock_ec2 +def test_filter_instances_by_wildcard_tags(): + conn = boto.connect_ec2(aws_access_key_id='the_key', aws_secret_access_key='the_secret') + reservation = conn.run_instances('ami-1234abcd') + instance_a = reservation.instances[0] + instance_a.add_tag("Key1", "Value1") + reservation_b = conn.run_instances('ami-1234abcd') + instance_b = reservation_b.instances[0] + instance_b.add_tag("Key1", "Value2") + + reservations = conn.get_all_instances(filters={'tag:Key1': 'Value*'}) + reservations.should.have.length_of(2) + + reservations = conn.get_all_instances(filters={'tag-key': 'Key*'}) + reservations.should.have.length_of(2) + + reservations = conn.get_all_instances(filters={'tag-value': 'Value*'}) + reservations.should.have.length_of(2)