feat: Add new gcloud commands, API clients, and third-party libraries across various services.

This commit is contained in:
2026-01-01 20:26:35 +01:00
parent 5e23cbece0
commit a19e592eb7
25221 changed files with 8324611 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""Package for the api_keys CLI subcommands."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class ApiKeys(base.Group):
"""Manage API keys."""

View File

@@ -0,0 +1,166 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""services api-keys create command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.services import apikeys
from googlecloudsdk.api_lib.services import services_util
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.services import common_flags
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
OP_BASE_CMD = 'gcloud services operations '
OP_WAIT_CMD = OP_BASE_CMD + 'wait {0}'
_DETAILED_HELP = {'EXAMPLES': """
To create a key with display name and allowed IPs specified:
$ {command} --display-name="test name" --allowed-ips=2620:15c:2c4:203:2776:1f90:6b3b:217,104.133.8.78
To create a key with annotations:
$ {command} --annotations=foo=bar,abc=def
To create a key with user-specified key ID:
$ {command} --key-id="my-key-id"
To create a key with allowed referrers restriction:
$ {command} --allowed-referrers="https://www.example.com/*,http://sub.example.com/*"
To create a key with allowed IOS app bundle IDs:
$ {command} --allowed-bundle-ids=my.app
To create a key with allowed Android application:
$ {command} --allowed-application=sha1_fingerprint=foo1,package_name=bar.foo --allowed-application=sha1_fingerprint=foo2,package_name=foo.bar
To create a key with allowed API targets (service name only):
$ {command} --api-target=service=bar.service.com --api-target=service=foo.service.com
To create a key with service account:
$ {command} --service-account=my-service-account
To create a key with allowed API targets (service and methods are
specified):
$ {command} --flags-file=my-flags.yaml
The content of 'my-flags.yaml' is as follows:
```
- --api-target:
service: "foo.service.com"
- --api-target:
service: "bar.service.com"
methods:
- "foomethod"
- "barmethod"
```
"""}
@base.UniverseCompatible
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Create(base.CreateCommand):
"""Create an API key."""
@staticmethod
def Args(parser):
common_flags.display_name_flag(parser=parser, suffix='to create')
common_flags.add_key_create_args(parser)
common_flags.key_id_flag(parser=parser, suffix='to create')
common_flags.service_account_flag(parser)
base.ASYNC_FLAG.AddToParser(parser)
def Run(self, args):
"""Run command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
None
"""
project_id = properties.VALUES.core.project.GetOrFail()
client = apikeys.GetClientInstance()
messages = client.MESSAGES_MODULE
key_proto = messages.V2Key(restrictions=messages.V2Restrictions())
if args.IsSpecified('display_name'):
key_proto.displayName = args.display_name
if args.IsSpecified('allowed_referrers'):
key_proto.restrictions.browserKeyRestrictions = (
messages.V2BrowserKeyRestrictions(
allowedReferrers=args.allowed_referrers
)
)
elif args.IsSpecified('allowed_ips'):
key_proto.restrictions.serverKeyRestrictions = (
messages.V2ServerKeyRestrictions(allowedIps=args.allowed_ips)
)
elif args.IsSpecified('allowed_bundle_ids'):
key_proto.restrictions.iosKeyRestrictions = messages.V2IosKeyRestrictions(
allowedBundleIds=args.allowed_bundle_ids
)
elif args.IsSpecified('allowed_application'):
key_proto.restrictions.androidKeyRestrictions = (
messages.V2AndroidKeyRestrictions(
allowedApplications=apikeys.GetAllowedAndroidApplications(
args, messages
)
)
)
if args.IsSpecified('api_target'):
key_proto.restrictions.apiTargets = apikeys.GetApiTargets(args, messages)
if args.IsSpecified('annotations'):
key_proto.annotations = apikeys.GetAnnotations(args, messages)
if args.IsSpecified('service_account'):
key_proto.serviceAccountEmail = args.service_account
if args.IsSpecified('key_id'):
request = messages.ApikeysProjectsLocationsKeysCreateRequest(
parent=apikeys.GetParentResourceName(project_id),
v2Key=key_proto,
keyId=args.key_id,
)
else:
request = messages.ApikeysProjectsLocationsKeysCreateRequest(
parent=apikeys.GetParentResourceName(project_id), v2Key=key_proto
)
op = client.projects_locations_keys.Create(request)
if not op.done:
if args.async_:
cmd = OP_WAIT_CMD.format(op.name)
log.status.Print(
'Asynchronous operation is in progress... '
'Use the following command to wait for its '
'completion:\n {0}'.format(cmd)
)
return op
op = services_util.WaitOperation(op.name, apikeys.GetOperation)
services_util.PrintOperationWithResponse(op)
return op
detailed_help = _DETAILED_HELP

