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,36 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 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.
"""Functions for Backupdr gcloud declarative commands."""
from googlecloudsdk.generated_clients.apis.backupdr.v1 import backupdr_v1_messages
def SetBasicViewByDefaultRequestHook(ref, args, request):
"""Add basic view as a default field to list request.
Args:
ref: A parsed resource reference; unused.
args: The parsed args namespace from CLI; unused.
request: List request for the API call.
Returns:
Modified request that includes the view field set to basic view.
"""
del ref, args # Unused.
request.view = (
backupdr_v1_messages.BackupdrProjectsLocationsBackupVaultsDataSourcesBackupsListRequest.ViewValueValuesEnum.BACKUP_VIEW_BASIC
)
return request

View File

@@ -0,0 +1,224 @@
project:
name: project
collection: backupdr.projects
attributes:
- &project
parameter_name: projectsId
attribute_name: project
help: |
The project name.
property: core/project
location:
name: location
collection: backupdr.projects.locations
attributes:
- *project
- &location
parameter_name: locationsId
attribute_name: location
help: |
Location ID of the resource.
disable_auto_completers: false
locationDefaultGlobal:
name: location
collection: backupdr.projects.locations
attributes:
- *project
- &locationDefaultGlobal
parameter_name: locationsId
attribute_name: location
help: |
Location ID of the resource.
fallthroughs:
- value: "-"
hint: |
default is all locations
operation:
name: operation
collection: backupdr.projects.locations.operations
attributes:
- *project
- *location
- &operation
parameter_name: operationsId
attribute_name: operation
help: |
ID of the operation.
disable_auto_completers: false
managementServer:
name: management_server
collection: backupdr.projects.locations.managementServers
request_id_field: managementServerId
attributes:
- *project
- *location
- &managementServerId
parameter_name: managementServersId
attribute_name: management_server
help: The ID of the Managment Server.
disable_auto_completers: false
backupPlans:
name: backup_plan
collection: backupdr.projects.locations.backupPlans
request_id_field: backupPlansId
attributes:
- *project
- *location
- &backupPlansId
parameter_name: backupPlansId
attribute_name: backup_plan
help: The ID of the Backup Plan
disable_auto_completers: false
backupPlanDefault:
name: backup_plan
collection: backupdr.projects.locations.backupPlans
request_id_field: backupPlansId
attributes:
- *project
- *locationDefaultGlobal
- &backupPlansDefault
parameter_name: backupPlansId
attribute_name: backup_plan
help: The ID of the Backup Plan
fallthroughs:
- value: "-"
hint: |
default is all backup plans
backupPlanRevisions:
name: backup_plan_revision
collection: backupdr.projects.locations.backupPlans.revisions
request_id_field: revisionsId
attributes:
- *project
- *location
- *backupPlansId
- &revisionsId
parameter_name: revisionsId
attribute_name: backup_plan_revision
help: The ID of the Backup Plan Revision
disable_auto_completers: false
backupPlanAssociations:
name: backup_plan_association
collection: backupdr.projects.locations.backupPlanAssociations
request_id_field: backupPlanAssociationsId
attributes:
- *project
- *location
- &backupPlanAssociationsId
parameter_name: backupPlanAssociationsId
attribute_name: backup_plan_association
help: The ID of the Backup Plan Association
disable_auto_completers: false
backupVault:
name: backup_vault
collection: backupdr.projects.locations.backupVaults
request_id_field: backupVaultId
attributes:
- *project
- *location
- &backupVaultId
parameter_name: backupVaultsId
attribute_name: backup_vault
help: The ID of the Backup Vault.
disable_auto_completers: false
backupVaultDefault:
name: backup_vault
collection: backupdr.projects.locations.backupVaults
request_id_field: backupVaultId
attributes:
- *project
- *locationDefaultGlobal
- &backupVaultDefault
parameter_name: backupVaultsId
attribute_name: backup_vault
help: The ID of the Backup Vault.
fallthroughs:
- value: "-"
hint: |
default is all backup vaults
dataSource:
name: data_source
collection: backupdr.projects.locations.backupVaults.dataSources
request_id_field: dataSourceId
attributes:
- *project
- *location
- *backupVaultId
- &dataSourceId
parameter_name: dataSourcesId
attribute_name: data_source
help: The ID of the Data Source.
disable_auto_completers: false
dataSourceDefault:
name: dataSource
collection: backupdr.projects.locations.backupVaults.dataSources
request_id_field: dataSourceId
attributes:
- *project
- *locationDefaultGlobal
- *backupVaultDefault
- &dataSourceDefault
parameter_name: dataSourcesId
attribute_name: data_source
help: The ID of the Data Source.
fallthroughs:
- value: "-"
hint: |
default is all data sources
backup:
name: backup
collection: backupdr.projects.locations.backupVaults.dataSources.backups
request_id_field: backupId
attributes:
- *project
- *location
- *backupVaultId
- *dataSourceId
- &backupId
parameter_name: backupsId
attribute_name: backup
help: The ID of the Backup.
disable_auto_completers: false
dataSourceReference:
name: data_source_reference
collection: backupdr.projects.locations.dataSourceReferences
request_id_field: dataSourceReferenceId
attributes:
- *project
- *location
- &dataSourceReferenceId
parameter_name: dataSourceReferencesId
attribute_name: data_source_reference
help: The ID of the Data Source Reference.
disable_auto_completers: false
dataSourceReferenceDefault:
name: dataSourceReference
collection: backupdr.projects.locations.dataSourceReferences
request_id_field: dataSourceReferenceId
attributes:
- *project
- *locationDefaultGlobal
- *backupVaultDefault
- &dataSourceReferenceDefault
parameter_name: dataSourceReferencesId
attribute_name: data_source_reference
help: The ID of the Data Source Reference.
fallthroughs:
- value: "-"
hint: |
default is all data source references

