fix(compliance): add manual status to requirements (#7938)

This commit is contained in:
Víctor Fernández Poyatos
2025-06-05 10:54:51 +02:00
committed by GitHub
parent d89df83904
commit 6332427e5e
5 changed files with 59 additions and 17 deletions
+7 -7
View File
@@ -190,6 +190,8 @@ def generate_compliance_overview_template(prowler_compliance: dict):
total_checks = len(requirement.Checks)
checks_dict = {check: None for check in requirement.Checks}
req_status_val = "MANUAL" if total_checks == 0 else "PASS"
# Build requirement dictionary
requirement_dict = {
"name": requirement.Name or requirement.Id,
@@ -204,20 +206,18 @@ def generate_compliance_overview_template(prowler_compliance: dict):
"manual": 0,
"total": total_checks,
},
"status": "PASS",
"status": req_status_val,
}
# Update requirements status
if total_checks == 0:
# Update requirements status counts for the framework
if req_status_val == "MANUAL":
requirements_status["manual"] += 1
elif req_status_val == "PASS":
requirements_status["passed"] += 1
# Add requirement to compliance requirements
compliance_requirements[requirement.Id] = requirement_dict
# Calculate pending requirements
pending_requirements = total_requirements - requirements_status["manual"]
requirements_status["passed"] = pending_requirements
# Build compliance dictionary
compliance_dict = {
"framework": compliance_data.Framework,
+6 -6
View File
@@ -1,12 +1,12 @@
from unittest.mock import patch, MagicMock
from unittest.mock import MagicMock, patch
from api.compliance import (
generate_compliance_overview_template,
generate_scan_compliance,
get_prowler_provider_checks,
get_prowler_provider_compliance,
load_prowler_compliance,
load_prowler_checks,
generate_scan_compliance,
generate_compliance_overview_template,
load_prowler_compliance,
)
from api.models import Provider
@@ -69,7 +69,7 @@ class TestCompliance:
load_prowler_compliance()
from api.compliance import PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE, PROWLER_CHECKS
from api.compliance import PROWLER_CHECKS, PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE
assert PROWLER_COMPLIANCE_OVERVIEW_TEMPLATE == {
"template_key": "template_value"
@@ -268,7 +268,7 @@ class TestCompliance:
"manual": 0,
"total": 0,
},
"status": "PASS",
"status": "MANUAL",
},
},
"requirements_status": {
+18
View File
@@ -4837,6 +4837,24 @@ class TestComplianceOverviewViewSet:
assert "description" in attributes
assert "status" in attributes
def test_compliance_overview_requirements_manual(
self, authenticated_client, compliance_requirements_overviews_fixture
):
scan_id = str(compliance_requirements_overviews_fixture[0].scan.id)
# Compliance with a manual requirement
compliance_id = "aws_account_security_onboarding_aws"
response = authenticated_client.get(
reverse("complianceoverview-requirements"),
{
"filter[scan_id]": scan_id,
"filter[compliance_id]": compliance_id,
},
)
assert response.status_code == status.HTTP_200_OK
data = response.json()["data"]
assert data[-1]["attributes"]["status"] == "MANUAL"
def test_compliance_overview_requirements_missing_scan_id(
self, authenticated_client
):
+11 -3
View File
@@ -2733,7 +2733,10 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
"requirement_id", "framework", "version", "description"
)
.distinct()
.annotate(total_instances=Count("id"))
.annotate(
total_instances=Count("id"),
manual_count=Count("id", filter=Q(requirement_status="MANUAL")),
)
)
passed_instances = (
@@ -2751,8 +2754,13 @@ class ComplianceOverviewViewSet(BaseRLSViewSet, TaskManagementMixin):
requirement_id = requirement["requirement_id"]
total_instances = requirement["total_instances"]
passed_count = passed_counts.get(requirement_id, 0)
requirement_status = "PASS" if passed_count == total_instances else "FAIL"
is_manual = requirement["manual_count"] == total_instances
if is_manual:
requirement_status = "MANUAL"
elif passed_count == total_instances:
requirement_status = "PASS"
else:
requirement_status = "FAIL"
requirements_summary.append(
{
+17 -1
View File
@@ -846,8 +846,23 @@ def compliance_requirements_overviews_fixture(scans_fixture, tenants_fixture):
total_checks=2,
)
# Create a different compliance framework for testing
requirement_overview5 = ComplianceRequirementOverview.objects.create(
tenant=tenant,
scan=scan1,
compliance_id="aws_account_security_onboarding_aws",
framework="AWS-Account-Security-Onboarding",
version="1.0",
description="Description for AWS Account Security Onboarding (MANUAL)",
region="eu-west-2",
requirement_id="requirement3",
requirement_status=StatusChoices.MANUAL,
passed_checks=0,
failed_checks=0,
total_checks=0,
)
# Create a different compliance framework for testing
requirement_overview6 = ComplianceRequirementOverview.objects.create(
tenant=tenant,
scan=scan1,
compliance_id="cis_1.4_aws",
@@ -868,6 +883,7 @@ def compliance_requirements_overviews_fixture(scans_fixture, tenants_fixture):
requirement_overview3,
requirement_overview4,
requirement_overview5,
requirement_overview6,
)