mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-03-22 03:08:23 +00:00
feat(findings): Add resource_tag filters for findings endpoint (#6527)
This commit is contained in:
committed by
GitHub
parent
f9a3b5f3cd
commit
d7b40905ff
@@ -319,6 +319,27 @@ class FindingFilter(FilterSet):
|
||||
field_name="resources__type", lookup_expr="icontains"
|
||||
)
|
||||
|
||||
resource_tag_key = CharFilter(field_name="resources__tags__key")
|
||||
resource_tag_key__in = CharInFilter(
|
||||
field_name="resources__tags__key", lookup_expr="in"
|
||||
)
|
||||
resource_tag_key__icontains = CharFilter(
|
||||
field_name="resources__tags__key", lookup_expr="icontains"
|
||||
)
|
||||
resource_tag_value = CharFilter(field_name="resources__tags__value")
|
||||
resource_tag_value__in = CharInFilter(
|
||||
field_name="resources__tags__value", lookup_expr="in"
|
||||
)
|
||||
resource_tag_value__icontains = CharFilter(
|
||||
field_name="resources__tags__value", lookup_expr="icontains"
|
||||
)
|
||||
resource_tags = CharInFilter(
|
||||
method="filter_resource_tag",
|
||||
lookup_expr="in",
|
||||
help_text="Filter by resource tags `key:value` pairs.\nMultiple values may be "
|
||||
"separated by commas.",
|
||||
)
|
||||
|
||||
scan = UUIDFilter(method="filter_scan_id")
|
||||
scan__in = UUIDInFilter(method="filter_scan_id_in")
|
||||
|
||||
@@ -353,6 +374,12 @@ class FindingFilter(FilterSet):
|
||||
},
|
||||
}
|
||||
|
||||
@property
|
||||
def qs(self):
|
||||
# Force distinct results to prevent duplicates with many-to-many relationships
|
||||
parent_qs = super().qs
|
||||
return parent_qs.distinct()
|
||||
|
||||
# Convert filter values to UUIDv7 values for use with partitioning
|
||||
def filter_scan_id(self, queryset, name, value):
|
||||
try:
|
||||
@@ -426,6 +453,16 @@ class FindingFilter(FilterSet):
|
||||
|
||||
return queryset.filter(id__lte=end).filter(inserted_at__lte=value)
|
||||
|
||||
def filter_resource_tag(self, queryset, name, value):
|
||||
overall_query = Q()
|
||||
for key_value_pair in value:
|
||||
tag_key, tag_value = key_value_pair.split(":", 1)
|
||||
overall_query |= Q(
|
||||
resources__tags__key__icontains=tag_key,
|
||||
resources__tags__value__icontains=tag_value,
|
||||
)
|
||||
return queryset.filter(overall_query).distinct()
|
||||
|
||||
@staticmethod
|
||||
def maybe_date_to_datetime(value):
|
||||
dt = value
|
||||
|
||||
@@ -477,6 +477,51 @@ paths:
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tag_key]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_key__icontains]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_key__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tag_value]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_value__icontains]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_value__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tags]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: |-
|
||||
Filter by resource tags `key:value` pairs.
|
||||
Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_type]
|
||||
schema:
|
||||
@@ -983,6 +1028,51 @@ paths:
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tag_key]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_key__icontains]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_key__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tag_value]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_value__icontains]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_value__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tags]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: |-
|
||||
Filter by resource tags `key:value` pairs.
|
||||
Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_type]
|
||||
schema:
|
||||
@@ -1410,6 +1500,51 @@ paths:
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tag_key]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_key__icontains]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_key__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tag_value]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_value__icontains]
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: filter[resource_tag_value__in]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_tags]
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: |-
|
||||
Filter by resource tags `key:value` pairs.
|
||||
Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- in: query
|
||||
name: filter[resource_type]
|
||||
schema:
|
||||
|
||||
@@ -2444,6 +2444,15 @@ class TestFindingViewSet:
|
||||
("search", "ec2", 2),
|
||||
# full text search on finding tags
|
||||
("search", "value2", 2),
|
||||
("resource_tag_key", "key", 2),
|
||||
("resource_tag_key__in", "key,key2", 2),
|
||||
("resource_tag_key__icontains", "key", 2),
|
||||
("resource_tag_value", "value", 2),
|
||||
("resource_tag_value__in", "value,value2", 2),
|
||||
("resource_tag_value__icontains", "value", 2),
|
||||
("resource_tags", "key:value", 2),
|
||||
("resource_tags", "not:exists", 0),
|
||||
("resource_tags", "not:exists,key:value", 2),
|
||||
]
|
||||
),
|
||||
)
|
||||
@@ -2592,7 +2601,7 @@ class TestFindingViewSet:
|
||||
|
||||
expected_services = {"ec2", "s3"}
|
||||
expected_regions = {"eu-west-1", "us-east-1"}
|
||||
expected_tags = {"key": "value", "key2": "value2"}
|
||||
expected_tags = {"key": ["value"], "key2": ["value2"]}
|
||||
expected_resource_types = {"prowler-test"}
|
||||
|
||||
assert data["data"]["type"] == "findings-metadata"
|
||||
@@ -2619,7 +2628,7 @@ class TestFindingViewSet:
|
||||
|
||||
expected_services = {"s3"}
|
||||
expected_regions = {"eu-west-1"}
|
||||
expected_tags = {"key": "value", "key2": "value2"}
|
||||
expected_tags = {"key": ["value"], "key2": ["value2"]}
|
||||
expected_resource_types = {"prowler-test"}
|
||||
|
||||
assert data["data"]["type"] == "findings-metadata"
|
||||
|
||||
@@ -1414,7 +1414,14 @@ class FindingViewSet(BaseRLSViewSet):
|
||||
if result["tags"] is None:
|
||||
result["tags"] = []
|
||||
|
||||
result["tags"] = {t["key"]: t["value"] for t in result["tags"]}
|
||||
tags_dict = {}
|
||||
for t in result["tags"]:
|
||||
key, value = t["key"], t["value"]
|
||||
if key not in tags_dict:
|
||||
tags_dict[key] = []
|
||||
tags_dict[key].append(value)
|
||||
|
||||
result["tags"] = tags_dict
|
||||
|
||||
serializer = self.get_serializer(
|
||||
data=result,
|
||||
|
||||
Reference in New Issue
Block a user