diff --git a/prowler/providers/common/provider.py b/prowler/providers/common/provider.py index a47dabe6c7..b89ae5dacf 100644 --- a/prowler/providers/common/provider.py +++ b/prowler/providers/common/provider.py @@ -180,7 +180,18 @@ class Provider(ABC): ) if not isinstance(Provider._global, provider_class): - global_provider = provider_class(arguments) + if "Gcp" in provider_class_name: + global_provider = provider_class( + arguments.project_id, + arguments.excluded_project_id, + arguments.credentials_file, + arguments.impersonate_service_account, + arguments.list_project_id, + arguments.config_file, + arguments.fixer_config, + ) + else: + global_provider = provider_class(arguments) Provider._global = global_provider except TypeError as error: diff --git a/prowler/providers/gcp/gcp_provider.py b/prowler/providers/gcp/gcp_provider.py index b56408c725..d1f253d9a7 100644 --- a/prowler/providers/gcp/gcp_provider.py +++ b/prowler/providers/gcp/gcp_provider.py @@ -38,13 +38,30 @@ class GcpProvider(Provider): # TODO: this is not optional, enforce for all providers audit_metadata: Audit_Metadata - def __init__(self, arguments): + def __init__( + self, + project_ids: list = None, + excluded_project_ids: list = None, + credentials_file: str = None, + impersonate_service_account: str = None, + list_project_ids: bool = False, + config_file: str = None, + fixer_config: str = None, + ): + """ + GCP Provider constructor + + Args: + project_ids: list + excluded_project_ids: list + credentials_file: str + impersonate_service_account: str + list_project_ids: bool + config_file: str + fixer_config: str + """ logger.info("Instantiating GCP Provider ...") - input_project_ids = arguments.project_id - excluded_project_ids = arguments.excluded_project_id - credentials_file = arguments.credentials_file - self._impersonated_service_account = arguments.impersonate_service_account - list_project_ids = arguments.list_project_id + self._impersonated_service_account = impersonate_service_account self._session = self.setup_session( credentials_file, self._impersonated_service_account @@ -56,10 +73,11 @@ class GcpProvider(Provider): accessible_projects = self.get_projects() if not accessible_projects: logger.critical("No Project IDs can be accessed via Google Credentials.") - sys.exit(1) + # TODO: add custom exception once we have the GCP exceptions + raise SystemExit - if input_project_ids: - for input_project in input_project_ids: + if project_ids: + for input_project in project_ids: for accessible_project in accessible_projects: if self.is_project_matching(input_project, accessible_project): self._projects[accessible_project] = accessible_projects[ @@ -88,7 +106,8 @@ class GcpProvider(Provider): logger.critical( "No Input Project IDs can be accessed via Google Credentials." ) - sys.exit(1) + # TODO: add custom exception once we have the GCP exceptions + raise SystemExit if list_project_ids: print( @@ -105,12 +124,8 @@ class GcpProvider(Provider): # TODO: move this to the providers, pending for AWS, GCP, AZURE and K8s # Audit Config - self._audit_config = load_and_validate_config_file( - self._type, arguments.config_file - ) - self._fixer_config = load_and_validate_config_file( - self._type, arguments.fixer_config - ) + self._audit_config = load_and_validate_config_file(self._type, config_file) + self._fixer_config = load_and_validate_config_file(self._type, fixer_config) @property def identity(self): @@ -241,7 +256,7 @@ class GcpProvider(Provider): logger.critical( f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - sys.exit(1) + raise error @staticmethod def test_connection( @@ -272,9 +287,7 @@ class GcpProvider(Provider): "Cloud Resource Manager API has not been used before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/ then retry." ) if raise_on_exception: - raise Exception( - "Cloud Resource Manager API has not been used before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/ then retry." - ) + raise http_error else: logger.critical( f"{http_error.__class__.__name__}[{http_error.__traceback__.tb_lineno}]: {http_error}" @@ -297,6 +310,10 @@ class GcpProvider(Provider): f"GCP Account: {Fore.YELLOW}{self.identity.profile}{Style.RESET_ALL}", f"GCP Project IDs: {Fore.YELLOW}{', '.join(self.project_ids)}{Style.RESET_ALL}", ] + if self.identity.profile: + report_lines.append( + f"Profile: {Fore.YELLOW}{self.identity.profile}{Style.RESET_ALL}" + ) if self.impersonated_service_account: report_lines.append( f"Impersonated Service Account: {Fore.YELLOW}{self.impersonated_service_account}{Style.RESET_ALL}" @@ -357,7 +374,7 @@ class GcpProvider(Provider): logger.critical( "Cloud Resource Manager API has not been used before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudresourcemanager.googleapis.com/ then retry." ) - sys.exit(1) + raise http_error else: logger.error( f"{http_error.__class__.__name__}[{http_error.__traceback__.tb_lineno}]: {http_error}" @@ -366,7 +383,7 @@ class GcpProvider(Provider): logger.critical( f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - sys.exit(1) + raise error finally: return projects diff --git a/tests/providers/gcp/gcp_provider_test.py b/tests/providers/gcp/gcp_provider_test.py index c84af17d82..c43b533b01 100644 --- a/tests/providers/gcp/gcp_provider_test.py +++ b/tests/providers/gcp/gcp_provider_test.py @@ -16,14 +16,13 @@ from tests.providers.gcp.gcp_fixtures import mock_api_client class TestGCPProvider: def test_gcp_provider(self): - arguments = Namespace() - arguments.project_id = [] - arguments.excluded_project_id = [] - arguments.list_project_id = False - arguments.credentials_file = "" - arguments.impersonate_service_account = "" - arguments.config_file = default_config_file_path - arguments.fixer_config = default_fixer_config_file_path + project_id = [] + excluded_project_id = [] + list_project_id = False + credentials_file = "" + impersonate_service_account = "" + config_file = default_config_file_path + fixer_config = default_fixer_config_file_path projects = { "test-project": GCPProject( @@ -54,7 +53,15 @@ class TestGCPProvider: "prowler.providers.gcp.gcp_provider.discovery.build", return_value=mocked_service, ): - gcp_provider = GcpProvider(arguments) + gcp_provider = GcpProvider( + project_id, + excluded_project_id, + credentials_file, + impersonate_service_account, + list_project_id, + config_file, + fixer_config, + ) assert gcp_provider.session is None assert gcp_provider.project_ids == ["test-project"] assert gcp_provider.projects == projects @@ -112,7 +119,15 @@ class TestGCPProvider: "prowler.providers.gcp.gcp_provider.discovery.build", return_value=mocked_service, ): - gcp_provider = GcpProvider(arguments) + gcp_provider = GcpProvider( + arguments.project_id, + arguments.excluded_project_id, + arguments.credentials_file, + arguments.impersonate_service_account, + arguments.list_project_id, + arguments.config_file, + arguments.fixer_config, + ) # This is needed since the output_options requires to get the global provider to get the audit config with patch( "prowler.providers.common.provider.Provider.get_global_provider", @@ -194,7 +209,15 @@ class TestGCPProvider: "prowler.providers.gcp.gcp_provider.discovery.build", return_value=mocked_service, ): - gcp_provider = GcpProvider(arguments) + gcp_provider = GcpProvider( + arguments.project_id, + arguments.excluded_project_id, + arguments.credentials_file, + arguments.impersonate_service_account, + arguments.list_project_id, + arguments.config_file, + arguments.fixer_config, + ) input_project = "sys-*" project_to_match = "sys-12345678" @@ -258,7 +281,15 @@ class TestGCPProvider: "prowler.providers.gcp.gcp_provider.discovery.build", return_value=mocked_service, ): - gcp_provider = GcpProvider(arguments) + gcp_provider = GcpProvider( + arguments.project_id, + arguments.excluded_project_id, + arguments.credentials_file, + arguments.impersonate_service_account, + arguments.list_project_id, + arguments.config_file, + arguments.fixer_config, + ) assert environ["GOOGLE_APPLICATION_CREDENTIALS"] == "test_credentials_file" assert gcp_provider.session is not None assert gcp_provider.identity.profile == "test-service-account-email" @@ -309,7 +340,15 @@ class TestGCPProvider: "prowler.providers.gcp.gcp_provider.discovery.build", return_value=mocked_service, ): - gcp_provider = GcpProvider(arguments) + gcp_provider = GcpProvider( + arguments.project_id, + arguments.excluded_project_id, + arguments.credentials_file, + arguments.impersonate_service_account, + arguments.list_project_id, + arguments.config_file, + arguments.fixer_config, + ) assert environ["GOOGLE_APPLICATION_CREDENTIALS"] == "test_credentials_file" assert gcp_provider.session is not None assert ( @@ -368,7 +407,15 @@ class TestGCPProvider: "prowler.providers.gcp.gcp_provider.discovery.build", return_value=mocked_service, ): - gcp_provider = GcpProvider(arguments) + gcp_provider = GcpProvider( + arguments.project_id, + arguments.excluded_project_id, + arguments.credentials_file, + arguments.impersonate_service_account, + arguments.list_project_id, + arguments.config_file, + arguments.fixer_config, + ) gcp_provider.print_credentials() captured = capsys.readouterr() assert "Using the GCP credentials below:" in captured.out @@ -426,7 +473,15 @@ class TestGCPProvider: "prowler.providers.gcp.gcp_provider.discovery.build", return_value=mocked_service, ): - gcp_provider = GcpProvider(arguments) + gcp_provider = GcpProvider( + arguments.project_id, + arguments.excluded_project_id, + arguments.credentials_file, + arguments.impersonate_service_account, + arguments.list_project_id, + arguments.config_file, + arguments.fixer_config, + ) gcp_provider.print_credentials() captured = capsys.readouterr() assert "Using the GCP credentials below:" in captured.out @@ -492,7 +547,15 @@ class TestGCPProvider: "prowler.providers.gcp.gcp_provider.discovery.build", return_value=mocked_service, ): - gcp_provider = GcpProvider(arguments) + gcp_provider = GcpProvider( + arguments.project_id, + arguments.excluded_project_id, + arguments.credentials_file, + arguments.impersonate_service_account, + arguments.list_project_id, + arguments.config_file, + arguments.fixer_config, + ) gcp_provider.print_credentials() captured = capsys.readouterr() assert "Using the GCP credentials below:" in captured.out