mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
feat(scan): add status argument (#5443)
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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, [])
|
||||
|
||||
Reference in New Issue
Block a user