Fix ec2 filter by empty tag value (#3605)

* Fix ec2 filter by empty tag value

Return `None` instead of an empty string when the tag key does not exist
and replace the falsy check with a more explicit `is None`, which allows
empty string values to correctly pass through the filter comparator.

Behavior confirmed against a real AWS backend.

Closes #3603

* Make test case more explicit

Test case now pulled directly from the issue report (#3603).

Co-authored-by: Bert Blommers <bblommers@users.noreply.github.com>
This commit is contained in:
Brian Pandola 2021-01-24 04:00:25 -08:00 committed by GitHub
parent 8f4c3e4a51
commit 38124ab1c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 2 deletions

View File

@ -249,7 +249,7 @@ class TaggedEC2Resource(BaseModel):
if tag["key"] == tagname:
return tag["value"]
return ""
return None
elif filter_name == "tag-key":
return [tag["key"] for tag in tags]
elif filter_name == "tag-value":

View File

@ -458,7 +458,7 @@ def filter_internet_gateways(igws, filter_dict):
def is_filter_matching(obj, filter, filter_value):
value = obj.get_filter_value(filter)
if not filter_value:
if filter_value is None:
return False
if isinstance(value, six.string_types):

View File

@ -921,3 +921,44 @@ def test_create_image_with_tag_specification():
ex.value.response["Error"]["Message"].should.equal(
"'invalid-resource-type' is not a valid taggable resource type for this operation."
)
@mock_ec2
def test_ami_filter_by_empty_tag():
ec2 = boto3.resource("ec2", region_name="us-west-1")
client = boto3.client("ec2", region_name="us-west-1")
fake_images = []
instance = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1)[0]
for i in range(10):
image = client.create_image(
InstanceId=instance.instance_id,
Name="MyAMI{}".format(i),
Description="Test",
)
ec2.create_tags(
Resources=[image["ImageId"]],
Tags=[
{
"Key": "Base_AMI_Name",
"Value": "Deep Learning Base AMI (Amazon Linux 2) Version 31.0",
},
{"Key": "OS_Version", "Value": "AWS Linux 2"},
],
)
fake_images.append(image)
# Add release tags to some of the images in the middle
for image in fake_images[3:6]:
ec2.create_tags(
Resources=[image["ImageId"]], Tags=[{"Key": "RELEASE", "Value": ""}]
)
images_filter = [
{
"Name": "tag:Base_AMI_Name",
"Values": ["Deep Learning Base AMI (Amazon Linux 2) Version 31.0"],
},
{"Name": "tag:OS_Version", "Values": ["AWS Linux 2"]},
{"Name": "tag:RELEASE", "Values": [""]},
]
assert len(client.describe_images(Filters=images_filter)["Images"]) == 3