mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
refactor(gcp): refactor GCP provider (#4790)
Co-authored-by: Sergio <sergio@prowler.com>
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user