View File

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""services api-keys delete command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.services import apikeys
from googlecloudsdk.api_lib.services import services_util
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.services import common_flags
from googlecloudsdk.core import log
OP_BASE_CMD = 'gcloud services operations '
OP_WAIT_CMD = OP_BASE_CMD + 'wait {0}'
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Delete(base.DeleteCommand):
"""Delete an API key.
Delete an API key.
## EXAMPLES
Delete an API Key :
$ {command} projects/myproject/locations/global/keys/1234
$ {command} 1234
"""
@staticmethod
def Args(parser):
common_flags.key_flag(parser=parser, suffix='to delete')
base.ASYNC_FLAG.AddToParser(parser)
def Run(self, args):
"""Run command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
The response from the Delete API call.
"""
client = apikeys.GetClientInstance()
messages = client.MESSAGES_MODULE
key_ref = args.CONCEPTS.key.Parse()
request = messages.ApikeysProjectsLocationsKeysDeleteRequest(
name=key_ref.RelativeName())
op = client.projects_locations_keys.Delete(request)
if not op.done:
if args.async_:
cmd = OP_WAIT_CMD.format(op.name)
log.status.Print('Asynchronous operation is in progress... '
'Use the following command to wait for its '
'completion:\n {0}'.format(cmd))
return op
op = services_util.WaitOperation(op.name, apikeys.GetOperation)
services_util.PrintOperationWithResponse(op)
return op

View File

@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""services api-keys describe command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.services import apikeys
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.services import common_flags
DETAILED_HELP = {
'DESCRIPTION':
"""Describe an API key's metadata.""",
'EXAMPLES':
"""\
To describe an API key using Key:
$ {command} 1234
OR
$ {command} projects/myproject/locations/global/keys/1234
To describe an API key with key and project:
$ {command} 1234 --project=myproject
To describe an API key with key, project, and location:
$ {command} 1234 --project=myproject --location=global
""",
}
@base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
base.ReleaseTrack.GA)
class DescribeGa(base.DescribeCommand):
"""Describe an API key's metadata."""
detailed_help = DETAILED_HELP
@staticmethod
def Args(parser):
common_flags.key_flag(parser=parser, suffix='to describe', api_version='v2')
def Run(self, args):
"""Run command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
The metadata of API key.
"""
client = apikeys.GetClientInstance(self.ReleaseTrack())
messages = client.MESSAGES_MODULE
key_ref = args.CONCEPTS.key.Parse()
request = messages.ApikeysProjectsLocationsKeysGetRequest(
name=key_ref.RelativeName())
return client.projects_locations_keys.Get(request)

View File

@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""services api-keys get-key-string command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.services import apikeys
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.services import common_flags
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class GetKeyString(base.DescribeCommand):
"""Get the key string of an API key.
Get the key string of an API key
## EXAMPLES
To get the key string of API key `1234`, run:
$ {command} 1234
To get the key string of API key `1234` in project
`myproject` using the fully qualified API key name, run:
$ {command} projects/myproject/locations/global/keys/1234
"""
@staticmethod
def Args(parser):
common_flags.key_flag(parser=parser, suffix='to retrieve key string')
def Run(self, args):
"""Run command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
Key string.
"""
client = apikeys.GetClientInstance()
messages = client.MESSAGES_MODULE
key_ref = args.CONCEPTS.key.Parse()
request = messages.ApikeysProjectsLocationsKeysGetKeyStringRequest(
name=key_ref.RelativeName())
return client.projects_locations_keys.GetKeyString(request)

View File

