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,48 @@
# -*- 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.
"""Commands for reading and manipulating project-level data."""
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 ProjectInfo(base.Group):
"""Read and manipulate project-level data like quotas and metadata."""
ProjectInfo.category = base.TOOLS_CATEGORY
ProjectInfo.detailed_help = {
'DESCRIPTION': """
Read and manipulate project-level data like quotas and
metadata.
For more information about quotas, see the
[quotas documentation](https://cloud.google.com/compute/quotas).
``Note'': Project-level metadata is a distinct concept from instance-level
metadata.
For more information about instance metadata, see
[Storing and retrieving instance metadata](https://cloud.google.com/compute/docs/storing-retrieving-metadata).
See also: [Projects API](https://cloud.google.com/compute/docs/reference/rest/v1/projects).
""",
}

View File

@@ -0,0 +1,119 @@
# -*- 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 adding project-wide metadata."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import encoding
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import metadata_utils
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import exceptions as compute_exceptions
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
class AddMetadata(base.UpdateCommand):
# pylint:disable=line-too-long
"""Add or update project-wide metadata.
*{command}* can be used to add or update project-wide
metadata. Every instance has access to a metadata server that
can be used to query metadata that has been set through this
tool. Project-wide metadata entries are visible to all
instances. To set metadata for individual instances, use
`gcloud compute instances add-metadata`. For information on
metadata, see
[](https://cloud.google.com/compute/docs/metadata)
Only metadata keys that are provided are mutated. Existing
metadata entries will remain unaffected.
If you are using this command to manage SSH keys for your project, please note
the
[risks](https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys#risks)
of manual SSH key management as well as the required format for SSH key
metadata, available at
[](https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys)
"""
# pylint:enable=line-too-long
@staticmethod
def Args(parser):
metadata_utils.AddMetadataArgs(parser, required=True)
def CreateReference(self, resources):
return resources.Parse(
properties.VALUES.core.project.GetOrFail(),
collection='compute.projects')
def GetGetRequest(self, client, project_ref):
return (client.apitools_client.projects,
'Get',
client.messages.ComputeProjectsGetRequest(**project_ref.AsDict()))
def GetSetRequest(self, client, project_ref, replacement):
return (client.apitools_client.projects,
'SetCommonInstanceMetadata',
client.messages.ComputeProjectsSetCommonInstanceMetadataRequest(
metadata=replacement.commonInstanceMetadata,
**project_ref.AsDict()))
def Modify(self, client, args, existing):
new_object = encoding.JsonToMessage(
type(existing), encoding.MessageToJson(existing))
existing_metadata = existing.commonInstanceMetadata
new_object.commonInstanceMetadata = metadata_utils.ConstructMetadataMessage(
client.messages,
metadata=args.metadata,
metadata_from_file=args.metadata_from_file,
existing_metadata=existing_metadata)
if metadata_utils.MetadataEqual(existing_metadata,
new_object.commonInstanceMetadata):
return None
else:
return new_object
def Run(self, args):
if not args.metadata and not args.metadata_from_file:
raise compute_exceptions.ArgumentError(
'At least one of [--metadata] or [--metadata-from-file] must be '
'provided.')
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
project_ref = self.CreateReference(holder.resources)
get_request = self.GetGetRequest(client, project_ref)
objects = client.MakeRequests([get_request])
new_object = self.Modify(client, args, objects[0])
# If existing object is equal to the proposed object or if
# Modify() returns None, then there is no work to be done, so we
# print the resource and return.
if not new_object or objects[0] == new_object:
log.status.Print(
'No change requested; skipping update for [{0}].'.format(
objects[0].name))
return objects
return client.MakeRequests(
[self.GetSetRequest(client, project_ref, new_object)])

View File

@@ -0,0 +1,50 @@
# -*- 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 describing the project."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.projects import util
from googlecloudsdk.core import properties
class Describe(base.DescribeCommand):
"""Describe the Compute Engine project resource."""
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
project_ref = util.ParseProject(properties.VALUES.core.project.GetOrFail())
return client.MakeRequests([(client.apitools_client.projects, 'Get',
client.messages.ComputeProjectsGetRequest(
project=project_ref.projectId))])[0]
Describe.detailed_help = {
'brief': 'Describe the Compute Engine project resource',
'DESCRIPTION': """\
*{command}* displays all data associated with the
Compute Engine project resource. The project resource contains
data such as global quotas, common instance metadata, and the
project's creation time.
""",
}

View File

