File: //snap/google-cloud-cli/396/lib/surface/compute/operations/list.py
# -*- coding: utf-8 -*- #
# Copyright 2014 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 for listing operations."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import lister
from googlecloudsdk.api_lib.compute import request_helper
from googlecloudsdk.api_lib.compute import utils
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
def _AllowPartialError():
return properties.VALUES.compute.allow_partial_error.GetBool()
def AddFlags(parser, is_ga):
"""Helper function for adding flags dependant on the release track."""
parser.display_info.AddFormat("""\
table(
name,
operationType:label=TYPE,
targetLink.scope():label=TARGET,
operation_http_status():label=HTTP_STATUS,
status,
insertTime:label=TIMESTAMP
)""")
if is_ga:
lister.AddMultiScopeListerFlags(
parser, zonal=True, regional=True, global_=True)
else:
lister.AddBaseListerArgs(parser)
parser.add_argument(
'--zones',
metavar='ZONE',
help=('If arguments are provided, only resources from the given '
'zones are shown. If no arguments are provided all zonal '
'operations are shown.'),
type=arg_parsers.ArgList())
parser.add_argument(
'--regions',
metavar='REGION',
help=('If arguments are provided, only resources from the given '
'regions are shown. If no arguments are provided all regional '
'operations are shown.'),
type=arg_parsers.ArgList())
parser.add_argument(
'--global',
action='store_true',
help='If provided, all global resources are shown.',
default=False)
@base.ReleaseTracks(base.ReleaseTrack.GA)
@base.UniverseCompatible
class List(base.ListCommand):
"""List Compute Engine operations."""
@staticmethod
def Args(parser):
AddFlags(parser, True)
def NoArguments(self, args):
"""Determine if the user provided any flags indicating scope."""
no_compute_args = (args.zones is None and args.regions is None and
not getattr(args, 'global'))
return no_compute_args
def Run(self, args):
"""Yields zonal, regional, and/or global resources."""
compute_holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
compute_client = compute_holder.client
# This is True if the user provided no flags indicating scope.
no_scope_flags = self.NoArguments(args)
requests = []
request_data = lister.ParseNamesAndRegexpFlags(args,
compute_holder.resources)
# TODO(b/36050874): Start using aggregatedList for zones and regions when
# the operations list API supports them.
if no_scope_flags:
requests.append(
(compute_client.apitools_client.globalOperations, 'AggregatedList',
compute_client.apitools_client.globalOperations.GetRequestType(
'AggregatedList')(
filter=request_data.filter,
maxResults=request_data.max_results,
returnPartialSuccess=True,
project=list(request_data.scope_set)[0].project)))
else:
if getattr(args, 'global'):
requests.append(
(compute_client.apitools_client.globalOperations, 'List',
compute_client.apitools_client.globalOperations.GetRequestType(
'List')(
filter=request_data.filter,
maxResults=request_data.max_results,
project=list(request_data.scope_set)[0].project)))
if args.regions is not None:
args_region_names = [
compute_holder.resources.Parse( # pylint:disable=g-complex-comprehension
region,
params={'project': properties.VALUES.core.project.GetOrFail},
collection='compute.regions').Name()
for region in args.regions or []]
# If no regions were provided by the user, fetch a list.
errors = []
region_names = (
args_region_names or [res.name for res in lister.GetGlobalResources( # pylint:disable=g-complex-comprehension
service=compute_client.apitools_client.regions,
project=properties.VALUES.core.project.GetOrFail(),
filter_expr=None,
http=compute_client.apitools_client.http,
batch_url=compute_client.batch_url,
errors=errors)])
if errors:
utils.RaiseToolException(
errors,
'Unable to fetch a list of regions. Specifying [--regions] may '
'fix this issue:')
for region_name in region_names:
requests.append(
(compute_client.apitools_client.regionOperations, 'List',
compute_client.apitools_client.regionOperations.GetRequestType(
'List')(
filter=request_data.filter,
maxResults=request_data.max_results,
region=region_name,
project=list(request_data.scope_set)[0].project)))
if args.zones is not None:
args_zone_names = [
compute_holder.resources.Parse( # pylint:disable=g-complex-comprehension
zone,
params={
'project': properties.VALUES.core.project.GetOrFail,
},
collection='compute.zones').Name()
for zone in args.zones or []]
# If no zones were provided by the user, fetch a list.
errors = []
zone_names = (
args_zone_names or [res.name for res in lister.GetGlobalResources( # pylint:disable=g-complex-comprehension
service=compute_client.apitools_client.zones,
project=properties.VALUES.core.project.GetOrFail(),
filter_expr=None,
http=compute_client.apitools_client.http,
batch_url=compute_client.batch_url,
errors=errors)])
if errors:
utils.RaiseToolException(
errors,
'Unable to fetch a list of zones. Specifying [--zones] may '
'fix this issue:')
for zone_name in zone_names:
requests.append(
(compute_client.apitools_client.zoneOperations, 'List',
compute_client.apitools_client.zoneOperations.GetRequestType(
'List')(
filter=request_data.filter,
maxResults=request_data.max_results,
zone=zone_name,
project=list(request_data.scope_set)[0].project)))
errors = []
results = list(
request_helper.ListJson(
requests=requests,
http=compute_client.apitools_client.http,
batch_url=compute_client.batch_url,
errors=errors))
if errors:
if _AllowPartialError():
utils.WarnIfPartialRequestFail(errors)
else:
utils.RaiseToolException(errors)
return results
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA)
class ListBeta(List):
"""List Compute Engine operations."""
@staticmethod
def Args(parser):
AddFlags(parser, False)
List.detailed_help = base_classes.GetGlobalRegionalListerHelp('operations')
ListBeta.detailed_help = {
'brief': 'List Compute Engine operations',
'DESCRIPTION': """
*{command}* displays all Compute Engine operations in a
project.
By default, all global, regional, and zonal operations are listed. The
results can be narrowed by providing combinations of the --zones,
--regions, and --global flags.
Note: *{command}* displays operations fewer than 14 days old, up to a
maximum of 5000.
""",
'EXAMPLES': """
To list all operations in a project in table form, run:
$ {command}
To list the URIs of all operations in a project, run:
$ {command} --uri
To list all operations in zones us-central1-b and
europe-west1-d, run:
$ {command} --zones=us-central1-b,europe-west1-d
To list all global operations in a project, run:
$ {command} --global
To list all regional operations in a project, run:
$ {command} --regions=""
To list all operations with names prefixed with `operation`, run:
$ {command} --filter="name:operation"
To list all operations in the us-central1 and europe-west1
regions and all operations in the us-central1-a zone, run:
$ {command} --zones=us-central1-a --regions=us-central1,europe-west1
To list all operations with a specified target, filter on the targetLink
field (run `{command} --format=json` to see a full, well-structured list
of available fields). Additionally, use `scope()` which extracts the
last part of the URL to get the required target information, and run:
$ {command} --filter="targetLink.scope():default-12345abc"
""",
}