@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""services api-keys list command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.services import apikeys
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
def _GetUriFunction(api_version):
"""Returns a Uri function for list."""
collection = 'apikeys.projects.locations.keys'
def UriFunc(resource):
return resources.REGISTRY.ParseRelativeName(
resource.name, collection=collection,
api_version=api_version).SelfLink()
return UriFunc
def _ListArgs(parser):
parser.add_argument(
'--show-deleted',
action='store_true',
help=('Show soft-deleted keys by specifying this flag.'))
@base.ReleaseTracks(base.ReleaseTrack.ALPHA,
base.ReleaseTrack.BETA, base.ReleaseTrack.GA)
class List(base.ListCommand):
"""Lists API keys.
Lists the API keys of a given project.
## EXAMPLES
List keys of a given project:
$ {command}
List keys of a given project, including keys that were soft-deleted in the
past 30 days.:
$ {command} --show-deleted --project=my_project
"""
@staticmethod
def Args(parser):
_ListArgs(parser)
parser.display_info.AddUriFunc(_GetUriFunction(api_version='v2'))
def Run(self, args):
"""Run command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
The list of api keys.
"""
project_id = properties.VALUES.core.project.GetOrFail()
return apikeys.ListKeys(project_id, args.show_deleted, args.page_size,
args.limit)

View File

@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""services api-keys lookup command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.services import apikeys
from googlecloudsdk.calliope import base
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Lookup(base.Command):
"""Look up resource name of a key string.
Look up resource name of a key string.
## EXAMPLES
Look up resource name of a key string named my-key-string:
$ {command} my-key-string
"""
@staticmethod
def Args(parser):
parser.add_argument('key_string', help='Key string of the key')
def Run(self, args):
"""Run command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
Resource name and its parent name.
"""
client = apikeys.GetClientInstance()
messages = client.MESSAGES_MODULE
request = messages.ApikeysKeysLookupKeyRequest(keyString=args.key_string)
return client.keys.LookupKey(request)

View File

@@ -0,0 +1,102 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""services api-keys undelete command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.services import apikeys
from googlecloudsdk.api_lib.services import services_util
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.services import common_flags
from googlecloudsdk.core import log
OP_BASE_CMD = 'gcloud services operations '
OP_WAIT_CMD = OP_BASE_CMD + 'wait {0}'
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Undelete(base.RestoreCommand):
"""Undelete an API key.
API Keys that are deleted will be retained in the system for 30 days. If a
key is still within this retention window, it can be undeleted with this
command.
## EXAMPLES
UnDelete an API Key (Key or key-string should be specified):
To undelete with key `1234`, run:
$ {command} 1234
To undelete with `1234` in project `myproject` using the fully qualified API
key name, run:
$ {command} projects/myproject/locations/global/keys/1234
To undelete using a Key-string, run:
$ {command} --key-string='my-key-string'
"""
@staticmethod
def Args(parser):
common_flags.add_key_undelete_args(parser)
base.ASYNC_FLAG.AddToParser(parser)
def Run(self, args):
"""Run command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
None
"""
client = apikeys.GetClientInstance()
messages = client.MESSAGES_MODULE
if args.IsSpecified('key'):
key_ref = args.CONCEPTS.key.Parse()
key_name = key_ref.RelativeName()
if args.IsSpecified('key_string'):
lookup_request = messages.ApikeysKeysLookupKeyRequest(
keyString=args.key_string
)
response = client.keys.LookupKey(lookup_request)
key_name = response.name
request = messages.ApikeysProjectsLocationsKeysUndeleteRequest(
name=key_name
)
op = client.projects_locations_keys.Undelete(request)
if not op.done:
if args.async_:
cmd = OP_WAIT_CMD.format(op.name)
log.status.Print('Asynchronous operation is in progress... '
'Use the following command to wait for its '
'completion:\n {0}'.format(cmd))
return op
op = services_util.WaitOperation(op.name, apikeys.GetOperation)
services_util.PrintOperationWithResponse(op)
return op

View File