@@ -0,0 +1,110 @@
# -*- 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 removing project-wide metadata."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from apitools.base.py import encoding
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.api_lib.compute import metadata_utils
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import exceptions
from googlecloudsdk.core import log
from googlecloudsdk.core import properties
class RemoveMetadata(base.UpdateCommand):
"""Remove project-wide metadata entries.
*{command}* can be used to remove project-wide metadata entries.
"""
@staticmethod
def Args(parser):
group = parser.add_mutually_exclusive_group()
group.add_argument(
'--all',
action='store_true',
default=False,
help='If provided, all metadata entries are removed.')
group.add_argument(
'--keys',
type=arg_parsers.ArgList(min_length=1),
metavar='KEY',
help='The keys of the entries to remove.')
def CreateReference(self, resources):
return resources.Parse(
properties.VALUES.core.project.GetOrFail(),
collection='compute.projects')
def GetGetRequest(self, client, project_ref):
return (client.apitools_client.projects,
'Get',
client.messages.ComputeProjectsGetRequest(**project_ref.AsDict()))
def GetSetRequest(self, client, project_ref, replacement):
return (client.apitools_client.projects,
'SetCommonInstanceMetadata',
client.messages.ComputeProjectsSetCommonInstanceMetadataRequest(
metadata=replacement.commonInstanceMetadata,
**project_ref.AsDict()))
def Modify(self, client, args, existing):
new_object = encoding.JsonToMessage(
type(existing), encoding.MessageToJson(existing))
existing_metadata = existing.commonInstanceMetadata
new_object.commonInstanceMetadata = metadata_utils.RemoveEntries(
client.messages,
existing_metadata=existing_metadata,
keys=args.keys,
remove_all=args.all)
if metadata_utils.MetadataEqual(existing_metadata,
new_object.commonInstanceMetadata):
return None
else:
return new_object
def Run(self, args):
if not args.all and not args.keys:
raise exceptions.ArgumentError(
'One of [--all] or [--keys] must be provided.')
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
project_ref = self.CreateReference(holder.resources)
get_request = self.GetGetRequest(client, project_ref)
objects = client.MakeRequests([get_request])
new_object = self.Modify(client, args, objects[0])
# If existing object is equal to the proposed object or if
# Modify() returns None, then there is no work to be done, so we
# print the resource and return.
if not new_object or objects[0] == new_object:
log.status.Print(
'No change requested; skipping update for [{0}].'.format(
objects[0].name))
return objects
return client.MakeRequests(
[self.GetSetRequest(client, project_ref, new_object)])

View File

@@ -0,0 +1,118 @@
# -*- coding: utf-8 -*- #
# Copyright 2016 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 setting the default service account on a GCE project."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.core import properties
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class SetDefaultServiceAccount(base.SilentCommand):
r"""Set the default service account on the project.
*{command}* is used to configure the default service account on project.
The project's default service account is used when a new instance is
created unless a custom service account is set via --scopes or
--no-scopes. Existing instances are not affected.
For example,
$ {command} --service-account=example@developers.gserviceaccount.com
$ gcloud compute instances create instance-name
will set the project's default service account as
example@developers.gserviceaccount.com. The instance created will have
example@developers.gserviceaccount.com as the service account associated
with because no service account email was specified in the
"instances create" command.
To remove the default service account from the project, issue the command:
$ {command} --no-service-account
The required permission to execute this command is
`compute.projects.setDefaultServiceAccount`. If needed, you can include this
permission, or choose any of the following preexisting IAM roles that contain
this particular permission:
* Owner
* Editor
* Compute Admin
"""
@staticmethod
def Args(parser):
accounts_group = parser.add_mutually_exclusive_group()
accounts_group.add_argument(
'--service-account',
help="""\
The email address of the service account that will be set as the default
service account for all newly created instances in the project.
To set the default service account to
example@project.iam.gserviceaccount.com:
$ {command} --service-account example@project.iam.gserviceaccount.com
""")
accounts_group.add_argument(
'--no-service-account',
action='store_true',
help="""\
Sets the default service account on the project as no service account.
This causes newly created instances to not run as a service account
by default.
To set the default service account as no service account, specify this
flag:
$ {command} --no-service-account
""")
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
self.validateFlags(args)
if args.no_service_account:
request = client.messages.ComputeProjectsSetDefaultServiceAccountRequest(
project=properties.VALUES.core.project.GetOrFail(),
projectsSetDefaultServiceAccountRequest=
client.messages.ProjectsSetDefaultServiceAccountRequest())
else:
request = client.messages.ComputeProjectsSetDefaultServiceAccountRequest(
project=properties.VALUES.core.project.GetOrFail(),
projectsSetDefaultServiceAccountRequest=
client.messages.ProjectsSetDefaultServiceAccountRequest(
email=args.service_account
)
)
return client.MakeRequests([(client.apitools_client.projects,
'SetDefaultServiceAccount', request)])
def validateFlags(self, args):
if not args.no_service_account and not args.service_account:
raise exceptions.RequiredArgumentException(
'--service-account', 'must be specified with a service account. To '
'clear the default service account use [--no-service-account].')

View File

