161 lines
5.9 KiB
Python
161 lines
5.9 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2018 Google LLC. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""The utils for asset surface."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
import re
|
|
|
|
from googlecloudsdk.calliope import exceptions as gcloud_exceptions
|
|
from googlecloudsdk.command_lib.projects import util as project_util
|
|
from googlecloudsdk.core import properties
|
|
|
|
|
|
def SetDefaultScopeIfEmpty(unused_ref, args, request):
|
|
"""Update the request scope to fall back to core project if not specified.
|
|
|
|
Used by Asset Search gcloud `modify_request_hooks`. When --scope flag is not
|
|
specified, it will modify the request.scope to fallback to the core properties
|
|
project.
|
|
|
|
Args:
|
|
unused_ref: unused.
|
|
args: The argument namespace.
|
|
request: The request to modify.
|
|
|
|
Returns:
|
|
The modified request.
|
|
"""
|
|
request.scope = GetDefaultScopeIfEmpty(args)
|
|
return request
|
|
|
|
|
|
def GetDefaultScopeIfEmpty(args):
|
|
"""Return the request scope and fall back to core project if not specified."""
|
|
if args.scope:
|
|
VerifyScopeForSearch(args.scope)
|
|
return args.scope
|
|
else:
|
|
return 'projects/{0}'.format(properties.VALUES.core.project.GetOrFail())
|
|
|
|
|
|
def VerifyScopeForSearch(scope):
|
|
"""Perform permissive validation of the search scope.
|
|
|
|
This validation is required although the API server contains similar request
|
|
validation.
|
|
The reason is that a malformed scope will be translated into an
|
|
invalid URL, resulting in 404. For example, scope "projects/123/abc/" is
|
|
translated to
|
|
"https://cloudasset.googleapis.com/v1p1beta1/projects/123/abc/resources:searchAll".(404)
|
|
However our OnePlatform API only accepts URL in format:
|
|
"https://cloudasset.googleapis.com/v1p1beta1/*/*/resources:searchAll"
|
|
|
|
Args:
|
|
scope: the scope string of a search request.
|
|
"""
|
|
if not re.match('^[^/#?]+/[^/#?]+$', scope):
|
|
raise gcloud_exceptions.InvalidArgumentException(
|
|
'--scope', 'A valid scope should be: projects/{PROJECT_ID}, '
|
|
'projects/{PROJECT_NUMBER}, folders/{FOLDER_NUMBER} or '
|
|
'organizations/{ORGANIZATION_NUMBER}.')
|
|
|
|
|
|
def VerifyParentForExport(organization,
|
|
project,
|
|
folder,
|
|
attribute='root cloud asset'):
|
|
"""Verify the parent name."""
|
|
if organization is None and project is None and folder is None:
|
|
raise gcloud_exceptions.RequiredArgumentException(
|
|
'--organization or --project or --folder',
|
|
'Should specify the organization, or project, or the folder for '
|
|
'{0}.'.format(attribute))
|
|
if organization and project:
|
|
raise gcloud_exceptions.ConflictingArgumentsException(
|
|
'organization', 'project')
|
|
if organization and folder:
|
|
raise gcloud_exceptions.ConflictingArgumentsException(
|
|
'organization', 'folder')
|
|
if project and folder:
|
|
raise gcloud_exceptions.ConflictingArgumentsException('project', 'folder')
|
|
|
|
|
|
def GetParentNameForExport(organization,
|
|
project,
|
|
folder,
|
|
attribute='root cloud asset'):
|
|
"""Gets the parent name from organization Id, project Id, or folder Id."""
|
|
VerifyParentForExport(organization, project, folder, attribute)
|
|
if organization:
|
|
return 'organizations/{0}'.format(organization)
|
|
if folder:
|
|
return 'folders/{0}'.format(folder)
|
|
return 'projects/{0}'.format(project)
|
|
|
|
|
|
def GetFeedParent(organization, project, folder):
|
|
"""Get the parent name from organization Number, project Id, or folder Number."""
|
|
if organization:
|
|
return 'organizations/{0}'.format(organization)
|
|
if folder:
|
|
return 'folders/{0}'.format(folder)
|
|
return 'projects/{0}'.format(project_util.GetProjectNumber(project))
|
|
|
|
|
|
def GetSavedQueriesParent(organization, project, folder):
|
|
"""Get the parent name from organization Number, project Id, or folder Number."""
|
|
if organization:
|
|
return 'organizations/{0}'.format(organization)
|
|
if folder:
|
|
return 'folders/{0}'.format(folder)
|
|
return 'projects/{0}'.format(project_util.GetProjectNumber(project))
|
|
|
|
|
|
def VerifyParentForGetHistory(organization,
|
|
project,
|
|
attribute='root cloud asset'):
|
|
"""Verify the parent name."""
|
|
if organization is None and project is None:
|
|
raise gcloud_exceptions.RequiredArgumentException(
|
|
'--organization or --project',
|
|
'Should specify the organization, or project for {0}.'.format(
|
|
attribute))
|
|
if organization and project:
|
|
raise gcloud_exceptions.ConflictingArgumentsException(
|
|
'organization', 'project')
|
|
|
|
|
|
def GetParentNameForGetHistory(organization,
|
|
project,
|
|
attribute='root cloud asset'):
|
|
"""Gets the parent name from organization Id, project Id."""
|
|
VerifyParentForGetHistory(organization, project, attribute)
|
|
if organization:
|
|
return 'organizations/{0}'.format(organization)
|
|
return 'projects/{0}'.format(project)
|
|
|
|
|
|
def GetParentNameForAnalyzeIamPolicy(organization,
|
|
project,
|
|
folder,
|
|
attribute='policy analysis scope'):
|
|
"""Gets the parent name from organization Id, project Id, or folder Id."""
|
|
|
|
# Analyzer supports the same set of parents as ExportAssets.
|
|
return GetParentNameForExport(organization, project, folder, attribute)
|