@@ -0,0 +1,157 @@
# -*- coding: utf-8 -*- #
# Copyright 2020 Google Inc. 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.
"""services api-keys update command."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.services import apikeys
from googlecloudsdk.api_lib.services import services_util
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.services import common_flags
from googlecloudsdk.core import log
OP_BASE_CMD = 'gcloud services operations '
OP_WAIT_CMD = OP_BASE_CMD + 'wait {0}'
DETAILED_HELP = {
'EXAMPLES':
"""
To remove all restrictions of the key:
$ {command} projects/myproject/keys/my-key-id --clear-restrictions
To update display name and set allowed ips as server key restrictions:
$ {command} projects/myproject/keys/my-key-id --display-name="test name" --allowed-ips=2620:15c:2c4:203:2776:1f90:6b3b:217,104.133.8.78
To update annotations:
$ {command} projects/myproject/keys/my-key-id --annotations=foo=bar,abc=def
To update key's allowed referrers restriction:
$ {command} projects/myproject/keys/my-key-id --allowed-referrers="https://www.example.com/*,http://sub.example.com/*"
To update key's allowed ios app bundle ids:
$ {command} projects/myproject/keys/my-key-id --allowed-bundle-ids=my.app
To update key's allowed android application:
$ {command} projects/myproject/keys/my-key-id --allowed-application=sha1_fingerprint=foo1,package_name=bar1 --allowed-application=sha1_fingerprint=foo2,package_name=bar2
To update keys' allowed api target with multiple services:
$ {command} projects/myproject/keys/my-key-id --api-target=service=bar.service.com --api-target=service=foo.service.com
To update keys' allowed api target with service and method:
$ {command} projects/myproject/keys/my-key-id --flags-file=my-flags.yaml
The content of 'my-flags.yaml' is as following:
```
- --api-target:
service: "foo.service.com"
- --api-target:
service: "bar.service.com"
methods:
- "foomethod"
- "barmethod"
```
"""
}
@base.ReleaseTracks(
base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA, base.ReleaseTrack.GA
)
class Update(base.UpdateCommand):
"""Update an API key's metadata."""
@staticmethod
def Args(parser):
common_flags.key_flag(parser=parser, suffix='to update')
common_flags.display_name_flag(parser=parser, suffix='to update')
common_flags.add_key_update_args(parser)
base.ASYNC_FLAG.AddToParser(parser)
def Run(self, args):
"""Run command.
Args:
args: an argparse namespace. All the arguments that were provided to this
command invocation.
Returns:
None
"""
client = apikeys.GetClientInstance()
messages = client.MESSAGES_MODULE
key_ref = args.CONCEPTS.key.Parse()
update_mask = []
key_proto = messages.V2Key(
name=key_ref.RelativeName(), restrictions=messages.V2Restrictions())
if args.IsSpecified('annotations'):
update_mask.append('annotations')
key_proto.annotations = apikeys.GetAnnotations(args, messages)
if args.IsSpecified('display_name'):
update_mask.append('display_name')
key_proto.displayName = args.display_name
if args.IsSpecified('clear_annotations'):
update_mask.append('annotations')
if args.IsSpecified('clear_restrictions'):
update_mask.append('restrictions')
else:
if args.IsSpecified('allowed_referrers'):
update_mask.append('restrictions.browser_key_restrictions')
key_proto.restrictions.browserKeyRestrictions = messages.V2BrowserKeyRestrictions(
allowedReferrers=args.allowed_referrers)
elif args.IsSpecified('allowed_ips'):
update_mask.append('restrictions.server_key_restrictions')
key_proto.restrictions.serverKeyRestrictions = messages.V2ServerKeyRestrictions(
allowedIps=args.allowed_ips)
elif args.IsSpecified('allowed_bundle_ids'):
update_mask.append('restrictions.ios_key_restrictions')
key_proto.restrictions.iosKeyRestrictions = messages.V2IosKeyRestrictions(
allowedBundleIds=args.allowed_bundle_ids)
elif args.IsSpecified('allowed_application'):
update_mask.append('restrictions.android_key_restrictions')
key_proto.restrictions.androidKeyRestrictions = messages.V2AndroidKeyRestrictions(
allowedApplications=apikeys.GetAllowedAndroidApplications(
args, messages))
if args.IsSpecified('api_target'):
update_mask.append('restrictions.api_targets')
key_proto.restrictions.apiTargets = apikeys.GetApiTargets(
args, messages)
request = messages.ApikeysProjectsLocationsKeysPatchRequest(
name=key_ref.RelativeName(),
updateMask=','.join(update_mask),
v2Key=key_proto)
op = client.projects_locations_keys.Patch(request)
if not op.done:
if args.async_:
cmd = OP_WAIT_CMD.format(op.name)
log.status.Print('Asynchronous operation is in progress... '
'Use the following command to wait for its '
'completion:\n {0}'.format(cmd))
return op
op = services_util.WaitOperation(op.name, apikeys.GetOperation)
services_util.PrintOperationWithResponse(op)
return op
detailed_help = DETAILED_HELP