mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
fix(gcp): scan only ACTIVE projects (#5743)
This commit is contained in:
@@ -15,8 +15,8 @@ class GCPBaseException(ProwlerException):
|
||||
"remediation": "Check the HTTP error and ensure the request is properly formatted.",
|
||||
},
|
||||
(3002, "GCPNoAccesibleProjectsError"): {
|
||||
"message": "No Project IDs can be accessed via Google Credentials",
|
||||
"remediation": "Ensure the project is accessible and properly set up.",
|
||||
"message": "No Project IDs are active or can be accessed via Google Credentials",
|
||||
"remediation": "Ensure the project is active and accessible.",
|
||||
},
|
||||
(3003, "GCPSetUpSessionError"): {
|
||||
"message": "Error setting up session",
|
||||
|
||||
@@ -105,22 +105,28 @@ class GcpProvider(Provider):
|
||||
file=__file__,
|
||||
message="No Project IDs can be accessed via Google Credentials.",
|
||||
)
|
||||
|
||||
if project_ids:
|
||||
if self._default_project_id not in project_ids:
|
||||
self._default_project_id = project_ids[0]
|
||||
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[
|
||||
accessible_project
|
||||
]
|
||||
self._project_ids.append(
|
||||
accessible_projects[accessible_project].id
|
||||
)
|
||||
for (
|
||||
accessible_project_id,
|
||||
accessible_project,
|
||||
) in accessible_projects.items():
|
||||
# Only scan active projects
|
||||
if accessible_project.lifecycle_state == "ACTIVE":
|
||||
if self.is_project_matching(
|
||||
input_project, accessible_project_id
|
||||
):
|
||||
self._projects[accessible_project_id] = accessible_project
|
||||
self._project_ids.append(accessible_project_id)
|
||||
else:
|
||||
# If not projects were input, all accessible projects are scanned by default
|
||||
for project_id, project in accessible_projects.items():
|
||||
self._projects[project_id] = project
|
||||
self._project_ids.append(project_id)
|
||||
# Only scan active projects
|
||||
if project.lifecycle_state == "ACTIVE":
|
||||
self._projects[project_id] = project
|
||||
self._project_ids.append(project_id)
|
||||
|
||||
# Remove excluded projects if any input
|
||||
if excluded_project_ids:
|
||||
@@ -134,11 +140,11 @@ class GcpProvider(Provider):
|
||||
|
||||
if not self._projects:
|
||||
logger.critical(
|
||||
"No Input Project IDs can be accessed via Google Credentials."
|
||||
"No Input Project IDs are active or can be accessed via Google Credentials."
|
||||
)
|
||||
raise GCPNoAccesibleProjectsError(
|
||||
file=__file__,
|
||||
message="No Input Project IDs can be accessed via Google Credentials.",
|
||||
message="No Input Project IDs are active or can be accessed via Google Credentials.",
|
||||
)
|
||||
|
||||
if list_project_ids:
|
||||
|
||||
@@ -14,6 +14,7 @@ from prowler.config.config import (
|
||||
from prowler.providers.common.models import Connection
|
||||
from prowler.providers.gcp.exceptions.exceptions import (
|
||||
GCPInvalidProviderIdError,
|
||||
GCPNoAccesibleProjectsError,
|
||||
GCPTestConnectionError,
|
||||
)
|
||||
from prowler.providers.gcp.gcp_provider import GcpProvider
|
||||
@@ -40,7 +41,7 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -109,7 +110,7 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -183,7 +184,7 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -319,7 +320,7 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
organization=GCPOrganization(
|
||||
id="test-organization-id",
|
||||
name="test-organization",
|
||||
@@ -369,6 +370,69 @@ class TestGCPProvider:
|
||||
== "test-organization-id"
|
||||
)
|
||||
|
||||
def test_setup_session_with_inactive_project(self):
|
||||
mocked_credentials = MagicMock()
|
||||
|
||||
mocked_credentials.refresh.return_value = None
|
||||
mocked_credentials._service_account_email = "test-service-account-email"
|
||||
|
||||
arguments = Namespace()
|
||||
arguments.project_id = ["project/55555555"]
|
||||
arguments.excluded_project_id = []
|
||||
arguments.organization_id = None
|
||||
arguments.list_project_id = False
|
||||
arguments.credentials_file = "test_credentials_file"
|
||||
arguments.impersonate_service_account = ""
|
||||
arguments.config_file = default_config_file_path
|
||||
arguments.fixer_config = default_fixer_config_file_path
|
||||
|
||||
projects = {
|
||||
"test-project": GCPProject(
|
||||
number="55555555",
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="DELETE_REQUESTED",
|
||||
)
|
||||
}
|
||||
|
||||
mocked_service = MagicMock()
|
||||
|
||||
mocked_service.projects.list.return_value = MagicMock(
|
||||
execute=MagicMock(return_value={"projects": projects})
|
||||
)
|
||||
with patch(
|
||||
"prowler.providers.gcp.gcp_provider.GcpProvider.get_projects",
|
||||
return_value=projects,
|
||||
), patch(
|
||||
"prowler.providers.gcp.gcp_provider.GcpProvider.update_projects_with_organizations",
|
||||
return_value=None,
|
||||
), patch(
|
||||
"os.path.abspath",
|
||||
return_value="test_credentials_file",
|
||||
), patch(
|
||||
"prowler.providers.gcp.gcp_provider.default",
|
||||
return_value=(mocked_credentials, MagicMock()),
|
||||
), patch(
|
||||
"prowler.providers.gcp.gcp_provider.discovery.build",
|
||||
return_value=mocked_service,
|
||||
):
|
||||
with pytest.raises(Exception) as e:
|
||||
GcpProvider(
|
||||
arguments.organization_id,
|
||||
arguments.project_id,
|
||||
arguments.excluded_project_id,
|
||||
arguments.credentials_file,
|
||||
arguments.impersonate_service_account,
|
||||
arguments.list_project_id,
|
||||
arguments.config_file,
|
||||
arguments.fixer_config,
|
||||
client_id=None,
|
||||
client_secret=None,
|
||||
refresh_token=None,
|
||||
)
|
||||
assert e.type == GCPNoAccesibleProjectsError
|
||||
|
||||
def test_print_credentials_default_options(self, capsys):
|
||||
mocked_credentials = MagicMock()
|
||||
|
||||
@@ -391,7 +455,7 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -462,7 +526,7 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -533,14 +597,14 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
),
|
||||
"test-excluded-project": GCPProject(
|
||||
number="12345678",
|
||||
id="project/12345678",
|
||||
name="test-excluded-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
),
|
||||
}
|
||||
|
||||
@@ -658,7 +722,7 @@ class TestGCPProvider:
|
||||
id="project/55555555",
|
||||
name="test-project",
|
||||
labels={"test": "value"},
|
||||
lifecycle_state="",
|
||||
lifecycle_state="ACTIVE",
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user