feat(scan): add status argument (#5443)

This commit is contained in:
Pedro Martín
2024-10-17 15:27:27 +02:00
committed by GitHub
parent f7fd355dc1
commit efc60d2bf4
3 changed files with 74 additions and 1 deletions
+11
View File
@@ -25,6 +25,10 @@ class ScanBaseException(ProwlerException):
"message": "Invalid category provided.",
"remediation": "Please provide a valid category name.",
},
(2005, "ScanInvalidStatusError"): {
"message": "Invalid status provided.",
"remediation": "Please provide a valid status: FAIL, PASS, MANUAL.",
},
}
def __init__(self, code, file=None, original_exception=None, message=None):
@@ -74,3 +78,10 @@ class ScanInvalidCategoryError(ScanBaseException):
super().__init__(
2004, file=file, original_exception=original_exception, message=message
)
class ScanInvalidStatusError(ScanBaseException):
def __init__(self, file=None, original_exception=None, message=None):
super().__init__(
2005, file=file, original_exception=original_exception, message=message
)
+24 -1
View File
@@ -12,13 +12,14 @@ from prowler.lib.check.compliance import update_checks_metadata_with_compliance
from prowler.lib.check.compliance_models import Compliance
from prowler.lib.check.models import CheckMetadata
from prowler.lib.logger import logger
from prowler.lib.outputs.finding import Finding, Severity
from prowler.lib.outputs.finding import Finding, Severity, Status
from prowler.lib.scan.exceptions.exceptions import (
ScanInvalidCategoryError,
ScanInvalidCheckError,
ScanInvalidComplianceFrameworkError,
ScanInvalidServiceError,
ScanInvalidSeverityError,
ScanInvalidStatusError,
)
from prowler.providers.common.models import Audit_Metadata
from prowler.providers.common.provider import Provider
@@ -36,6 +37,7 @@ class Scan:
_progress: float = 0.0
_findings: list = []
_duration: int = 0
_status: list[str] = None
def __init__(
self,
@@ -47,6 +49,7 @@ class Scan:
severities: list[str] = None,
excluded_checks: list[str] = None,
excluded_services: list[str] = None,
status: list[str] = None,
):
"""
Scan is the class that executes the checks and yields the progress and the findings.
@@ -60,6 +63,7 @@ class Scan:
severities: list[str] -> The severities of the checks
excluded_checks: list[str] -> The checks to exclude
excluded_services: list[str] -> The services to exclude
status: list[str] -> The status of the checks
Raises:
ScanInvalidCheckError: If the check does not exist in the provider or is from another provider.
@@ -67,9 +71,22 @@ class Scan:
ScanInvalidComplianceFrameworkError: If the compliance framework does not exist in the provider.
ScanInvalidCategoryError: If the category does not exist in the provider.
ScanInvalidSeverityError: If the severity does not exist in the provider.
ScanInvalidStatusError: If the status does not exist in the provider.
"""
self._provider = provider
# Validate the status
if status:
try:
for s in status:
Status(s)
if not self._status:
self._status = []
if s not in self._status:
self._status.append(s)
except ValueError:
raise ScanInvalidStatusError(f"Invalid status provided: {s}.")
# Load bulk compliance frameworks
bulk_compliance_frameworks = Compliance.get_bulk(provider.type)
@@ -258,6 +275,12 @@ class Scan:
output_options=None,
)
# Filter the findings by the status
if self._status:
for finding in check_findings:
if finding.status not in self._status:
check_findings.remove(finding)
# Store findings
self._findings.extend(check_findings)
+39
View File
@@ -11,6 +11,7 @@ from prowler.lib.scan.exceptions.exceptions import (
ScanInvalidComplianceFrameworkError,
ScanInvalidServiceError,
ScanInvalidSeverityError,
ScanInvalidStatusError,
)
from prowler.lib.scan.scan import Scan, get_service_checks_to_execute
from tests.lib.outputs.fixtures.fixtures import generate_finding_output
@@ -376,3 +377,41 @@ class TestScan:
Scan(
mock_provider, checks=checks_to_execute, categories=["invalid_category"]
)
def test_init_invalid_status(
mock_provider,
):
checks_to_execute = set()
mock_provider.type = "aws"
with pytest.raises(ScanInvalidStatusError):
Scan(mock_provider, checks=checks_to_execute, status=["invalid_status"])
@patch("importlib.import_module")
def test_scan_filter_status(
mock_import_module,
mock_global_provider,
mock_recover_checks_from_provider,
mock_load_check_metadata,
):
mock_check_class = MagicMock()
mock_check_instance = mock_check_class.return_value
mock_check_instance.Provider = "aws"
mock_check_instance.CheckID = "accessanalyzer_enabled"
mock_check_instance.CheckTitle = "Check if IAM Access Analyzer is enabled"
mock_check_instance.Categories = []
mock_import_module.return_value = MagicMock(
accessanalyzer_enabled=mock_check_class
)
checks_to_execute = {"accessanalyzer_enabled"}
custom_checks_metadata = {}
mock_global_provider.type = "aws"
scan = Scan(mock_global_provider, checks=checks_to_execute, status=["FAIL"])
mock_load_check_metadata.assert_called_once()
mock_recover_checks_from_provider.assert_called_once_with("aws")
results = list(scan.scan(custom_checks_metadata))
assert results[0] == (100.0, [])