@@ -0,0 +1,99 @@
# -*- 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 setting usage buckets."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.compute import exceptions as compute_exceptions
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
import six
class SetUsageBucket(base.SilentCommand):
"""Set usage reporting bucket for a project.
*{command}* configures usage reporting for projects.
Setting usage reporting will cause a log of usage per resource to be
written to a specified Google Cloud Storage bucket daily.
For example, to write daily logs of the form usage_gce_YYYYMMDD.csv
to the bucket `my-bucket`, run:
$ gcloud compute project-info set-usage-bucket --bucket=gs://my-bucket
To disable this feature, issue the command:
$ gcloud compute project-info set-usage-bucket --no-bucket
"""
@staticmethod
def Args(parser):
bucket_group = parser.add_mutually_exclusive_group(required=True)
bucket_group.add_argument(
'--no-bucket', action='store_true',
help='Unsets the bucket. This disables usage report storage.')
bucket_group.add_argument(
'--bucket',
help="""\
Name of an existing Google Cloud Storage bucket where the usage
report object should be stored. This can either be the bucket name by
itself, such as `my-bucket`, or the bucket name with `gs://`
or `https://storage.googleapis.com/` in front of it, such as
`gs://my-bucket`. The Google Service Account for
performing usage reporting is granted write access to this bucket.
The user running this command must be an owner of the bucket.
To clear the usage bucket, use `--no-bucket`.
""")
parser.add_argument(
'--prefix',
help="""\
Optional prefix for the name of the usage report object stored in
the bucket. If not supplied, then this defaults to ``usage''. The
report is stored as a CSV file named PREFIX_gce_YYYYMMDD.csv where
YYYYMMDD is the day of the usage according to Pacific Time. The prefix
should conform to Google Cloud Storage object naming conventions.
This flag must not be provided when clearing the usage bucket.
""")
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client
if not args.bucket and args.prefix:
raise compute_exceptions.ArgumentError(
'[--prefix] cannot be specified when unsetting the usage bucket.')
bucket_uri = None
if args.bucket:
bucket_uri = six.text_type(resources.REGISTRY.Parse(args.bucket))
request = client.messages.ComputeProjectsSetUsageExportBucketRequest(
project=properties.VALUES.core.project.GetOrFail(),
usageExportLocation=client.messages.UsageExportLocation(
bucketName=bucket_uri,
reportNamePrefix=args.prefix,
)
)
return client.MakeRequests([(client.apitools_client.projects,
'SetUsageExportBucket', request)])

View File

@@ -0,0 +1,113 @@
# -*- coding: utf-8 -*- #
# Copyright 2017 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 update the project."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.compute import base_classes
from googlecloudsdk.calliope import base
from googlecloudsdk.core import properties
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
r"""Update a Compute Engine project resource.
*{command}* is used to update a Compute Engine project resource.
"""
_support_managed_protection_tier = False
@classmethod
def Args(cls, parser):
parser.add_argument(
'--default-network-tier',
choices=['PREMIUM', 'STANDARD'],
type=lambda x: x.upper(),
help='The default network tier to assign to the project.')
parser.add_argument(
'--cloud-armor-tier',
choices=['CA_STANDARD', 'CA_ENTERPRISE_PAYGO', 'CA_ENTERPRISE_ANNUAL'],
type=lambda x: x.upper(),
help='Cloud armor tier to assign to the project.',
)
if cls._support_managed_protection_tier:
parser.add_argument(
'--managed-protection-tier',
choices=['CA_STANDARD', 'CAMP_PLUS_PAYGO', 'CAMP_PLUS_ANNUAL'],
type=lambda x: x.upper(),
help='Managed protection tier to assign to the project.',
)
def Run(self, args):
holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
client = holder.client.apitools_client
messages = holder.client.messages
requests = []
if args.default_network_tier:
request = messages.ComputeProjectsSetDefaultNetworkTierRequest(
project=properties.VALUES.core.project.GetOrFail(),
projectsSetDefaultNetworkTierRequest=messages.
ProjectsSetDefaultNetworkTierRequest(
networkTier=messages.ProjectsSetDefaultNetworkTierRequest.
NetworkTierValueValuesEnum(args.default_network_tier)))
requests.append((client.projects, 'SetDefaultNetworkTier', request))
if args.cloud_armor_tier:
request = messages.ComputeProjectsSetCloudArmorTierRequest(
project=properties.VALUES.core.project.GetOrFail(),
projectsSetCloudArmorTierRequest=messages.ProjectsSetCloudArmorTierRequest(
cloudArmorTier=messages.ProjectsSetCloudArmorTierRequest.CloudArmorTierValueValuesEnum(
args.cloud_armor_tier
)
),
)
requests.append((client.projects, 'SetCloudArmorTier', request))
elif self._support_managed_protection_tier and args.managed_protection_tier:
request = messages.ComputeProjectsSetManagedProtectionTierRequest(
project=properties.VALUES.core.project.GetOrFail(),
projectsSetManagedProtectionTierRequest=messages.ProjectsSetManagedProtectionTierRequest(
managedProtectionTier=messages.ProjectsSetManagedProtectionTierRequest.ManagedProtectionTierValueValuesEnum(
args.managed_protection_tier
)
),
)
requests.append((client.projects, 'SetManagedProtectionTier', request))
return holder.client.MakeRequests(requests)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
r"""Update a Compute Engine project resource.
*{command}* is used to update a Compute Engine project resource.
"""
_support_managed_protection_tier = True
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
r"""Update a Compute Engine project resource.
*{command}* is used to update a Compute Engine project resource.
"""
_support_managed_protection_tier = True