Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed secretsmanager list api to support filtering correctly #7511

Merged
merged 3 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion moto/ec2/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, List
from typing import List

from moto.core.base_backend import BackendDict, BaseBackend

Expand Down
28 changes: 19 additions & 9 deletions moto/secretsmanager/list_secrets/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def name_filter(secret: "FakeSecret", names: List[str]) -> bool:


def description_filter(secret: "FakeSecret", descriptions: List[str]) -> bool:
return _matcher(descriptions, [secret.description]) # type: ignore
return _matcher(descriptions, [secret.description], match_prefix=False) # type: ignore


def tag_key(secret: "FakeSecret", tag_keys: List[str]) -> bool:
Expand All @@ -30,21 +30,31 @@ def filter_all(secret: "FakeSecret", values: List[str]) -> bool:
return _matcher(values, attributes) # type: ignore


def _matcher(patterns: List[str], strings: List[str]) -> bool:
def _matcher(
patterns: List[str], strings: List[str], match_prefix: bool = True
) -> bool:
for pattern in [p for p in patterns if p.startswith("!")]:
for string in strings:
if _match_pattern(pattern[1:], string):
return False
if not _match_pattern(pattern[1:], string, match_prefix):
return True

for pattern in [p for p in patterns if not p.startswith("!")]:
for string in strings:
if _match_pattern(pattern, string):
if _match_pattern(pattern, string, match_prefix):
return True
return False


def _match_pattern(pattern: str, value: str) -> bool:
for word in pattern.split(" "):
if word not in value:
return False
def _match_pattern(pattern: str, value: str, match_prefix: bool = True) -> bool:
if match_prefix:
return value.startswith(pattern)
else:
pattern_words = pattern.split(" ")
value_words = value.split(" ")
for pattern_word in pattern_words:
# all words in value must start with pattern_word
if not any(
value_word.startswith(pattern_word) for value_word in value_words
):
return False
return True
8 changes: 7 additions & 1 deletion tests/test_secretsmanager/test_list_secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,13 @@ def test_with_filter_with_negation():
)

secret_names = list(map(lambda s: s["Name"], secrets["SecretList"]))
assert secret_names == ["baz"]
for secret_name in ["foo", "bar", "baz"]:
assert secret_name in secret_names

secrets = conn.list_secrets(Filters=[{"Key": "description", "Values": ["!o"]}])
secret_names = list(map(lambda s: s["Name"], secrets["SecretList"]))
for secret_name in ["qux", "none"]:
assert secret_name in secret_names


@mock_aws
Expand Down