Skip to content

Commit

Permalink
Add logic to validate project status
Browse files Browse the repository at this point in the history
  • Loading branch information
x4v13r64 committed Apr 29, 2020
1 parent 9e48bf8 commit 1a4ee10
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
48 changes: 47 additions & 1 deletion ScoutSuite/providers/gcp/facade/base.py
@@ -1,4 +1,4 @@
from ScoutSuite.core.console import print_exception, print_info
from ScoutSuite.core.console import print_exception, print_info, print_debug, print_error
from ScoutSuite.providers.gcp.facade.basefacade import GCPBaseFacade
from ScoutSuite.providers.gcp.facade.cloudresourcemanager import CloudResourceManagerFacade
from ScoutSuite.providers.gcp.facade.cloudsql import CloudSQLFacade
Expand All @@ -8,6 +8,9 @@
from ScoutSuite.providers.gcp.facade.kms import KMSFacade
from ScoutSuite.providers.gcp.facade.stackdriverlogging import StackdriverLoggingFacade
from ScoutSuite.providers.gcp.facade.utils import GCPFacadeUtils
from ScoutSuite.providers.utils import run_concurrently
from ScoutSuite.providers.gcp.facade.utils import GCPFacadeUtils
from ScoutSuite.utils import format_service_name

# Try to import proprietary facades
try:
Expand Down Expand Up @@ -126,3 +129,46 @@ async def _get_projects_recursively(self, parent_type, parent_id):

finally:
return projects

async def is_api_enabled(self, project_id, service):
"""
Given a project ID and service name, this method tries to determine if the service's API is enabled
"""

serviceusage_client = self._build_arbitrary_client('serviceusage', 'v1', force_new=True)
services = serviceusage_client.services()
request = services.list(parent='projects/{}'.format(project_id))
services_response = await GCPFacadeUtils.get_all('services', request, services)

# These are hardcoded endpoint correspondences as there's no easy way to do this.
if service == 'IAM':
endpoint = 'iam'
elif service == 'KMS':
endpoint = 'cloudkms'
elif service == 'CloudStorage':
endpoint = 'storage-component'
elif service == 'CloudSQL':
endpoint = 'sql-component'
elif service == 'ComputeEngine':
endpoint = 'compute'
elif service == 'KubernetesEngine':
endpoint = 'container'
elif service == 'StackdriverLogging':
endpoint = 'logging'
else:
print_debug('Could not validate the state of the {} API for project \"{}\", including'.format(
format_service_name(service.lower()), project_id))
return True

for s in services_response:
if endpoint in s.get('name'):
if s.get('state') == 'ENABLED':
return True
else:
print_info('{} API not enabled for project \"{}\", skipping'.format(format_service_name(service.lower()),
project_id))
return False

print_error('Could not validate the state of the {} API for project \"{}\", including'.format(
format_service_name(service.lower()), project_id))
return True
10 changes: 8 additions & 2 deletions ScoutSuite/providers/gcp/resources/projects.py
Expand Up @@ -14,8 +14,14 @@ async def fetch_all(self):
"""

raw_projects = await self.facade.get_projects()
self['projects'] = {raw_project['projectId']: {}
for raw_project in raw_projects}

self['projects'] = {}
# For each project, validate that the corresponding service API is enabled before including it in the execution.
for p in raw_projects:
enabled = await self.facade.is_api_enabled(p['projectId'], self.__class__.__name__)
if enabled:
self['projects'][p['projectId']] = {}

await self._fetch_children_of_all_resources(
resources=self['projects'],
scopes={project_id: {'project_id': project_id} for project_id in self['projects']})
Expand Down

0 comments on commit 1a4ee10

Please sign in to comment.