mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-03-22 03:08:23 +00:00
fix(iac): include resource line range in finding UID to prevent duplicates (#10241)
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
This commit is contained in:
@@ -453,6 +453,9 @@ class Finding(BaseModel):
|
||||
f"{output_data['region']}-{output_data['resource_name']}"
|
||||
)
|
||||
|
||||
if provider.type == "iac" and output_data.get("resource_line_range"):
|
||||
output_data["uid"] += f"-{output_data['resource_line_range']}"
|
||||
|
||||
if not output_data["resource_uid"]:
|
||||
logger.error(
|
||||
f"Check {check_output.check_metadata.CheckID} has no resource_uid."
|
||||
|
||||
@@ -302,7 +302,12 @@ class Scan:
|
||||
|
||||
for report in iac_reports:
|
||||
# Generate unique UID for the finding
|
||||
finding_uid = f"{report.check_metadata.CheckID}-{report.resource_name}-{report.resource_line_range}"
|
||||
finding_uid = (
|
||||
f"prowler-iac-{report.check_metadata.CheckID}-iac-"
|
||||
f"{report.region}-{report.resource_name}"
|
||||
)
|
||||
if report.resource_line_range:
|
||||
finding_uid += f"-{report.resource_line_range}"
|
||||
|
||||
# Convert status string to Status enum
|
||||
status_enum = (
|
||||
|
||||
@@ -723,6 +723,10 @@ class TestFinding:
|
||||
assert finding_output.resource_name == "aws_s3_bucket.example"
|
||||
assert finding_output.resource_uid == "aws_s3_bucket.example"
|
||||
assert finding_output.region == "main" # Branch name, not line range
|
||||
assert (
|
||||
finding_output.uid
|
||||
== "prowler-iac-service_check_id-iac-main-aws_s3_bucket.example-1:5"
|
||||
)
|
||||
assert finding_output.status == Status.PASS
|
||||
assert finding_output.status_extended == "mock_status_extended"
|
||||
assert finding_output.muted is False
|
||||
@@ -737,6 +741,35 @@ class TestFinding:
|
||||
assert finding_output.metadata.SubServiceName == ""
|
||||
assert finding_output.metadata.ResourceIdTemplate == ""
|
||||
|
||||
def test_generate_output_iac_empty_line_range(self):
|
||||
provider = MagicMock()
|
||||
provider.type = "iac"
|
||||
provider.provider_uid = None
|
||||
provider.scan_repository_url = "https://github.com/user/repo"
|
||||
provider.auth_method = "No auth"
|
||||
|
||||
check_output = MagicMock()
|
||||
check_output.file_path = "/path/to/iac/main.tf"
|
||||
check_output.resource_name = "main.tf"
|
||||
check_output.resource_path = "/path/to/iac/main.tf"
|
||||
check_output.resource_line_range = ""
|
||||
check_output.region = "main"
|
||||
check_output.resource = {"resource": "main.tf", "value": {}}
|
||||
check_output.resource_details = ""
|
||||
check_output.status = Status.PASS
|
||||
check_output.status_extended = "No issues found"
|
||||
check_output.muted = False
|
||||
check_output.check_metadata = mock_check_metadata(provider="iac")
|
||||
check_output.compliance = {}
|
||||
|
||||
output_options = MagicMock()
|
||||
output_options.unix_timestamp = False
|
||||
|
||||
finding_output = Finding.generate_output(provider, check_output, output_options)
|
||||
|
||||
assert isinstance(finding_output, Finding)
|
||||
assert finding_output.uid == "prowler-iac-service_check_id-iac-main-main.tf"
|
||||
|
||||
def assert_keys_lowercase(self, d):
|
||||
for k, v in d.items():
|
||||
assert k.islower()
|
||||
|
||||
Reference in New Issue
Block a user