303 lines
13 KiB
Python
303 lines
13 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2020 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.
|
|
"""Command to SearchAllResources."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from googlecloudsdk.api_lib.asset import client_util
|
|
from googlecloudsdk.calliope import arg_parsers
|
|
from googlecloudsdk.calliope import base
|
|
|
|
|
|
# pylint: disable=line-too-long
|
|
DETAILED_HELP = {
|
|
'DESCRIPTION':
|
|
"""\
|
|
Searches all Cloud resources within the specified scope, such as a
|
|
project, folder or organization. The caller must be granted the
|
|
``cloudasset.assets.searchAllResources'' permission on the desired
|
|
scope.
|
|
""",
|
|
'EXAMPLES':
|
|
"""\
|
|
To search all Cloud resources whose full resource name contains
|
|
``xyz'' as a prefix of any word, within ``organizations/123456'', ensure
|
|
the caller has been granted the ``cloudasset.assets.searchAllResources''
|
|
permission on the organization and run:
|
|
|
|
$ {command} --scope='organizations/123456' --query='name:xyz*'
|
|
"""
|
|
}
|
|
|
|
|
|
def AddScopeArgument(parser):
|
|
parser.add_argument(
|
|
'--scope',
|
|
metavar='SCOPE',
|
|
required=False,
|
|
help=("""\
|
|
A scope can be a project, a folder, or an organization. The search is
|
|
limited to the Cloud resources within this scope. The caller must be
|
|
granted the ``cloudasset.assets.searchAllResources'' permission on
|
|
the desired scope. If not specified, the [configured project property](https://cloud.google.com//sdk/docs/configurations#setting_configuration_properties)
|
|
will be used. To find the configured project, run:
|
|
```gcloud config get project```. To change the setting, run:
|
|
```gcloud config set project PROJECT_ID```.
|
|
|
|
The allowed values are:
|
|
|
|
* ```projects/{PROJECT_ID}``` (e.g., ``projects/foo-bar'')
|
|
* ```projects/{PROJECT_NUMBER}``` (e.g., ``projects/12345678'')
|
|
* ```folders/{FOLDER_NUMBER}``` (e.g., ``folders/1234567'')
|
|
* ```organizations/{ORGANIZATION_NUMBER}``` (e.g. ``organizations/123456'')
|
|
"""))
|
|
|
|
|
|
def AddQueryArgument(parser):
|
|
parser.add_argument(
|
|
'--query',
|
|
metavar='QUERY',
|
|
required=False,
|
|
help=("""\
|
|
The query statement. See [how to construct a
|
|
query](https://cloud.google.com/asset-inventory/docs/searching-resources#how_to_construct_a_query)
|
|
for more details. If not specified or empty, it will search all the
|
|
resources within the specified ```scope```.
|
|
|
|
Examples:
|
|
|
|
* ```name:Important``` to find Cloud resources whose name contains
|
|
``Important'' as a word.
|
|
* ```name=Important``` to find the Cloud resource whose name is exactly
|
|
``Important''.
|
|
* ```displayName:Impor*``` to find Cloud resources whose display name
|
|
contains ``Impor'' as a prefix of any word.
|
|
* ```location:us-west*``` to find Cloud resources whose location
|
|
contains both ``us'' and ``west'' as prefixes.
|
|
* ```labels:prod``` to find Cloud resources whose labels contain
|
|
``prod'' as a key or value.
|
|
* ```labels.env:prod``` to find Cloud resources that have a label
|
|
``env'' and its value is ``prod''.
|
|
* ```labels.env:*``` to find Cloud resources that have a label
|
|
``env''.
|
|
* ```tagKeys:env``` to find Cloud resources that are directly attached
|
|
to tags where the
|
|
[`TagKey.namespacedName`](https://cloud.google.com/resource-manager/reference/rest/v3/tagKeys#resource:-tagkey)
|
|
contains `env`.
|
|
* ```tagValues:prod*``` to find Cloud resources that are directly
|
|
attached to tags where the
|
|
[`TagValue.namespacedName`](https://cloud.google.com/resource-manager/reference/rest/v3/tagValues#resource:-tagvalue)
|
|
contains a word prefixed by `prod`.
|
|
* ```tagValueIds=tagValues/123``` to find Cloud resources that are
|
|
directly attached to tags where the
|
|
[`TagValue.name`](https://cloud.google.com/resource-manager/reference/rest/v3/tagValues#resource:-tagvalue)
|
|
is exactly `tagValues/123`.
|
|
* ```effectiveTagKeys:env``` to find Cloud resources that are directly
|
|
attached to or inherited tags where the
|
|
[`TagKey.namespacedName`](https://cloud.google.com/resource-manager/reference/rest/v3/tagKeys#resource:-tagkey)
|
|
contains `env`.
|
|
* ```effectiveTagValues:prod*``` to find Cloud resources that are
|
|
directly attached to or inherited tags where the
|
|
[`TagValue.namespacedName`](https://cloud.google.com/resource-manager/reference/rest/v3/tagValues#resource:-tagvalue)
|
|
contains a word prefixed by `prod`.
|
|
* ```effectiveTagValueIds=tagValues/123``` to find Cloud resources that
|
|
are directly attached to or inherited tags where the
|
|
[`TagValue.name`](https://cloud.google.com/resource-manager/reference/rest/v3/tagValues#resource:-tagvalue)
|
|
is exactly `tagValues/123`.
|
|
* ```kmsKey:key``` to find Cloud resources encrypted with a
|
|
customer-managed encryption key whose name contains ``key'' as a word.
|
|
This field is deprecated. Please use the `kmsKeys` field to retrieve
|
|
KMS key information.
|
|
* ```kmsKeys:key``` to find Cloud resources encrypted with
|
|
customer-managed encryption keys whose name contains the word ``key''.
|
|
* ```relationships:instance-group-1``` to find Cloud resources that have
|
|
relationships with ``instance-group-1'' in the related resource name.
|
|
* ```relationships:INSTANCE_TO_INSTANCEGROUP``` to find Compute
|
|
instances that have relationships of type
|
|
``INSTANCE_TO_INSTANCEGROUP''.
|
|
* ```relationships.INSTANCE_TO_INSTANCEGROUP:instance-group-1``` to find
|
|
Compute instances that have relationships with ``instance-group-1'' in
|
|
the Compute instance group resource name, for relationship type
|
|
``INSTANCE_TO_INSTANCEGROUP''.
|
|
* ```sccSecurityMarks.key=value``` to find Cloud resources that are
|
|
attached with security marks whose key is ``key'' and value is
|
|
``value''.
|
|
* ```sccSecurityMarks.key:*``` to find Cloud resources that are attached
|
|
with security marks whose key is ``key''.
|
|
* ```state:ACTIVE``` to find Cloud resources whose state contains
|
|
``ACTIVE'' as a word.
|
|
* ```NOT state:ACTIVE``` to find Cloud resources whose state doesn't
|
|
contain ``ACTIVE'' as a word.
|
|
* ```createTime<1609459200``` or ```createTime<2021-01-01``` or
|
|
```createTime<"2021-01-01T00:00:00"``` to find Cloud resources that
|
|
were created before ``2021-01-01 00:00:00 UTC''. 1609459200 is the
|
|
epoch timestamp of ``2021-01-01 00:00:00 UTC'' in seconds.
|
|
* ```updateTime>1609459200``` or ```updateTime>2021-01-01``` or
|
|
```updateTime>"2021-01-01T00:00:00"``` to find Cloud resources that
|
|
were updated after ``2021-01-01 00:00:00 UTC''. 1609459200 is the
|
|
epoch timestamp of ``2021-01-01 00:00:00 UTC'' in seconds.
|
|
* ```Important``` to find Cloud resources that contain ``Important''
|
|
as a word in any of the searchable fields.
|
|
* ```Impor*``` to find Cloud resources that contain ``Impor'' as a
|
|
prefix of any word in any of the searchable fields.
|
|
* ```Important location:(us-west1 OR global)``` to find
|
|
Cloud resources that contain ``Important'' as a word in any of the
|
|
searchable fields and are also located in the ``us-west1'' region or
|
|
the ``global'' location.
|
|
"""))
|
|
|
|
|
|
def AddAssetTypesArgument(parser):
|
|
parser.add_argument(
|
|
'--asset-types',
|
|
metavar='ASSET_TYPES',
|
|
type=arg_parsers.ArgList(),
|
|
default=[],
|
|
help=("""\
|
|
A list of asset types that this request searches for. If empty, it will
|
|
search all the [searchable asset types](https://cloud.google.com/asset-inventory/docs/supported-asset-types).
|
|
|
|
Regular expressions are also supported. For example:
|
|
|
|
* ``compute.googleapis.com.*'' snapshots resources whose asset type
|
|
starts with ``compute.googleapis.com''.
|
|
* ``.*Instance'' snapshots resources whose asset type ends with
|
|
``Instance''.
|
|
* ``.*Instance.*'' snapshots resources whose asset type contains
|
|
``Instance''.
|
|
|
|
See [RE2](https://github.com/google/re2/wiki/Syntax) for all supported
|
|
regular expression syntax. If the regular expression does not match any
|
|
supported asset type, an ``INVALID_ARGUMENT'' error will be returned.
|
|
"""))
|
|
|
|
|
|
def AddOrderByArgument(parser):
|
|
parser.add_argument(
|
|
'--order-by',
|
|
metavar='ORDER_BY',
|
|
required=False,
|
|
help=("""\
|
|
A comma-separated list of fields specifying the sorting order of the
|
|
results. The default order is ascending. Add `` DESC'' after the field
|
|
name to indicate descending order. Redundant space characters are
|
|
ignored. Example: ``location DESC, name''. Only singular primitive
|
|
fields in the response are sortable:
|
|
|
|
* `name`
|
|
* `assetType`
|
|
* `project`
|
|
* `displayName`
|
|
* `description`
|
|
* `location`
|
|
* `createTime`
|
|
* `updateTime`
|
|
* `state`
|
|
* `parentFullResourceName`
|
|
* `parentAssetType`
|
|
|
|
All the other fields such as repeated fields (e.g., `networkTags`,
|
|
`kmsKeys`), map fields (e.g., `labels`) and struct fields (e.g.,
|
|
`additionalAttributes`) are not supported.
|
|
|
|
Both ```--order-by``` and ```--sort-by``` flags can be used to sort the
|
|
output, with the following differences:
|
|
|
|
* The ```--order-by``` flag performs server-side sorting (better
|
|
performance), while the ```--sort-by``` flag performs client-side
|
|
sorting.
|
|
* The ```--sort-by``` flag supports all the fields in the output, while
|
|
the ```--order-by``` flag only supports limited fields as shown above.
|
|
"""))
|
|
|
|
|
|
def AddReadMaskArgument(parser):
|
|
parser.add_argument(
|
|
'--read-mask',
|
|
metavar='READ_MASK',
|
|
required=False,
|
|
help=("""\
|
|
A comma-separated list of fields specifying which fields to be returned
|
|
in the results. Only `"*"` or combination of top level fields can be
|
|
specified. Examples: `"*"`, `"name,location"`, `"name,versionedResources"`.
|
|
|
|
The read_mask paths must be valid field paths listed but not limited to
|
|
the following (both snake_case and camelCase are supported):
|
|
* `name`
|
|
* `asset_type` or `assetType`
|
|
* `project`
|
|
* `display_name` or `displayName`
|
|
* `description`
|
|
* `location`
|
|
* `labels`
|
|
* `tags`
|
|
* `effective_tags` or `effectiveTags`
|
|
* `network_tags` or `networkTags`
|
|
* `kms_keys` or `kmsKeys`
|
|
* `create_time` or `createTime`
|
|
* `update_time` or `updateTime`
|
|
* `state`
|
|
* `additional_attributes` or `additionalAttributes`
|
|
* `versioned_resources` or `versionedResources`
|
|
|
|
If read_mask is not specified, all fields except versionedResources
|
|
will be returned.
|
|
|
|
If only `"*"` is specified, all fields including versionedResources will
|
|
be returned.
|
|
"""))
|
|
|
|
|
|
# pylint: enable=line-too-long
|
|
|
|
|
|
@base.ReleaseTracks(base.ReleaseTrack.BETA)
|
|
class SearchAllResourcesBeta(base.ListCommand):
|
|
"""Searches all Cloud resources within the specified accessible scope, such as a project, folder or organization."""
|
|
|
|
detailed_help = DETAILED_HELP
|
|
|
|
@staticmethod
|
|
def Args(parser):
|
|
AddScopeArgument(parser)
|
|
AddQueryArgument(parser)
|
|
AddAssetTypesArgument(parser)
|
|
AddOrderByArgument(parser)
|
|
base.URI_FLAG.RemoveFromParser(parser)
|
|
|
|
def Run(self, args):
|
|
client = client_util.AssetSearchClient(client_util.V1P1BETA1_API_VERSION)
|
|
return client.SearchAllResources(args)
|
|
|
|
|
|
@base.ReleaseTracks(base.ReleaseTrack.GA)
|
|
class SearchAllResources(SearchAllResourcesBeta):
|
|
"""Searches all Cloud resources within the specified accessible scope, such as a project, folder or organization."""
|
|
|
|
@staticmethod
|
|
def Args(parser):
|
|
AddScopeArgument(parser)
|
|
AddQueryArgument(parser)
|
|
AddAssetTypesArgument(parser)
|
|
AddOrderByArgument(parser)
|
|
AddReadMaskArgument(parser)
|
|
base.URI_FLAG.RemoveFromParser(parser)
|
|
|
|
def Run(self, args):
|
|
client = client_util.AssetSearchClient(client_util.DEFAULT_API_VERSION)
|
|
return client.SearchAllResources(args)
|