diff --git a/prowler/lib/check/check.py b/prowler/lib/check/check.py index 947b7284..446a4421 100644 --- a/prowler/lib/check/check.py +++ b/prowler/lib/check/check.py @@ -24,6 +24,7 @@ except Exception: from prowler.lib.utils.utils import open_file, parse_json_file from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info +from prowler.providers.common.models import Audit_Metadata from prowler.providers.common.outputs import Provider_Output_Options @@ -316,6 +317,9 @@ def execute_checks( audit_output_options: Provider_Output_Options, ) -> list: all_findings = [] + services_executed = set() + checks_executed = set() + total_checks_to_execute = len(checks_to_execute) # Execution with the --only-logs flag if audit_output_options.only_logs: for check_name in checks_to_execute: @@ -323,7 +327,14 @@ def execute_checks( service = check_name.split("_")[0] try: check_findings = execute( - service, check_name, provider, audit_output_options, audit_info + service, + check_name, + provider, + audit_output_options, + audit_info, + services_executed, + checks_executed, + total_checks_to_execute, ) all_findings.extend(check_findings) @@ -359,7 +370,14 @@ def execute_checks( ) try: check_findings = execute( - service, check_name, provider, audit_output_options, audit_info + service, + check_name, + provider, + audit_output_options, + audit_info, + services_executed, + checks_executed, + total_checks_to_execute, ) all_findings.extend(check_findings) bar() @@ -380,11 +398,14 @@ def execute_checks( def execute( - service, + service: str, check_name: str, provider: str, audit_output_options: Provider_Output_Options, audit_info: AWS_Audit_Info, + services_executed: set, + checks_executed: set, + total_checks_to_execute: int, ): # Import check module check_module_path = ( @@ -396,6 +417,14 @@ def execute( c = check_to_execute() # Run check check_findings = run_check(c, audit_output_options) + services_executed.add(service) + checks_executed.add(check_name) + audit_info.audit_metadata = Audit_Metadata( + services_scanned=len(services_executed), + expected_checks=total_checks_to_execute, + completed_checks=len(checks_executed), + audit_progress=100 * len(checks_executed) / total_checks_to_execute, + ) report(check_findings, audit_output_options, audit_info) return check_findings diff --git a/prowler/providers/aws/lib/audit_info/audit_info.py b/prowler/providers/aws/lib/audit_info/audit_info.py index 1da6ab7b..e91b4175 100644 --- a/prowler/providers/aws/lib/audit_info/audit_info.py +++ b/prowler/providers/aws/lib/audit_info/audit_info.py @@ -23,4 +23,5 @@ current_audit_info = AWS_Audit_Info( ), audited_regions=None, organizations_metadata=None, + audit_metadata=None, ) diff --git a/prowler/providers/aws/lib/audit_info/models.py b/prowler/providers/aws/lib/audit_info/models.py index e7ad3f48..2252e320 100644 --- a/prowler/providers/aws/lib/audit_info/models.py +++ b/prowler/providers/aws/lib/audit_info/models.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from datetime import datetime +from typing import Any, Optional from boto3 import session @@ -42,3 +43,4 @@ class AWS_Audit_Info: assumed_role_info: AWS_Assume_Role audited_regions: list organizations_metadata: AWS_Organizations_Info + audit_metadata: Optional[Any] = None diff --git a/prowler/providers/azure/lib/audit_info/audit_info.py b/prowler/providers/azure/lib/audit_info/audit_info.py index 53bf08d8..0d1b8752 100644 --- a/prowler/providers/azure/lib/audit_info/audit_info.py +++ b/prowler/providers/azure/lib/audit_info/audit_info.py @@ -3,4 +3,6 @@ from prowler.providers.azure.lib.audit_info.models import ( Azure_Identity_Info, ) -azure_audit_info = Azure_Audit_Info(credentials=None, identity=Azure_Identity_Info()) +azure_audit_info = Azure_Audit_Info( + credentials=None, identity=Azure_Identity_Info(), audit_metadata=None +) diff --git a/prowler/providers/azure/lib/audit_info/models.py b/prowler/providers/azure/lib/audit_info/models.py index 10a3ef21..62619f26 100644 --- a/prowler/providers/azure/lib/audit_info/models.py +++ b/prowler/providers/azure/lib/audit_info/models.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +from typing import Any, Optional from azure.identity import DefaultAzureCredential from pydantic import BaseModel @@ -16,7 +17,9 @@ class Azure_Identity_Info(BaseModel): class Azure_Audit_Info: credentials: DefaultAzureCredential identity: Azure_Identity_Info + audit_metadata: Optional[Any] - def __init__(self, credentials, identity): + def __init__(self, credentials, identity, audit_metadata): self.credentials = credentials self.identity = identity + self.audit_metadata = audit_metadata diff --git a/prowler/providers/common/models.py b/prowler/providers/common/models.py new file mode 100644 index 00000000..d6301481 --- /dev/null +++ b/prowler/providers/common/models.py @@ -0,0 +1,8 @@ +from pydantic import BaseModel + + +class Audit_Metadata(BaseModel): + services_scanned: int + expected_checks: int + completed_checks: int + audit_progress: int diff --git a/tests/providers/common/audit_info_test.py b/tests/providers/common/audit_info_test.py index eca24ead..8d6d8a17 100644 --- a/tests/providers/common/audit_info_test.py +++ b/tests/providers/common/audit_info_test.py @@ -27,10 +27,11 @@ mock_current_audit_info = AWS_Audit_Info( assumed_role_info=None, audited_regions=["eu-west-2", "eu-west-1"], organizations_metadata=None, + audit_metadata=None, ) mock_azure_audit_info = Azure_Audit_Info( - credentials=None, identity=Azure_Identity_Info() + credentials=None, identity=Azure_Identity_Info(), audit_metadata=None ) mock_set_audit_info = Audit_Info() diff --git a/tests/providers/common/common_outputs_test.py b/tests/providers/common/common_outputs_test.py index 9041e921..691893db 100644 --- a/tests/providers/common/common_outputs_test.py +++ b/tests/providers/common/common_outputs_test.py @@ -1,18 +1,18 @@ -from prowler.providers.common.outputs import ( - Aws_Output_Options, - Azure_Output_Options, - set_provider_output_options, -) +from argparse import Namespace +from boto3 import session +from mock import patch from prowler.providers.aws.lib.audit_info.audit_info import AWS_Audit_Info from prowler.providers.azure.lib.audit_info.audit_info import ( Azure_Audit_Info, Azure_Identity_Info, ) -from boto3 import session -from mock import patch -from argparse import Namespace +from prowler.providers.common.outputs import ( + Aws_Output_Options, + Azure_Output_Options, + set_provider_output_options, +) AWS_ACCOUNT_NUMBER = "012345678912" DATETIME = "20230101120000" @@ -30,7 +30,9 @@ def mock_change_config_var(*_): class Test_Common_Output_Options: # Mocked Azure Audit Info def set_mocked_azure_audit_info(self): - audit_info = Azure_Audit_Info(credentials=None, identity=Azure_Identity_Info()) + audit_info = Azure_Audit_Info( + credentials=None, identity=Azure_Identity_Info(), audit_metadata=None + ) return audit_info # Mocked AWS Audit Info