View File

@@ -0,0 +1,772 @@
# -*- coding: utf-8 -*- #
# Copyright 2024 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.
"""Flags for backup-dr restore compute commands."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.command_lib.backupdr import util
from googlecloudsdk.command_lib.util.apis import arg_utils
def AddNameArg(parser, required=True):
parser.add_argument(
'--name',
type=str,
required=required,
help='Name of the restored Compute Instance.',
)
def AddTargetZoneArg(parser, required=True):
parser.add_argument(
'--target-zone',
type=str,
required=required,
help='Zone where the target instance is restored.',
)
def AddTargetProjectArg(parser, required=True):
parser.add_argument(
'--target-project',
type=str,
required=required,
help='Project where the restore should happen.',
)
def AddNetworkInterfaceArg(parser, required=True):
"""Network interface of the restored resource."""
network_tier_options = ('NETWORK_TIER_UNSPECIFIED', 'STANDARD', 'PREMIUM')
stack_type_options = ('STACK_TYPE_UNSPECIFIED', 'IPV4_ONLY', 'IPV4_IPV6')
nic_type_options = ('NIC_TYPE_UNSPECIFIED', 'VIRTIO_NET', 'GVNIC')
network_tier_validator = util.GetOneOfValidator(
'network-tier', network_tier_options
)
stack_type_validator = util.GetOneOfValidator(
'stack-type', stack_type_options
)
nic_type_validator = util.GetOneOfValidator('nic-type', nic_type_options)
network_interface_spec = {
'network': str,
'subnet': str,
'private-network-ip': str,
'internal-ipv6-address': str,
'internal-ipv6-prefix-length': int,
'address': str,
'external-ipv6-address': str,
'external-ipv6-prefix-length': int,
'network-tier': network_tier_validator,
'aliases': str,
'stack-type': stack_type_validator,
'queue-count': int,
'nic-type': nic_type_validator,
'network-attachment': str,
}
parser.add_argument(
'--network-interface',
required=required,
type=arg_parsers.ArgDict(spec=network_interface_spec),
action='append',
metavar='PROPERTY=VALUE',
help=(
'Adds a network interface to the instance. This flag can be repeated'
' to specify multiple network interfaces. The following keys are'
' allowed: network, subnet, private-network-ip,'
' internal-ipv6-address, internal-ipv6-prefix-length, address,'
' external-ipv6-address, external-ipv6-prefix-length,'
' network-tier, aliases,'
' stack-type, queue-count, nic-type, network-attachment'
),
)
def AddServiceAccountArg(parser, required=True):
"""Service account used to restore."""
parser.add_argument(
'--service-account',
type=str,
required=required,
help=(
'A service account is an identity attached to the instance. Its'
' access tokens can be accessed through the instance metadata server'
' and are used to authenticate applications on the instance. The'
' account can be set using an email address corresponding to the'
' required service account. If not provided, the instance will use'
" the project's default service account."
),
)
def AddScopesArg(parser, required=True):
"""Scopes for the service account used to restore."""
scopes_group = parser.add_mutually_exclusive_group()
scopes_group.add_argument(
'--scopes',
type=arg_parsers.ArgList(str),
required=required,
metavar='SCOPE',
help=(
'If not provided, the instance will be assigned the default scopes,'
' described below. However, if neither --scopes nor --no-scopes are'
' specified and the project has no default service account, then the'
' instance will be created with no scopes. Note that the level of'
' access that a service account has is determined by a combination of'
' access scopes and IAM roles so you must configure both access'
' scopes and IAM roles for the service account to work properly.'
' SCOPE can be either the full URI of the scope or an alias. Default'
' scopes are assigned to all instances. Available aliases are:'
' https://cloud.google.com/sdk/gcloud/reference/compute/instances/create#--scopes'
),
)
scopes_group.add_argument(
'--no-scopes',
action='store_true',
help='Create the instance with no scopes.',
)
def AddCreateDiskArg(parser, required=True):
"""Attaches persistent disks to the instances."""
disk_spec = {
'name': str,
'replica-zones': arg_parsers.ArgList(str, custom_delim_char=' '),
'device-name': str,
'kms-key': str,
}
parser.add_argument(
'--create-disk',
required=required,
type=arg_parsers.ArgDict(spec=disk_spec),
action='append',
metavar='PROPERTY=VALUE',
help="""
Creates and attaches persistent disks to the instances.
*name*: Specifies the name of the disk.
*replica-zones*: Required for each regional disk associated with the
instance. Specify the URLs of the zones where the disk should be
replicated to. You must provide exactly two replica zones, and one
zone must be the same as the instance zone.
*device-name*: Device name of the disk from the source instance.
""",
)
def AddDescriptionArg(parser, required=True):
"""Description of the restored instance."""
parser.add_argument(
'--description',
type=str,
required=required,
help='Specifies a textual description of the restored instance.',
)
def AddMetadataArg(parser, required=True):
"""Metadata to be made available to the guest operating system."""
helptext = """\
Metadata to be made available to the guest operating system
running on the instances. Each metadata entry is a key/value
pair separated by an equals sign. Each metadata key must be unique
and have a max of 128 bytes in length. Each value must have a max of
256 KB in length. Multiple arguments can be
passed to this flag, e.g.,
``--metadata key-1=value-1,key-2=value-2,key-3=value-3''.
The combined total size for all metadata entries is 512 KB.
In images that have Compute Engine tools installed on them,
such as the
link:https://cloud.google.com/compute/docs/images[official images],
the following metadata keys have special meanings:
*startup-script*::: Specifies a script that will be executed
by the instances once they start running.
*startup-script-url*::: Same as ``startup-script'' except that
the script contents are pulled from a publicly-accessible
location on the web.
For startup scripts on Windows instances, the following metadata keys
have special meanings:
``windows-startup-script-url'',
``windows-startup-script-cmd'', ``windows-startup-script-bat'',
``windows-startup-script-ps1'', ``sysprep-specialize-script-url'',
``sysprep-specialize-script-cmd'', ``sysprep-specialize-script-bat'',
and ``sysprep-specialize-script-ps1''. For more information, see
[Running startup scripts](https://cloud.google.com/compute/docs/startupscript).
"""
parser.add_argument(
'--metadata',
required=required,
type=arg_parsers.ArgDict(min_length=1),
default={},
metavar='KEY=VALUE',
help=helptext,
action=arg_parsers.StoreOnceAction,
)
def AddLabelsArg(parser, required=True):
"""Labels to be added to the instance."""
helptext = """\
List of label KEY=VALUE pairs to add.
Keys must start with a lowercase character and contain only hyphens (-),
underscores (_), lowercase characters, and numbers. Values must contain
only hyphens (-), underscores (_), lowercase characters, and numbers.
"""
parser.add_argument(
'--labels',
required=required,
type=arg_parsers.ArgDict(),
default={},
metavar='KEY=VALUE',
help=helptext,
)
def AddTagsArg(parser, required=True):
"""Tags to be added to the instance."""
helptext = """\
Specifies a list of tags to apply to the instance. These tags allow
network firewall rules and routes to be applied to specified VM instances.
See gcloud_compute_firewall-rules_create(1) for more details.
"""
parser.add_argument(
'--tags',
required=required,
type=arg_parsers.ArgList(min_length=1),
metavar='TAG',
help=helptext,
)
def AddMachineTypeArg(parser, required=True):
"""Machine type used for the restored instance."""
helptext = """\
Specifies the machine type used for the restored instance. To get a list
of available machine types, run 'gcloud compute machine-types list'. If
unspecified, the default type will be based on the source instance.
This can either be the fully qualified path or the name.
For example:
* ``--machine-type=projects/my-project/zones/us-central1-a/machineTypes/n1-standard-1''
* ``--machine-type=n1-standard-1''
"""
parser.add_argument(
'--machine-type',
type=str,
required=required,
help=helptext,
)
def AddHostnameArg(parser, required=True):
"""Hostname of the restore instance."""
helptext = """\
Specify the hostname of the restore instance to be created. The specified
hostname must be RFC1035 compliant. If hostname is not specified, the
default hostname is [INSTANCE_NAME].c.[TARGET_PROJECT_ID].internal when using the
global DNS, and [INSTANCE_NAME].[ZONE].c.[TARGET_PROJECT_ID].internal when using
zonal DNS.
"""
parser.add_argument(
'--hostname',
type=str,
required=required,
help=helptext,
)
def AddEnableUefiNetworkingArg(parser, required=True):
"""Enable UEFI networking for the instance creation."""
helptext = """\
If set to true, enables UEFI networking for the instance creation.
"""
parser.add_argument(
'--enable-uefi-networking',
action=arg_parsers.StoreTrueFalseAction,
required=required,
help=helptext,
)
def AddThreadsPerCoreArg(parser, required=True):
"""The number of visible threads per physical core."""
helptext = """
The number of visible threads per physical core. To disable simultaneous
multithreading (SMT) set this to 1. Valid values are: 1 or 2.
For more information about configuring SMT, see:
https://cloud.google.com/compute/docs/instances/configuring-simultaneous-multithreading.
"""
parser.add_argument(
'--threads-per-core',
type=int,
required=required,
help=helptext,
)
def AddVisibleCoreCountArg(parser, required=True):
"""The number of physical cores to expose to the instance's guest operating system."""
helptext = """
The number of physical cores to expose to the instance's guest operating
system. The number of virtual CPUs visible to the instance's guest
operating system is this number of cores multiplied by the instance's
count of visible threads per physical core.
"""
parser.add_argument(
'--visible-core-count',
type=int,
required=required,
help=helptext,
)
def AddAcceleratorArg(parser, required=True):
"""Attaches accelerators (e.g. GPUs) to the instances."""
helptext = """\
Attaches accelerators (e.g. GPUs) to the instances.
*type*::: The specific type (e.g. nvidia-tesla-k80 for nVidia Tesla K80)
of accelerator to attach to the instances. Use 'gcloud compute
accelerator-types list' to learn about all available accelerator types.
*count*::: Number of accelerators to attach to each
instance. The default value is 1.
"""
parser.add_argument(
'--accelerator',
type=arg_parsers.ArgDict(
spec={'type': str, 'count': int}, required_keys=['type']
),
required=required,
help=helptext,
)
def AddMinCpuPlatform(parser, required=True):
"""Minimum CPU platform to be used for the instance."""
helptext = """\
When specified, the VM will be scheduled on host with specified CPU
architecture or a newer one. To list available CPU platforms in given
zone, run:
$ gcloud compute zones describe ZONE --format="value(availableCpuPlatforms)"
Default setting is "AUTOMATIC".
CPU platform selection is available only in selected zones.
You can find more information on-line:
[](https://cloud.google.com/compute/docs/instances/specify-min-cpu-platform)
"""
parser.add_argument(
'--min-cpu-platform',
type=str,
required=required,
metavar='PLATFORM',
help=helptext,
)
def AddMaintenancePolicyArg(parser, required=True):
"""Maintenance policy to be used for the instance."""
helptext = """\
Specifies the behavior of the VMs when their host machines undergo
maintenance. The default is MIGRATE.
For more information, see
https://cloud.google.com/compute/docs/instances/host-maintenance-options.
"""
parser.add_argument(
'--maintenance-policy',
choices={
'MIGRATE': (
'The instances should be migrated to a new host. This will'
' temporarily impact the performance of instances during a'
' migration event.'
),
'TERMINATE': 'The instances should be terminated.',
},
type=arg_utils.ChoiceToEnumName,
required=required,
help=helptext,
)
def AddPreemptibleArg(parser, required=True):
"""Preemptible state to be used for the instance."""
helptext = """\
If provided, instances will be preemptible and time-limited. Instances
might be preempted to free up resources for standard VM instances,
and will only be able to run for a limited amount of time. Preemptible
instances can not be restarted and will not migrate.
"""
parser.add_argument(
'--preemptible',
action=arg_parsers.StoreTrueFalseAction,
required=required,
help=helptext,
)
def AddRestartOnFailureArg(parser, required=True):
"""Restart on failure state to be used for the instance."""
helptext = """\
The instances will be restarted if they are terminated by Compute Engine.
This does not affect terminations performed by the user.
"""
parser.add_argument(
'--restart-on-failure',
action=arg_parsers.StoreTrueFalseAction,
required=required,
help=helptext,
)
def AddMinNodeCpuArg(parser, required=False):
"""Minimum Node CPUs to be used for the instance."""
helptext = """\
Minimum number of virtual CPUs this instance will consume when running on
a sole-tenant node.
"""
parser.add_argument(
'--min-node-cpu',
type=int,
required=required,
help=helptext,
)
def AddProvisioningModelArg(parser, required=False):
"""Provisioning model to be used for the instance."""
helptext = """\
Specifies provisioning model, which determines price, obtainability,
and runtime for the restored VM instance.
"""
parser.add_argument(
'--provisioning-model',
choices={
'SPOT': (
'Spot VMs are spare capacity; Spot VMs are discounted '
'to have much lower prices than standard VMs '
'but have no guaranteed runtime. Spot VMs are the new version '
'of preemptible VM instances, except Spot VMs do not have '
'a 24-hour maximum runtime.'
),
'STANDARD': (
'Default. Standard provisioning model for VM instances, '
'which has user-controlled runtime '
'but no Spot discounts.'
),
},
type=arg_utils.ChoiceToEnumName,
required=required,
help=helptext,
)
def AddInstanceTerminationActionArg(parser, required=False):
"""Termination action to be used for the instance."""
helptext = """\
Specifies the termination action that will be taken upon VM preemption
(--provisioning-model=SPOT) or automatic instance
termination (--max-run-duration or --termination-time).
"""
parser.add_argument(
'--instance-termination-action',
choices={
'STOP': (
'Default only for Spot VMs. Stop the VM without preserving'
' memory. The VM can be restarted later.'
),
'DELETE': 'Permanently delete the VM.',
},
type=arg_utils.ChoiceToEnumName,
required=required,
help=helptext,
)
def AddLocalSsdRecoveryTimeoutArg(parser, required=False):
"""Local SSD recovery timeout to be used for the instance."""
helptext = """\
Specifies the maximum amount of time a Local SSD VM should wait while
recovery of the Local SSD state is attempted. Its value should be in
between 0 and 168 hours with hour granularity and the default value being 1
hour.
"""
parser.add_argument(
'--local-ssd-recovery-timeout',
type=arg_parsers.Duration(
default_unit='h', lower_bound='0h', upper_bound='168h'
),
required=required,
help=helptext,
)
def AddNodeAffinityFileArg(parser, required=False):
"""Node affinity file to be used for the instance."""
helptext = """\
The JSON/YAML file containing the configuration of desired nodes onto
which this instance could be scheduled. These rules filter the nodes
according to their node affinity labels. A node's affinity labels come
from the node template of the group the node is in.
The file should contain a list of a JSON/YAML objects. For an example,
see https://cloud.google.com/compute/docs/nodes/provisioning-sole-tenant-vms#configure_node_affinity_labels.
The following list describes the fields:
*key*::: Corresponds to the node affinity label keys of
the Node resource.
*operator*::: Specifies the node selection type. Must be one of:
`IN`: Requires Compute Engine to seek for matched nodes.
`NOT_IN`: Requires Compute Engine to avoid certain nodes.
*values*::: Optional. A list of values which correspond to the node
affinity label values of the Node resource.
"""
parser.add_argument(
'--node-affinity-file',
type=arg_parsers.YAMLFileContents(),
required=required,
help=helptext,
hidden=True,
)
def AddReservationArgs(parser, required=False):
"""Reservation affinity to be used for the instance."""
reservation_group_helptext = """Specifies the reservation for the instance."""
reservation_affinity_helptext = """\
Specifies the reservation affinity of the instance.
"""
reservation_help_text = """The name of the reservation, required when `--reservation-affinity=specific`."""
group = parser.add_group(help=reservation_group_helptext)
group.add_argument(
'--reservation-affinity',
choices={
'any': 'Consume any available, matching reservation.',
'none': 'Do not consume from any reserved capacity.',
'specific': 'Must consume from a specific reservation.',
},
required=required,
help=reservation_affinity_helptext,
)
group.add_argument(
'--reservation',
required=required,
help=reservation_help_text,
)
def AddEnableDisplayDeviceArg(parser, required=False):
"""Enable display device for the instance."""
helptext = """\
Enable a display device on the restored VM instances. Disabled by default.
"""
parser.add_argument(
'--enable-display-device',
action=arg_parsers.StoreTrueFalseAction,
required=required,
help=helptext,
)
def AddCanIpForwardArg(parser, required=False):
"""Enable can ip forward for the restored instance."""
helptext = """\
If provided, allows the restored instances to send and receive packets
with non-matching destination or source IP addresses.
"""
parser.add_argument(
'--can-ip-forward',
action=arg_parsers.StoreTrueFalseAction,
required=required,
help=helptext,
)
def AddPrivateIpv6GoogleAccessArg(parser, required=False):
"""Enable private ipv6 google access for the restored instance."""
helptext = """\
The private IPv6 Google access type for the restored VM.
"""
enum_mappings = {
'inherit-subnetwork': 'INHERIT_FROM_SUBNETWORK',
'enable-bidirectional-access': 'ENABLE_BIDIRECTIONAL_ACCESS_TO_GOOGLE',
'enable-outbound-vm-access': 'ENABLE_OUTBOUND_VM_ACCESS_TO_GOOGLE',
}
helptext += 'PRIVATE_IPV6_GOOGLE_ACCESS_TYPE must be one of: {}'.format(
', '.join(list(enum_mappings.keys()))
)
parser.add_argument(
'--private-ipv6-google-access-type',
type=util.EnumMapper(enum_mappings).Parse,
required=required,
help=helptext,
)
def AddNetworkPerformanceConfigsArg(parser, required=False):
"""Enable network performance config for the restored instance."""
helptext = """\
Configures network performance settings for the restored instance.
If this flag is not specified, the restored instance will be created
with its source instance's network performance configuration.
*total-egress-bandwidth-tier*::: Total egress bandwidth is the available
outbound bandwidth from a VM, regardless of whether the traffic
is going to internal IP or external IP destinations.
The following tier values are allowed: [DEFAULT, TIER_1]
"""
parser.add_argument(
'--network-performance-configs',
type=arg_parsers.ArgDict(
spec={
'total-egress-bandwidth-tier': str,
},
),
metavar='PROPERTY=VALUE',
required=required,
help=helptext,
)
def AddConfidentialComputeArg(parser, required=False):
"""Enable confidential compute for the restored instance."""
helptext = """\
The restored instance boots with Confidential Computing enabled.
Confidential Computing is based on Secure Encrypted Virtualization (SEV),
an AMD virtualization feature for running confidential instances.
"""
parser.add_argument(
'--confidential-compute',
action='store_true',
required=required,
help=helptext,
)
def AddDeletionProtectionArg(parser, required=False):
"""Enable deletion protection for the restored instance."""
helptext = """\
Enables deletion protection for the restored instance.
"""
parser.add_argument(
'--deletion-protection',
action=arg_parsers.StoreTrueFalseAction,
required=required,
help=helptext,
)
def AddResourceManagerTagsArg(parser, required=False):
"""ResourceManagerTags to be added to the instance."""
helptext = """\
Specifies a list of resource manager tags to apply to the instance.
"""
parser.add_argument(
'--resource-manager-tags',
type=arg_parsers.ArgDict(),
metavar='KEY=VALUE',
required=required,
help=helptext,
)
def AddResourcePoliciesArg(parser, required=False):
"""ResourcePolicies to be added to the instance."""
helptext = """\
A list of resource policy names to be added to the instance.
The policies must exist in the same region as the instance.
"""
parser.add_argument(
'--resource-policies',
type=arg_parsers.ArgList(min_length=1),
metavar='RESOURCE_POLICY',
required=required,
help=helptext,
)
def AddKeyRevocationActionTypeArg(parser, required=False):
"""KeyRevocationActionType to be added to the instance."""
helptext = """\
Specifies the behavior of the instance when the KMS key of one of its
attached disks is revoked. The default is none. POLICY must be one of:
* none
No operation is performed.
* stop
The instance is stopped when the KMS key of one of its attached disks is
revoked.
"""
enum_mappings = {
'none': 'NONE',
'stop': 'STOP',
}
parser.add_argument(
'--key-revocation-action-type',
metavar='POLICY',
type=util.EnumMapper(enum_mappings).Parse,
required=required,
help=helptext,
)
def AddInstanceKmsKeyArg(parser, required=False):
"""InstanceKmsKey to be added to the instance."""
helptext = """\
The Cloud KMS (Key Management Service) cryptokey that will be used to
protect the restored instance.
Provide the full resource name of the cryptokey in the format:
`projects/<project>/locations/<location>/keyRings/<key-ring>/cryptoKeys/<key>`
"""
parser.add_argument(
'--instance-kms-key',
type=str,
required=required,
help=helptext,
)
def AddClearEncryptionKeyArg(parser):
"""Clear encryption key override for the disk."""
helptext = """\
The restored disk reverts to GMEK (CMEK is disabled).
"""
parser.add_argument(
'--clear-encryption-key',
action='store_true',
required=False,
help=helptext,
hidden=True,
)

View File

@@ -0,0 +1,341 @@
# -*- coding: utf-8 -*- #
# Copyright 2025 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.
"""Flags for backup-dr restore disk commands."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.command_lib.backupdr import util
from googlecloudsdk.command_lib.util.apis import arg_utils
def AddNameArg(parser, required=True):
parser.add_argument(
'--name',
type=str,
required=required,
help='Name of the restored Disk.',
)
def AddTargetZoneArg(parser, required=False):
parser.add_argument(
'--target-zone',
type=str,
required=required,
help=(
'Zone where the target disk is restored. This flag is mutually'
' exclusive with --target-region.'
),
)
def AddTargetRegionArg(parser, required=False):
parser.add_argument(
'--target-region',
type=str,
required=required,
help=(
'Region where the target disk is restored. This flag is mutually'
' exclusive with --target-zone.'
),
)
def AddTargetProjectArg(parser, required=True):
parser.add_argument(
'--target-project',
type=str,
required=required,
help='Project where the restore should happen.',
)
def AddReplicaZonesArg(parser, required=True):
parser.add_argument(
'--replica-zones',
type=arg_parsers.ArgList(min_length=2, max_length=2, element_type=str),
metavar='ZONE',
required=required,
help=(
'A comma-separated list of exactly 2 URLs of the zones where the disk'
' should be replicated to. Required when restoring'
' to a regional disk. The zones must be in the same region as'
' specified in the --target-region flag. See available zones with'
' gcloud compute zones list.'
),
)
def AddLicensesArg(parser, required=False):
parser.add_argument(
'--licenses',
type=arg_parsers.ArgList(min_length=1),
metavar='LICENSE',
required=required,
help=(
'A list of URIs to license resources. The provided licenses will be'
' added onto the created disks to indicate the licensing and billing'
' policies.'
),
)
def AddGuestOsFeaturesArgs(parser, required=False):
"""Adds a --guest-os-features flag to the given parser.
Args:
parser: A given parser.
required: Whether the argument is required or not.
"""
guest_os_features_options = (
'VIRTIO_SCSI_MULTIQUEUE',
'WINDOWS',
'MULTI_IP_SUBNET',
'UEFI_COMPATIBLE',
'SEV_CAPABLE',
'SEV_LIVE_MIGRATABLE',
'SEV_LIVE_MIGRATABLE_V2',
'SEV_SNP_CAPABLE',
'GVNIC',
'IDPF',
'TDX_CAPABLE',
'SUSPEND_RESUME_COMPATIBLE',
)
guest_os_features_validator = util.GetOneOfValidator(
'guest-os-features', guest_os_features_options
)
parser.add_argument(
'--guest-os-features',
type=arg_parsers.ArgList(guest_os_features_validator),
metavar='GUEST_OS_FEATURES',
required=required,
help=(
'Enables one or more features for VM instances that use the image'
' for their boot disks. See the descriptions of supported features'
' at: https://cloud.google.com/compute/docs/images/'
'create-delete-deprecate-private-images#guest-os-features.'
' GUEST_OS_FEATURE must be one of: {}.'.format(
', '.join(guest_os_features_options)
)
),
)
def AddDescriptionArg(parser, required=False):
"""Description of the restored disk."""
parser.add_argument(
'--description',
type=str,
required=required,
help='Specifies a textual description of the restored disk.',
)
def AddTypeArg(parser, required=True):
"""Adds a --type flag to the given parser.
Args:
parser: A given parser.
required: Whether the argument is required or not.
"""
help_text = """\
URL of the disk type describing which disk type to use to restore the disk. For example: projects/project/zones/zone/diskTypes/pd-ssd. To get a list of available disk types, run gcloud compute disk-types list. The default disk type is pd-standard.
"""
parser.add_argument(
'--type',
help=help_text,
type=str,
required=required,
)
def AddAccessModeArg(parser, required=True):
parser.add_argument(
'--access-mode',
choices={
'READ_WRITE_SINGLE': (
'The default AccessMode, means the disk can be attached to single'
' instance in RW mode.'
),
'READ_ONLY_MANY': (
'The AccessMode means the disk can be attached to multiple'
' instances in RW mode.'
),
'READ_WRITE_MANY': (
'The AccessMode means the disk can be attached to multiple'
' instances in RO mode.'
),
},
type=arg_utils.ChoiceToEnumName,
required=required,
help=(
'Specifies how VMs attached to the disk can access the data on the'
' disk. To grant read-only access to multiple VMs attached to the'
' disk, set access-mode to READ_ONLY_MANY. To grant read-write access'
' to only one VM attached to the disk, use READ_WRITE_SINGLE.'
' READ_WRITE_SINGLE is used if omitted. ACCESS_MODE must be one of:'
' READ_ONLY_MANY, READ_WRITE_MANY, READ_WRITE_SINGLE.'
),
)
def AddLabelsArg(parser, required=False):
"""Labels to be added to the disk."""
helptext = """\
List of label KEY=VALUE pairs to add.
Keys must start with a lowercase character and contain only hyphens (-),
underscores (_), lowercase characters, and numbers. Values must contain
only hyphens (-), underscores (_), lowercase characters, and numbers.
"""
parser.add_argument(
'--labels',
required=required,
type=arg_parsers.ArgDict(),
default={},
metavar='KEY=VALUE',
help=helptext,
)
def AddProvisionedIopsArg(parser, required=True):
"""Machine type used for the restored disk."""
parser.add_argument(
'--provisioned-iops',
type=arg_parsers.BoundedInt(),
required=required,
help=(
'Provisioned IOPS of disk to create. Only for use with disks of type '
'pd-extreme and hyperdisk-extreme.'
),
)
def AddArchitectureArg(parser, required=False):
return parser.add_argument(
'--architecture',
choices={
'X86_64': 'The disk can only be used with x86_64 machines.',
'ARM64': 'The disk can only be used with ARM64 machines.',
},
type=arg_utils.ChoiceToEnumName,
required=required,
help=(
'Specifies the architecture or processor type that this disk can'
' support. For available processor types on Compute Engine, see'
' https://cloud.google.com/compute/docs/cpu-platforms. ARCHITECTURE'
' must be one of: ARM64, X86_64'
),
)
def AddConfidentialComputeArg(parser, required=False):
return parser.add_argument(
'--confidential-compute',
required=required,
action='store_true',
help="""
Creates the disk with confidential compute mode enabled. Encryption with a Cloud KMS key is required to enable this option.
""",
)
def AddSizeArg(parser, required=False):
"""Size of the disk."""
helptext = """\
Size of the disk in GB.
Disk size must be a multiple of 1 GB. If disk size is not specified,
the default size of 500GB for pd-standard disks, 100GB for
pd-balanced disks, 100GB for pd-ssd disks, and 1000GB for pd-extreme disks
will be used.
For details about disk size limits,
refer to: https://cloud.google.com/compute/docs/disks
"""
parser.add_argument(
'--size',
type=arg_parsers.BoundedInt(),
required=required,
help=helptext,
)
def AddProvisionedThroughputArg(parser, required=False):
parser.add_argument(
'--provisioned-throughput',
type=arg_parsers.BoundedInt(),
required=required,
help=(
'Provisioned throughput of disk to create. The throughput unit is '
'MB per sec. Only for use with disks of type hyperdisk-throughput.'
),
)
def AddResourcePoliciesArg(parser, required=False):
"""ResourcePolicies to be added to the disk."""
helptext = """\
A list of resource policy names to be added to the disk.
The policies must exist in the same region as the disk.
"""
parser.add_argument(
'--resource-policies',
type=arg_parsers.ArgList(min_length=1),
metavar='RESOURCE_POLICY',
required=required,
help=helptext,
)
def AddKmsKeyArg(parser, required=False):
"""Kms key to be added to the instance."""
helptext = """\
The Cloud KMS (Key Management Service) cryptokey that will be used to protect the disk
Provide the full resource name of the cryptokey in the format:
projects/<project>/locations/<location>/keyRings/<key-ring>/cryptoKeys/<key>
"""
parser.add_argument(
'--kms-key',
type=str,
required=required,
help=helptext,
)
def AddClearEncryptionKeyArg(parser):
"""Clear encryption key override for the disk."""
helptext = """\
The restored disk reverts to GMEK (CMEK is disabled).
"""
parser.add_argument(
'--clear-encryption-key',
action='store_true',
required=False,
help=helptext,
)
def AddStoragePoolArg(parser, required=False):
helptext = """
Specifies the URI of the storage pool in which the disk is created.
"""
parser.add_argument(
'--storage-pool',
type=str,
required=required,
help=helptext,
)

View File

@@ -0,0 +1,141 @@
# -*- coding: utf-8 -*- #
# Copyright 2023 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.
"""Utilities for Backup and DR commands."""
import math
import uuid
from dateutil import tz
from googlecloudsdk.calliope import arg_parsers
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.core.util import iso_duration
from googlecloudsdk.core.util import times
def GenerateRequestId():
return str(uuid.uuid4())
def ConvertIntToStr(duration):
return str(duration) + 's'
def VerifyDateInFuture(date, flag):
"""Verify that the date is in the future."""
if date is None:
return None
if date < times.Now():
raise exceptions.InvalidArgumentException(
flag,
'Date must be in the future: {0}'.format(date)
)
date = date.astimezone(tz.tzutc())
return date.strftime('%Y-%m-%dT%H:%M:%SZ')
def ResetEnforcedRetention():
return '0001-01-01T00:00:00.000Z'
class OptionsMapValidator(object):
"""Option that are passed as key(alternative) value(actual) pairs are validated on the args."""
def __init__(self, options):
self.options = {opt.upper(): options[opt] for opt in options}
def Parse(self, s):
if s.upper() in self.options.keys():
return self.options[s.upper()]
elif s in self.options.values():
return s
else:
raise arg_parsers.ArgumentTypeError(
'Failed to parse the arg ({}). Value should be one of {}'.format(
s,
', '.join(
list(self.options.keys()) + list(self.options.values())
),
)
)
def TransformEnforcedRetention(backup_vault):
"""Transforms the backup vault enforced retention to a human readable format.
Args:
backup_vault: type of backup_vault can be either a Backup vault object or a
dict.
Returns:
Human readable format of backup vault enforced retention.
"""
if isinstance(backup_vault, dict):
backup_min_enforced_retention = backup_vault.get(
'backupMinimumEnforcedRetentionDuration', {}
)
else:
backup_min_enforced_retention = (
backup_vault.backupMinimumEnforcedRetentionDuration
)
if not backup_min_enforced_retention:
return ''
seconds_in_hour = 3600
seconds_in_day = 86400
seconds_in_month = 2629744
seconds_in_year = 31556926
seconds = times.ParseDuration(backup_min_enforced_retention).total_seconds
year = math.floor(seconds / seconds_in_year)
remaining_seconds = seconds % seconds_in_year
month = math.floor(remaining_seconds / seconds_in_month)
remaining_seconds %= seconds_in_month
day = math.floor(remaining_seconds / seconds_in_day)
remaining_seconds %= seconds_in_day
hour = math.ceil(remaining_seconds / seconds_in_hour)
duration = iso_duration.Duration(
years=year, months=month, days=day, hours=hour
)
return times.FormatDuration(duration, parts=-1)
def GetOneOfValidator(name, options):
validtor = arg_parsers.CustomFunctionValidator(
lambda arg: arg in options,
'{} should be one of the following: '.format(name) + ', '.join(options),
str,
)
return validtor
class EnumMapper(object):
"""Maps the args to Enum values."""
def __init__(self, enum_mapping):
self.enum_mapping = enum_mapping
def Parse(self, s):
if s in self.enum_mapping:
return self.enum_mapping[s]
else:
raise arg_parsers.ArgumentTypeError(
'Failed to parse the arg ({}). Value should be one of {}'.format(
s,
', '.join(list(self.enum_mapping.keys())),
)
)