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 2022 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 group for Cloud NetApp Volumes."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Volumes(base.Group):
"""Create and manage Cloud NetApp Volumes."""
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class VolumesBeta(Volumes):
"""Create and manage Cloud NetApp Volumes."""
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class VolumesAlpha(VolumesBeta):
"""Create and manage Cloud NetApp Volumes."""

View File

@@ -0,0 +1,177 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Create a Cloud NetApp Volume."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes import client as volumes_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp.volumes import flags as volumes_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
def _CommonArgs(parser, release_track):
volumes_flags.AddVolumeCreateArgs(parser, release_track=release_track)
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Create a Cloud NetApp Volume
""",
'EXAMPLES': """\
The following command creates a NFS Volume named NAME asynchronously using the specified arguments
$ {command} NAME --capacity=1024 --protocols=nfsv3,nfsv4 --share-name=share1 --storage-pool=sp1 --description="test description" --enable-kerberos=true --unix-permissions=0755 --async
The following command creates a SMB Volume named NAME asynchronously using the specified arguments
$ {command} NAME --capacity=1024 --protocols=smb --share-name=share2 --storage-pool=sp2 --description="test smb" --security-style=ntfs --smb-settings=SHOW_SNAPSHOT,SHOW_PREVIOUS_VERSIONS,ACCESS_BASED_ENUMERATION --snap-reserve=0.1 --async
""",
}
@staticmethod
def Args(parser):
_CommonArgs(parser, Create._RELEASE_TRACK)
def Run(self, args):
"""Create a Cloud NetApp Volume in the current project."""
volume_ref = args.CONCEPTS.volume.Parse()
client = volumes_client.VolumesClient(self._RELEASE_TRACK)
## Fill in protocol types into list
protocols = []
for protocol in args.protocols:
protocol_enum = volumes_flags.GetVolumeProtocolEnumFromArg(
protocol, client.messages)
protocols.append(protocol_enum)
capacity_in_gib = args.capacity >> 30
smb_settings = []
if args.smb_settings:
for smb_setting in args.smb_settings:
smb_setting_enum = (
volumes_flags.GetVolumeSmbSettingsEnumFromArg(
smb_setting, client.messages))
smb_settings.append(smb_setting_enum)
snapshot_policy = {}
for name, snapshot_schedule in {
'hourly_snapshot': args.snapshot_hourly,
'daily_snapshot': args.snapshot_daily,
'weekly_snapshot': args.snapshot_weekly,
'monthly_snapshot': args.snapshot_monthly
}.items():
if snapshot_schedule: # snapshot schedule is set
snapshot_policy[name] = snapshot_schedule
if not snapshot_policy:
# if no snapshot_schedule was set in args, change to None type for
# ParseVolumeConfig to easily parse
snapshot_policy = None
security_style = volumes_flags.GetVolumeSecurityStyleEnumFromArg(
args.security_style, client.messages
)
restricted_actions = []
if args.restricted_actions:
for restricted_action in args.restricted_actions:
restricted_action_enum = (
volumes_flags.GetVolumeRestrictedActionsEnumFromArg(
restricted_action, client.messages
)
)
restricted_actions.append(restricted_action_enum)
labels = labels_util.ParseCreateArgs(
args, client.messages.Volume.LabelsValue
)
large_capacity = args.large_capacity
throughput_mibps = args.throughput_mibps
multiple_endpoints = args.multiple_endpoints
cache_parameters = args.cache_parameters
cache_pre_populate = args.cache_pre_populate
block_devices = args.block_devices
if (self._RELEASE_TRACK == base.ReleaseTrack.BETA or
self._RELEASE_TRACK == base.ReleaseTrack.GA):
backup_config = args.backup_config
source_backup = args.source_backup
else:
backup_config = None
source_backup = None
volume = client.ParseVolumeConfig(
name=volume_ref.RelativeName(),
capacity=capacity_in_gib,
description=args.description,
labels=labels,
storage_pool=args.storage_pool,
protocols=protocols,
share_name=args.share_name,
export_policy=args.export_policy,
unix_permissions=args.unix_permissions,
smb_settings=smb_settings,
snapshot_policy=snapshot_policy,
snap_reserve=args.snap_reserve,
snapshot_directory=args.snapshot_directory,
security_style=security_style,
enable_kerberos=args.enable_kerberos,
snapshot=args.source_snapshot,
backup=source_backup,
restricted_actions=restricted_actions,
backup_config=backup_config,
large_capacity=large_capacity,
multiple_endpoints=multiple_endpoints,
tiering_policy=args.tiering_policy,
hybrid_replication_parameters=args.hybrid_replication_parameters,
throughput_mibps=throughput_mibps,
cache_parameters=cache_parameters,
cache_pre_populate=cache_pre_populate,
block_devices=block_devices,
)
result = client.CreateVolume(volume_ref, args.async_, volume)
if args.async_:
command = 'gcloud {} netapp volumes list'.format(
self.ReleaseTrack().prefix)
log.status.Print(
'Check the status of the new volume by listing all volumes:\n '
'$ {} '.format(command))
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@staticmethod
def Args(parser):
_CommonArgs(parser, CreateBeta._RELEASE_TRACK)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Create a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA
@staticmethod
def Args(parser):
_CommonArgs(parser, CreateAlpha._RELEASE_TRACK)

View File

@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Delete a Cloud NetApp Volume."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes import client as volumes_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp.volumes import flags as volumes_flags
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Delete(base.DeleteCommand):
"""Delete a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Delete a Cloud NetApp Volume
""",
'EXAMPLES': """\
The following command deletes a Volume named NAME in the given location
$ {command} NAME --location=us-central1
To delete a Volume named NAME asynchronously, run the following command:
$ {command} NAME --location=us-central1 --async
""",
}
@staticmethod
def Args(parser):
volumes_flags.AddVolumeDeleteArgs(parser)
def Run(self, args):
"""Deletes a Cloud NetApp Volume."""
volume_ref = args.CONCEPTS.volume.Parse()
if not args.quiet:
delete_warning = ('You are about to delete a Volume [{}].\n'
'Are you sure?'.format(volume_ref.RelativeName()))
if not console_io.PromptContinue(message=delete_warning):
return None
client = volumes_client.VolumesClient(release_track=self._RELEASE_TRACK)
result = client.DeleteVolume(volume_ref, args.async_, args.force)
if args.async_:
command = 'gcloud {} netapp volumes list'.format(
self.ReleaseTrack().prefix)
log.status.Print(
'Check the status of the deletion by listing all volumes:\n '
'$ {} '.format(command))
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DeleteBeta(Delete):
"""Delete a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DeleteAlpha(DeleteBeta):
"""Delete a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Describes a Cloud NetApp Volume."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes import client as volumes_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Describe(base.DescribeCommand):
"""Show metadata for a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Describe a Cloud NetApp Volume
""",
'EXAMPLES': """\
The following command describe a Volume named NAME in the given location
$ {command} NAME --location=us-central1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser([flags.GetVolumePresentationSpec(
'The Volume to describe.')]).AddToParser(parser)
def Run(self, args):
"""Run the describe command."""
volume_ref = args.CONCEPTS.volume.Parse()
client = volumes_client.VolumesClient(release_track=self._RELEASE_TRACK)
return client.GetVolume(volume_ref)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DescribeBeta(Describe):
"""Show metadata for a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DescribeAlpha(DescribeBeta):
"""Show metadata for a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,100 @@
# -*- 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.
"""Establish peering for Cache Volumes."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes import client as volumes_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
@base.Hidden # TODO(b/423515496): Remove hidden flag once the feature is ready.
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class EstablishPeering(base.Command):
"""Establish peering for Cache Volumes."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA
detailed_help = {
'DESCRIPTION': """\
Establish peering for Cache Volumes.
""",
'EXAMPLES': """\
The following command establishes peering for Cache Volume named NAME using the arguments specified:
$ {command} NAME --location=us-central1 --peer-cluster-name=peer-cluster-name1 --peer-svm-name=peer-svm-name1 --peer-volume-name=peer-volume-name1 --peer-ip-addresses=1.1.1.1,2.2.2.2
""",
}
@staticmethod
def Args(parser):
"""Add args for establishing peering for Cache Volume."""
concept_parsers.ConceptParser([
flags.GetVolumePresentationSpec(
'The Cache Volume to establish peering for.'
)
]).AddToParser(parser)
flags.AddResourcePeerClusterNameArg(parser)
flags.AddResourcePeerSvmNameArg(parser)
flags.AddResourcePeerVolumeNameArg(parser)
flags.AddResourcePeerIpAddressesArg(parser)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Run the establish peering command."""
volume_ref = args.CONCEPTS.volume.Parse()
client = volumes_client.VolumesClient(
release_track=self._RELEASE_TRACK
)
establish_volume_peering_request_config = (
client.ParseEstablishVolumePeeringRequestConfig(
args.peer_cluster_name,
args.peer_svm_name,
args.peer_volume_name,
args.peer_ip_addresses,
)
)
volume = client.EstablishPeering(
volume_ref,
establish_volume_peering_request_config,
args.async_,
)
return volume
@base.Hidden # TODO(b/423515496): Remove hidden flag once the feature is ready.
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class EstablishPeeringBeta(EstablishPeering):
"""Establish peering for Cache Volumes."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
# @base.Hidden # TODO(b/423515496): Uncomment this and make EstablishPeering
# point to GA release track for GA launch.
# @base.ReleaseTracks(base.ReleaseTrack.ALPHA)
# class EstablishPeeringAlpha(EstablishPeeringBeta):
# """Establish peering for Cache Volumes."""
# _RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Lists Cloud NetApp Volumes."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes import client as volumes_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes import flags as volumes_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import properties
@base.ReleaseTracks(base.ReleaseTrack.GA)
class List(base.ListCommand):
"""List Cloud NetApp Volumes."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Lists Cloud NetApp Volumes
""",
'EXAMPLES': """\
The following command lists all Volumes in the given location
$ {command} --location=us-central1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser([
flags.GetResourceListingLocationPresentationSpec(
'The location in which to list Volumes.')
]).AddToParser(parser)
parser.display_info.AddFormat(volumes_flags.VOLUMES_LIST_FORMAT)
def Run(self, args):
"""Run the list command."""
# Ensure that project is set before parsing location resource.
properties.VALUES.core.project.GetOrFail()
location_ref = args.CONCEPTS.location.Parse().RelativeName()
# Default to listing all Cloud NetApp Volumes in all locations.
location = args.location if args.location else '-'
location_list = location_ref.split('/')
location_list[-1] = location
location_ref = '/'.join(location_list)
client = volumes_client.VolumesClient(release_track=self._RELEASE_TRACK)
# TODO(b/294604013): Re-assess whether to keep or remove args.limit to be
# passed into List
return list(client.ListVolumes(location_ref, limit=args.limit))
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ListBeta(List):
"""List Cloud NetApp Volumes."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
detailed_help = {
'DESCRIPTION': """\
Lists Cloud NetApp Volumes
""",
'EXAMPLES': """\
The following command lists all Volumes in the given location
$ {command} --location=us-central1
""",
}
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListAlpha(ListBeta):
"""List Cloud NetApp Volumes."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,30 @@
# -*- 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.
"""Command group for Cloud NetApp Volume QuotaRules."""
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class QuotaRules(base.Group):
"""Create and manage Cloud NetApp Volume QuotaRules."""
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class QuotaRulesBeta(QuotaRules):
"""Create and manage Cloud NetApp Volume QuotaRules."""

View File

@@ -0,0 +1,106 @@
# -*- 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.
"""Create a Cloud NetApp Volume Quota Rule."""
from googlecloudsdk.api_lib.netapp.volumes.quota_rules import client as quota_rules_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp.volumes.quota_rules import flags as quota_rules_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a Cloud NetApp Volume Quota Rule."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Create a Cloud NetApp Volume Quota Rule.
""",
'EXAMPLES': """\
The following command creates a default `user` Quota Rule named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1 --type=DEFAULT_USER_QUOTA --disk-limit-mib=200
The following command creates a default `group` Quota Rule named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1 --type=DEFAULT_GROUP_QUOTA --disk-limit-mib=200
The following command creates an individual user Quota Rule named NAME for user with UID '100' using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1 --type=INDIVIDUAL_USER_QUOTA --target=100 --disk-limit-mib=200
The following command creates an individual group Quota Rule named NAME for group with GID '1001' using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1 --type=INDIVIDUAL_GROUP_QUOTA --target=1001 --disk-limit-mib=200
""",
}
@staticmethod
def Args(parser):
quota_rules_flags.AddQuotaRuleCreateArgs(parser)
def Run(self, args):
"""Create a Cloud NetApp Volume Quota Rule in the current project."""
quota_rule_ref = args.CONCEPTS.quota_rule.Parse()
volume_ref = args.CONCEPTS.volume.Parse().RelativeName()
client = quota_rules_client.QuotaRulesClient(self._RELEASE_TRACK)
quota_rule_type = quota_rules_flags.GetQuotaRuleTypeEnumFromArg(
args.type, client.messages
)
labels = labels_util.ParseCreateArgs(
args, client.messages.QuotaRule.LabelsValue
)
quota_rule = client.ParseQuotaRuleConfig(
name=quota_rule_ref.RelativeName(),
quota_rule_type=quota_rule_type,
target=args.target,
disk_limit_mib=args.disk_limit_mib,
description=args.description,
labels=labels,
)
result = client.CreateQuotaRule(
quota_rule_ref, volume_ref, args.async_, quota_rule
)
if args.async_:
command = 'gcloud {} netapp volumes quota-rules list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the new quota rule by listing all quota rules:\n'
'$ {} '.format(command)
)
return result
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a Cloud NetApp Volume Quota Rule."""
_RELEASE_TRACK = base.ReleaseTrack.BETA

View File

@@ -0,0 +1,89 @@
# -*- 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.
"""Delete a Cloud NetApp Volume Quota Rule."""
from googlecloudsdk.api_lib.netapp.volumes.quota_rules import client as quota_rules_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.quota_rules import flags as quota_rules_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Delete(base.DeleteCommand):
"""Delete a Cloud NetApp Volume QuotaRule."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Delete a Cloud NetApp Volume QuotaRule.
""",
'EXAMPLES': """\
The following command deletes a QuotaRule named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1
To delete a QuotaRule named NAME asynchronously, run the following command:
$ {command} NAME --location=us-central1 --volume=vol1 --async
""",
}
@staticmethod
def Args(parser):
"""Add args for deleting a Quota Rule."""
concept_parsers.ConceptParser([
flags.GetQuotaRulePresentationSpec('The Quota Rule to delete.')
]).AddToParser(parser)
quota_rules_flags.AddQuotaRuleVolumeArg(parser)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Delete a Cloud NetApp Volume QuotaRule in the current project."""
quota_rule_ref = args.CONCEPTS.quota_rule.Parse()
if not args.quiet:
delete_warning = (
'You are about to delete a QuotaRule {}.\nAre you sure?'.format(
quota_rule_ref.RelativeName()
)
)
if not console_io.PromptContinue(message=delete_warning):
return None
client = quota_rules_client.QuotaRulesClient(self._RELEASE_TRACK)
result = client.DeleteQuotaRule(quota_rule_ref, args.async_)
if args.async_:
command = 'gcloud {} netapp volumes quota-rules list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the deletion by listing all quota rules:\n '
'$ {} '.format(command)
)
return result
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DeleteBeta(Delete):
"""Delete a Cloud NetApp Volume Quota Rule."""
_RELEASE_TRACK = base.ReleaseTrack.BETA

View File

@@ -0,0 +1,64 @@
# -*- 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.
"""Describe a Cloud NetApp Volume Quota Rule."""
from googlecloudsdk.api_lib.netapp.volumes.quota_rules import client as quota_rules_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.quota_rules import flags as quota_rules_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Describe(base.DescribeCommand):
"""Describe a Cloud NetApp Volume Quota Rule."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Describe a Cloud NetApp Volume Quota Rule.
""",
'EXAMPLES': """\
The following command describes a Quota Rule named NAME in the given location and volume:
$ {command} NAME --location=us-central1 --volume=vol1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser(
[flags.GetQuotaRulePresentationSpec('The Quota Rule to describe.')]
).AddToParser(parser)
quota_rules_flags.AddQuotaRuleVolumeArg(parser, required=True)
def Run(self, args):
"""Get a Cloud NetApp Volume Quota Rule in the current project."""
quota_rule_ref = args.CONCEPTS.quota_rule.Parse()
client = quota_rules_client.QuotaRulesClient(
release_track=self._RELEASE_TRACK
)
return client.GetQuotaRule(quota_rule_ref)
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DescribeBeta(Describe):
"""Describe a Cloud NetApp Volume Quota Rule."""
_RELEASE_TRACK = base.ReleaseTrack.BETA

View File

@@ -0,0 +1,69 @@
# -*- 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.
"""List Cloud NetApp Volume Quota Rules."""
from googlecloudsdk.api_lib.netapp.volumes.quota_rules import client as quota_rules_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.quota_rules import flags as quota_rules_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import properties
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class List(base.ListCommand):
"""List Cloud NetApp Volume QuotaRules."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Lists Cloud NetApp Volume QuotaRules.
""",
'EXAMPLES': """\
The following command lists all QuotaRules in the given location and volume:
$ {command} --location=us-central1 --volume=vol1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser([
flags.GetResourceListingLocationPresentationSpec(
'The location in which to list Volume QuotaRules.')
]).AddToParser(parser)
quota_rules_flags.AddQuotaRuleVolumeArg(parser, required=True)
def Run(self, args):
"""Run the list command."""
# Ensure that project is set before parsing location resource.
properties.VALUES.core.project.GetOrFail()
volume_ref = args.CONCEPTS.volume.Parse().RelativeName()
client = quota_rules_client.QuotaRulesClient(
release_track=self._RELEASE_TRACK
)
return list(client.ListQuotaRules(volume_ref, limit=args.limit))
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ListBeta(List):
"""List Cloud NetApp Volume QuotaRules."""
_RELEASE_TRACK = base.ReleaseTrack.BETA

View File

@@ -0,0 +1,107 @@
# -*- 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.
"""Updates a Cloud NetApp Volume QuotaRule."""
from googlecloudsdk.api_lib.netapp.volumes.quota_rules import client as quota_rules_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp.volumes.quota_rules import flags as quota_rules_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Cloud NetApp Volume QuotaRule."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Update a Cloud NetApp Volume QuotaRule and its specified parameters.
""",
'EXAMPLES': """\
The following command updates a QuotaRule named NAME and its specified parameters:
$ {command} NAME --location=us-central1 --description="new" --disk-limit-mib=100 --update-labels=key2=val2 --volume=vol1
""",
}
@staticmethod
def Args(parser):
quota_rules_flags.AddQuotaRuleUpdateArgs(parser)
def Run(self, args):
"""Update a Cloud NetApp Volume QuotaRule in the current project."""
quota_rule_ref = args.CONCEPTS.quota_rule.Parse()
client = quota_rules_client.QuotaRulesClient(self._RELEASE_TRACK)
labels_diff = labels_util.Diff.FromUpdateArgs(args)
original_quota_rule = client.GetQuotaRule(quota_rule_ref)
# Update labels
if labels_diff.MayHaveUpdates():
labels = labels_diff.Apply(
client.messages.QuotaRule.LabelsValue, original_quota_rule.labels
).GetOrNone()
else:
labels = None
quota_rule = client.ParseUpdatedQuotaRuleConfig(
original_quota_rule,
disk_limit_mib=args.disk_limit_mib,
description=args.description,
labels=labels,
)
updated_fields = []
# add possible updated quota rule fields
# TODO(b/243601146) add config mapping and separate config file for update
if args.IsSpecified('description'):
updated_fields.append('description')
# Need a check for labels is not None. GetOrNone returns None if there are
# no updates to labels. If that's the case, make sure not to include the
# labels field in the field mask of the update command. Otherwise, it's
# possible to inadvertently clear the labels on the resource.
if (labels is not None) and (
args.IsSpecified('update_labels')
or args.IsSpecified('remove_labels')
or args.IsSpecified('clear_labels')
):
updated_fields.append('labels')
if args.IsSpecified('disk_limit_mib'):
updated_fields.append('diskLimitMib')
update_mask = ','.join(updated_fields)
result = client.UpdateQuotaRule(
quota_rule_ref, quota_rule, update_mask, args.async_
)
if args.async_:
command = 'gcloud {} netapp volumes quota-rules list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the updated quota rule by listing all quota'
' rules:\n $ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Cloud NetApp Volume Quota Rule."""
_RELEASE_TRACK = base.ReleaseTrack.BETA

View File

@@ -0,0 +1,37 @@
# -*- 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.
"""Command group for Cloud NetApp Volume Replications."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Replications(base.Group):
"""Create and manage Cloud NetApp Volume Replications."""
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ReplicationsBeta(Replications):
"""Create and manage Cloud NetApp Volume Replications."""
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ReplicationsAlpha(ReplicationsBeta):
"""Create and manage Cloud NetApp Volume Replications."""

View File

@@ -0,0 +1,128 @@
# -*- 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.
"""Create a Cloud NetApp Volume Replication."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp import util as netapp_api_util
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Create a Cloud NetApp Volume Replication.
""",
'EXAMPLES': """\
The following command creates a Replication named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1 --replication-schedule=EVERY_10_MINUTES --destination-volume-parameters=storage_pool=sp1,volume_id=vol2,share_name=share2
""",
}
@staticmethod
def Args(parser):
return Create._ReplicationArgs(parser, Create._RELEASE_TRACK)
@staticmethod
def _ReplicationArgs(parser, release_track):
"""Add args for creating a Replication."""
concept_parsers.ConceptParser(
[flags.GetReplicationPresentationSpec('The Replication to create.')]
).AddToParser(parser)
messages = netapp_api_util.GetMessagesModule(
release_track=release_track
)
replications_flags.AddReplicationVolumeArg(parser)
replications_flags.AddReplicationReplicationScheduleArg(parser)
replications_flags.AddReplicationDestinationVolumeParametersArg(
parser, messages
)
replications_flags.AddReplicationClusterLocationArg(parser)
flags.AddResourceAsyncFlag(parser)
flags.AddResourceDescriptionArg(parser, 'Replication')
labels_util.AddCreateLabelsFlags(parser)
def Run(self, args):
"""Create a Cloud NetApp Volume Replication in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
volume_ref = args.CONCEPTS.volume.Parse().RelativeName()
client = replications_client.ReplicationsClient(self._RELEASE_TRACK)
labels = labels_util.ParseCreateArgs(
args, client.messages.Replication.LabelsValue
)
replication_schedule_enum = (
replications_flags.GetReplicationReplicationScheduleEnumFromArg(
args.replication_schedule, client.messages
)
)
replication = client.ParseReplicationConfig(
name=replication_ref.RelativeName(),
description=args.description,
labels=labels,
replication_schedule=replication_schedule_enum,
destination_volume_parameters=args.destination_volume_parameters,
cluster_location=args.cluster_location,
)
result = client.CreateReplication(
replication_ref, volume_ref, args.async_, replication
)
if args.async_:
command = 'gcloud {} netapp volumes replications list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the new replication by listing all'
' replications:\n $ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@staticmethod
def Args(parser):
return CreateBeta._ReplicationArgs(parser, CreateBeta._RELEASE_TRACK)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Create a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA
@staticmethod
def Args(parser):
return CreateAlpha._ReplicationArgs(parser, CreateAlpha._RELEASE_TRACK)

View File

@@ -0,0 +1,99 @@
# -*- 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.
"""Delete a Cloud NetApp Volume Replication."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Delete(base.DeleteCommand):
"""Delete a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Delete a Cloud NetApp Volume Replication.
""",
'EXAMPLES': """\
The following command deletes a Replication named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1
To delete a Replication named NAME asynchronously, run the following command:
$ {command} NAME --location=us-central1 --volume=vol1 --async
""",
}
@staticmethod
def Args(parser):
"""Add args for deleting a Replication."""
concept_parsers.ConceptParser([
flags.GetReplicationPresentationSpec('The Replication to delete.')
]).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Delete a Cloud NetApp Volume Replication in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
if not args.quiet:
delete_warning = (
'You are about to delete a Replication {}.\nAre you sure?'.format(
replication_ref.RelativeName()
)
)
if not console_io.PromptContinue(message=delete_warning):
return None
client = replications_client.ReplicationsClient(self._RELEASE_TRACK)
result = client.DeleteReplication(replication_ref, args.async_)
if args.async_:
command = 'gcloud {} netapp volumes replications list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the deletion by listing all replications:\n '
'$ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DeleteBeta(Delete):
"""Delete a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DeleteAlpha(DeleteBeta):
"""Delete a Cloud NetApp Storage Pool."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,101 @@
# -*- 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.
"""Describe a Cloud NetApp Volume Replication."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Describe(base.DescribeCommand):
"""Describe a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Describe a Cloud NetApp Volume Replication.
""",
'EXAMPLES': """\
The following command describes a Replication named NAME in the given location and volume:
$ {command} NAME --location=us-central1 --volume=vol1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser(
[flags.GetReplicationPresentationSpec('The Replication to describe.')]
).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser)
def Run(self, args):
"""Get a Cloud NetApp Volume Replication in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
client = replications_client.ReplicationsClient(
release_track=self._RELEASE_TRACK
)
return client.GetReplication(replication_ref)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DescribeBeta(Describe):
"""Describe a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
detailed_help = {
'DESCRIPTION': """\
Describe a Cloud NetApp Volume Replication
""",
'EXAMPLES': """\
The following command describes a Replication named NAME in the given location and volume
$ {command} NAME --location=us-central1 --volume=vol1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser(
[flags.GetReplicationPresentationSpec('The Replication to describe.')]
).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser)
def Run(self, args):
"""Get a Cloud NetApp Volume Replication in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
client = replications_client.ReplicationsClient(
release_track=self._RELEASE_TRACK
)
return client.GetReplication(replication_ref)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DescribeAlpha(DescribeBeta):
"""Describe a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,97 @@
# -*- 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.
"""Establish peering for Hybrid replication."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class EstablishPeering(base.Command):
"""Establish peering for Hybrid replication."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Establish peering for Hybrid replication.
""",
'EXAMPLES': """\
The following command establishes peering for Hybrid replication named NAME using the arguments specified:
$ {command} NAME --volume=volume1 --peer-cluster-name=peer-cluster-name1 --peer-svm-name=peer-svm-name1 --peer-volume-name=peer-volume-name1 --peer-ip-addresses=1.1.1.1,2.2.2.2
""",
}
@staticmethod
def Args(parser):
"""Add args for establishing peering for Hybrid replication."""
concept_parsers.ConceptParser([
flags.GetReplicationPresentationSpec(
'The Hybrid replication to establish peering for.'
)
]).AddToParser(parser)
flags.AddResourcePeerClusterNameArg(parser)
flags.AddResourcePeerSvmNameArg(parser)
flags.AddResourcePeerVolumeNameArg(parser)
flags.AddResourcePeerIpAddressesArg(parser)
replications_flags.AddReplicationVolumeArg(parser)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Run the establish peering command."""
replication_ref = args.CONCEPTS.replication.Parse()
client = replications_client.ReplicationsClient(
release_track=self._RELEASE_TRACK
)
establish_peering_request_config = (
client.ParseEstablishPeeringRequestConfig(
args.peer_cluster_name,
args.peer_svm_name,
args.peer_volume_name,
args.peer_ip_addresses,
)
)
replication = client.EstablishPeering(
replication_ref,
establish_peering_request_config,
args.async_,
)
return replication
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class EstablishPeeringBeta(EstablishPeering):
"""Establish peering for Hybrid replication."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class EstablishPeeringAlpha(EstablishPeeringBeta):
"""Establish peering for Hybrid replication."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,88 @@
# -*- 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.
"""List Cloud NetApp Volume Replications."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import properties
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class List(base.ListCommand):
"""List Cloud NetApp Volume Replications."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Lists Cloud NetApp Volume Replications.
""",
'EXAMPLES': """\
The following command lists all Replications in the given location and volume:
$ {command} --location=us-central1 --volume=vol1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser(
[
flags.GetResourceListingLocationPresentationSpec(
'The location in which to list Volume Replications.'
)
]
).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser)
def Run(self, args):
"""Run the list command."""
# Ensure that project is set before parsing location resource.
properties.VALUES.core.project.GetOrFail()
if args.CONCEPTS.volume.Parse() is None:
raise exceptions.RequiredArgumentException(
'--volume', 'Requires a volume to list replications of'
)
volume_ref = args.CONCEPTS.volume.Parse().RelativeName()
client = replications_client.ReplicationsClient(
release_track=self._RELEASE_TRACK
)
return list(client.ListReplications(volume_ref, limit=args.limit))
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ListBeta(List):
"""List Cloud NetApp Volume Replications."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListAlpha(ListBeta):
"""List Cloud NetApp Volume Replications."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,89 @@
# -*- 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.
"""Resume a Cloud NetApp Volume Replication."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Resume(base.Command):
"""Resume a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Resume a Cloud NetApp Volume Replication.
""",
'EXAMPLES': """\
The following command resumes a Replication named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1
To resume a Replication named NAME asynchronously, run the following command:
$ {command} NAME --location=us-central1 --volume=vol1 --async
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser(
[flags.GetReplicationPresentationSpec('The Replication to create.')]
).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Resume a Cloud NetApp Volume Replication in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
client = replications_client.ReplicationsClient(self._RELEASE_TRACK)
result = client.ResumeReplication(
replication_ref, args.async_)
if args.async_:
command = 'gcloud {} netapp volumes replications list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the resumed replication by listing all'
' replications:\n $ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ResumeBeta(Resume):
"""Resume a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ResumeAlpha(ResumeBeta):
"""Resume a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,93 @@
# -*- 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.
"""Reverse a Cloud NetApp Volume Replication's direction."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Reverse(base.Command):
"""Reverse a Cloud NetApp Volume Replication's direction."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Reverse a Cloud NetApp Volume Replication.
""",
'EXAMPLES': """\
The following command reverses a Replication named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1
To reverse a Replication named NAME asynchronously, run the following command:
$ {command} NAME --location=us-central1 --volume=vol1 --async
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser(
[
flags.GetReplicationPresentationSpec(
'The Replication to reverse direction.'
)
]
).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser, reverse_op=True)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Reverse a Cloud NetApp Volume Replication's direction in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
client = replications_client.ReplicationsClient(self._RELEASE_TRACK)
result = client.ReverseReplication(
replication_ref, args.async_)
if args.async_:
command = 'gcloud {} netapp volumes replications list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the reversed replication by listing all'
' replications:\n $ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ReverseBeta(Reverse):
"""Reverse a Cloud NetApp Volume Replication's direction."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ReverseAlpha(ReverseBeta):
"""Reverse a Cloud NetApp Volume Replication's direction."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,90 @@
# -*- 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.
"""Stop a Cloud NetApp Volume Replication."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Stop(base.Command):
"""Stop a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Stop a Cloud NetApp Volume Replication.
""",
'EXAMPLES': """\
The following command stops a Replication named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1
To stop a Replication named NAME asynchronously, run the following command:
$ {command} NAME --location=us-central1 --volume=vol1 --async
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser(
[flags.GetReplicationPresentationSpec('The Replication to create.')]
).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser)
flags.AddResourceAsyncFlag(parser)
replications_flags.AddReplicationForceArg(parser)
def Run(self, args):
"""Stop a Cloud NetApp Volume Replication in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
client = replications_client.ReplicationsClient(self._RELEASE_TRACK)
result = client.StopReplication(
replication_ref, args.async_, args.force)
if args.async_:
command = 'gcloud {} netapp volumes replications list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the stopped replication by listing all'
' replications:\n $ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class StopBeta(Stop):
"""Stop a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class StopAlpha(StopBeta):
"""Stop a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,89 @@
# -*- 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.
"""Sync a Cloud NetApp Volume Replication."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Sync(base.Command):
"""Sync a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Sync a Cloud NetApp Volume Replication.
""",
'EXAMPLES': """\
The following command syncs a Replication named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1
To sync a Replication named NAME asynchronously, run the following command:
$ {command} NAME --location=us-central1 --volume=vol1 --async
""",
}
@staticmethod
def Args(parser):
"""Add args for syncing a Replication."""
concept_parsers.ConceptParser(
[flags.GetReplicationPresentationSpec('The Replication to sync.')]
).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Sync a Cloud NetApp Volume Replication in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
client = replications_client.ReplicationsClient(self._RELEASE_TRACK)
result = client.SyncReplication(replication_ref, args.async_)
if args.async_:
command = 'gcloud {} netapp volumes replications list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the sync replication by listing all'
' replications:\n $ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class SyncBeta(Sync):
"""Sync a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class SyncAlpha(SyncBeta):
"""Sync a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,135 @@
# -*- 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.
"""Update a Cloud NetApp Volume Replication."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.replications import client as replications_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.replications import flags as replications_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Update a Cloud NetApp Volume Replication and its specified parameters.
""",
'EXAMPLES': """\
The following command updates a Replication named NAME and its specified parameters:
$ {command} NAME --location=us-central1 --volume=vol1 --replication-schedule=EVERY_5_MINUTES --description="new description" --cluster-location= us-central1
""",
}
@staticmethod
def Args(parser):
"""Add args for updating a Replication."""
concept_parsers.ConceptParser(
[flags.GetReplicationPresentationSpec('The Replication to update.')]
).AddToParser(parser)
replications_flags.AddReplicationVolumeArg(parser)
replications_flags.AddReplicationReplicationScheduleArg(
parser, required=False
)
replications_flags.AddReplicationClusterLocationArg(parser)
flags.AddResourceAsyncFlag(parser)
flags.AddResourceDescriptionArg(parser, 'Replication')
labels_util.AddUpdateLabelsFlags(parser)
def Run(self, args):
"""Update a Cloud NetApp Volume Replication in the current project."""
replication_ref = args.CONCEPTS.replication.Parse()
client = replications_client.ReplicationsClient(self._RELEASE_TRACK)
labels_diff = labels_util.Diff.FromUpdateArgs(args)
original_replication = client.GetReplication(replication_ref)
# Update labels
if labels_diff.MayHaveUpdates():
labels = labels_diff.Apply(
client.messages.Replication.LabelsValue, original_replication.labels
).GetOrNone()
else:
labels = None
replication_schedule_enum = (
replications_flags.GetReplicationReplicationScheduleEnumFromArg(
args.replication_schedule, client.messages
)
)
replication = client.ParseUpdatedReplicationConfig(
original_replication, description=args.description, labels=labels,
replication_schedule=replication_schedule_enum,
cluster_location=args.cluster_location,
)
updated_fields = []
# Add possible updated replication fields.
# TODO(b/243601146) add config mapping and separate config file for update
if args.IsSpecified('description'):
updated_fields.append('description')
if (
args.IsSpecified('update_labels')
or args.IsSpecified('remove_labels')
or args.IsSpecified('clear_labels')
):
updated_fields.append('labels')
if args.IsSpecified('replication_schedule'):
updated_fields.append('replication_schedule')
if args.IsSpecified('cluster_location'):
updated_fields.append('cluster_location')
update_mask = ','.join(updated_fields)
result = client.UpdateReplication(
replication_ref, replication, update_mask, args.async_
)
if args.async_:
command = 'gcloud {} netapp volumes replications list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the updated replication by listing all'
' replications:\n $ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Cloud NetApp Volume Replication."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,97 @@
# -*- 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.
"""Restores selected files from a backup to a specified Volume."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes import client as volumes_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes import flags as volumes_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class RestoreBackupFiles(base.Command):
"""Restore specific files from a backup to a Volume."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA
detailed_help = {
'DESCRIPTION': """\
Restore specific files from a backup to a Volume
""",
'EXAMPLES': """\
The following command restores file1.txt and file2.txt from the given backup to a Volume named NAME to the directory /path/to/destination/directory.
$ {command} NAME --location=us-central1 --backup=backup-1 --file-list=file1.txt,file2.txt --restore-destination-path=/path/to/destination/directory
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser(
[flags.GetVolumePresentationSpec('The Volume to restore into.')]
).AddToParser(parser)
volumes_flags.AddVolumeRestoreFromBackupArg(parser)
volumes_flags.AddVolumeRestoreDestinationPathArg(parser)
volumes_flags.AddVolumeRestoreFileListArg(parser)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Run the restore command."""
volume_ref = args.CONCEPTS.volume.Parse()
client = volumes_client.VolumesClient(release_track=self._RELEASE_TRACK)
revert_warning = (
'You are about to restore files from a backup to Volume {}.\n'
'Are you sure?'.format(volume_ref.RelativeName())
)
if not console_io.PromptContinue(message=revert_warning):
return None
result = client.RestoreVolume(
volume_ref,
args.backup,
args.file_list,
args.restore_destination_path,
args.async_,
)
if args.async_:
command = 'gcloud {} netapp volumes list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the volume being restored by listing all'
' volumes:\n$ {}'.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class RestoreBackupFilesBeta(RestoreBackupFiles):
"""Restore specific files from a backup to a Volume."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.GA)
class RestoreBackupFilesGA(RestoreBackupFiles):
"""Restore specific files from a backup to a Volume."""
_RELEASE_TRACK = base.ReleaseTrack.GA

View File

@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Reverts a Cloud NetApp Volume back to a specified Snapshot."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes import client as volumes_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes import flags as volumes_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Revert(base.Command):
"""Revert a Cloud NetApp Volume back to a specified Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Revert a Cloud NetApp Volume back to a specified source Snapshot
""",
'EXAMPLES': """\
The following command reverts a Volume named NAME in the given location and snapshot
$ {command} NAME --location=us-central1 --snapshot="snapshot1"
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser([flags.GetVolumePresentationSpec(
'The Volume to revert.')]).AddToParser(parser)
volumes_flags.AddVolumeRevertSnapshotArg(parser)
flags.AddResourceAsyncFlag(parser)
def Run(self, args):
"""Run the revert command."""
volume_ref = args.CONCEPTS.volume.Parse()
client = volumes_client.VolumesClient(release_track=self._RELEASE_TRACK)
revert_warning = (
'You are about to revert Volume {} back to Snapshot {}.\n'
'Are you sure?'.format(volume_ref.RelativeName(), args.snapshot)
)
if not console_io.PromptContinue(message=revert_warning):
return None
result = client.RevertVolume(volume_ref, args.snapshot, args.async_)
if args.async_:
command = 'gcloud {} netapp volumes list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the volume being reverted by listing all'
' volumes:\n$ {}'.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class RevertBeta(Revert):
"""Revert a Cloud NetApp Volume back to a specified Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class RevertAlpha(RevertBeta):
"""Revert a Cloud NetApp Volume back to a specified Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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 group for Cloud NetApp Volume Snapshots."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.calliope import base
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Snapshots(base.Group):
"""Create and manage Cloud NetApp Volume Snapshots."""
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class SnapshotsBeta(Snapshots):
"""Create and manage Cloud NetApp Volume Snapshots."""
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class SnapshotsAlpha(SnapshotsBeta):
"""Create and manage Cloud NetApp Volume Snapshots."""

View File

@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Create a Cloud NetApp Volume Snapshot."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.snapshots import client as snapshots_client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.netapp.volumes.snapshots import flags as snapshots_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Create(base.CreateCommand):
"""Create a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Create a Cloud NetApp Volume Snapshot.
""",
'EXAMPLES': """\
The following command creates a Snapshot named NAME using the required arguments:
$ {command} NAME --location=us-central1 --volume=vol1
""",
}
@staticmethod
def Args(parser):
snapshots_flags.AddSnapshotCreateArgs(parser)
def Run(self, args):
"""Create a Cloud NetApp Volume Snapshot in the current project."""
snapshot_ref = args.CONCEPTS.snapshot.Parse()
if args.CONCEPTS.volume.Parse() is None:
raise exceptions.RequiredArgumentException(
'--volume', 'Requires a volume to create snapshot of'
)
volume_ref = args.CONCEPTS.volume.Parse().RelativeName()
client = snapshots_client.SnapshotsClient(self._RELEASE_TRACK)
labels = labels_util.ParseCreateArgs(
args, client.messages.Snapshot.LabelsValue
)
snapshot = client.ParseSnapshotConfig(
name=snapshot_ref.RelativeName(),
description=args.description,
labels=labels,
)
result = client.CreateSnapshot(
snapshot_ref, volume_ref, args.async_, snapshot
)
if args.async_:
command = 'gcloud {} netapp volumes snapshots list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the new snapshot by listing all snapshots:\n '
'$ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class CreateBeta(Create):
"""Create a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class CreateAlpha(CreateBeta):
"""Creates a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,92 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Delete a Cloud NetApp Volume Snapshot."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.snapshots import client as snapshots_client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.netapp.volumes.snapshots import flags as snapshots_flags
from googlecloudsdk.core import log
from googlecloudsdk.core.console import console_io
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Delete(base.DeleteCommand):
"""Delete a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Delete a Cloud NetApp Volume Snapshot.
""",
'EXAMPLES': """\
The following command deletes a Snapshot named NAME in the given location and volume:
$ {command} NAME --location=us-central1 --volume=vol1
To delete a Snapshot named NAME asynchronously, run the following command:
$ {command} NAME --location=us-central1 --volume=vol1 --async
""",
}
@staticmethod
def Args(parser):
snapshots_flags.AddSnapshotDeleteArgs(parser)
def Run(self, args):
"""Delete a Cloud NetApp Volume Snapshot in the current project."""
snapshot_ref = args.CONCEPTS.snapshot.Parse()
if args.CONCEPTS.volume.Parse() is None:
raise exceptions.RequiredArgumentException(
'--volume', 'Requires a volume to delete snapshot of')
if not args.quiet:
delete_warning = ('You are about to delete a Snapshot {}.\n'
'Are you sure?'.format(snapshot_ref.RelativeName()))
if not console_io.PromptContinue(message=delete_warning):
return None
client = snapshots_client.SnapshotsClient(self._RELEASE_TRACK)
result = client.DeleteSnapshot(snapshot_ref, args.async_)
if args.async_:
command = 'gcloud {} netapp volumes snapshots list'.format(
self.ReleaseTrack().prefix)
log.status.Print(
'Check the status of the deletion by listing all snapshots:\n '
'$ {} '.format(command))
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DeleteBeta(Delete):
"""Delete a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DeleteAlpha(DeleteBeta):
"""Delete a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Describe a Cloud NetApp Volume Snapshot."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.snapshots import client as snapshots_client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.snapshots import flags as snapshots_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Describe(base.DescribeCommand):
"""Describe a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Describe a Cloud NetApp Volume Snapshot.
""",
'EXAMPLES': """\
The following command describes a Snapshot named NAME in the given location and volume:
$ {command} NAME --location=us-central1 --volume=vol1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser([flags.GetSnapshotPresentationSpec(
'The Snapshot to describe.')]).AddToParser(parser)
snapshots_flags.AddSnapshotVolumeArg(parser)
def Run(self, args):
"""Get a Cloud NetApp Volume Snapshot in the current project."""
snapshot_ref = args.CONCEPTS.snapshot.Parse()
if args.CONCEPTS.volume.Parse() is None:
raise exceptions.RequiredArgumentException(
'--volume', 'Requires a volume to describe snapshot of')
client = snapshots_client.SnapshotsClient(release_track=self._RELEASE_TRACK)
return client.GetSnapshot(snapshot_ref)
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class DescribeBeta(Describe):
"""Describe a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class DescribeAlpha(DescribeBeta):
"""Describe a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""List Cloud NetApp Volume Snapshots."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.snapshots import client as snapshots_client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.netapp import flags
from googlecloudsdk.command_lib.netapp.volumes.snapshots import flags as snapshots_flags
from googlecloudsdk.command_lib.util.concepts import concept_parsers
from googlecloudsdk.core import properties
@base.ReleaseTracks(base.ReleaseTrack.GA)
class List(base.ListCommand):
"""List Cloud NetApp Volume Snapshots."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Lists Cloud NetApp Volume Snapshots.
""",
'EXAMPLES': """\
The following command lists all Snapshots in the given location and volume:
$ {command} --location=us-central1 --volume=vol1
""",
}
@staticmethod
def Args(parser):
concept_parsers.ConceptParser([
flags.GetResourceListingLocationPresentationSpec(
'The location in which to list Volume Snapshots.')
]).AddToParser(parser)
snapshots_flags.AddSnapshotVolumeArg(parser)
def Run(self, args):
"""Run the list command."""
# Ensure that project is set before parsing location resource.
properties.VALUES.core.project.GetOrFail()
if args.CONCEPTS.volume.Parse() is None:
raise exceptions.RequiredArgumentException(
'--volume', 'Requires a volume to list snapshots of')
volume_ref = args.CONCEPTS.volume.Parse().RelativeName()
client = snapshots_client.SnapshotsClient(release_track=self._RELEASE_TRACK)
return list(client.ListSnapshots(volume_ref, limit=args.limit))
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class ListBeta(List):
"""List Cloud NetApp Volume Snapshots."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class ListAlpha(ListBeta):
"""List Cloud NetApp Volume Snapshots."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,113 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Update a Cloud NetApp Volume Snapshot."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes.snapshots import client as snapshots_client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.netapp.volumes.snapshots import flags as snapshots_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Update a Cloud NetApp Volume Snapshot and its specified parameters.
""",
'EXAMPLES': """\
The following command updates a Snapshot named NAME and its specified parameters:
$ {command} NAME --location=us-central1 --description="new" --update-labels=key2=val2 --volume=vol1
""",
}
@staticmethod
def Args(parser):
snapshots_flags.AddSnapshotUpdateArgs(parser)
def Run(self, args):
"""Update a Cloud NetApp Volume Snapshot in the current project."""
snapshot_ref = args.CONCEPTS.snapshot.Parse()
if args.CONCEPTS.volume.Parse() is None:
raise exceptions.RequiredArgumentException(
'--volume', 'Requires a volume to update snapshot of')
client = snapshots_client.SnapshotsClient(self._RELEASE_TRACK)
labels_diff = labels_util.Diff.FromUpdateArgs(args)
original_snapshot = client.GetSnapshot(snapshot_ref)
# Update labels
if labels_diff.MayHaveUpdates():
labels = labels_diff.Apply(
client.messages.Snapshot.LabelsValue, original_snapshot.labels
).GetOrNone()
else:
labels = None
snapshot = client.ParseUpdatedSnapshotConfig(
original_snapshot, description=args.description, labels=labels
)
updated_fields = []
# add possible updated snapshot fields
# TODO(b/243601146) add config mapping and separate config file for update
if args.IsSpecified('description'):
updated_fields.append('description')
if (
args.IsSpecified('update_labels')
or args.IsSpecified('remove_labels')
or args.IsSpecified('clear_labels')
):
updated_fields.append('labels')
update_mask = ','.join(updated_fields)
result = client.UpdateSnapshot(
snapshot_ref, snapshot, update_mask, args.async_
)
if args.async_:
command = 'gcloud {} netapp volumes snapshots list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the updated snapshot by listing all snapshots:\n'
' $ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Cloud NetApp Volume Snapshot."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA

View File

@@ -0,0 +1,264 @@
# -*- coding: utf-8 -*- #
# Copyright 2022 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.
"""Updates a Cloud NetApp Volume."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from googlecloudsdk.api_lib.netapp.volumes import client as volumes_client
from googlecloudsdk.calliope import base
from googlecloudsdk.command_lib.netapp.volumes import flags as volumes_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
def _CommonArgs(parser, release_track):
volumes_flags.AddVolumeUpdateArgs(parser, release_track=release_track)
@base.DefaultUniverseOnly
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.UpdateCommand):
"""Update a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.GA
detailed_help = {
'DESCRIPTION': """\
Update a Cloud NetApp Volume and its specified parameters
""",
'EXAMPLES': """\
The following command updates a Volume named NAME and its specified parameters
$ {command} NAME --location=us-central1 --capacity=4096 --description="new description" --enable-kerberos=false --storage-pool=sp3 --unix-permissions=0777
""",
}
@staticmethod
def Args(parser):
_CommonArgs(parser, Update._RELEASE_TRACK)
def Run(self, args):
"""Update a Cloud NetApp Volume in the current project."""
volume_ref = args.CONCEPTS.volume.Parse()
client = volumes_client.VolumesClient(self._RELEASE_TRACK)
labels_diff = labels_util.Diff.FromUpdateArgs(args)
original_volume = client.GetVolume(volume_ref)
# Update labels
if labels_diff.MayHaveUpdates():
labels = labels_diff.Apply(client.messages.Volume.LabelsValue,
original_volume.labels).GetOrNone()
else:
labels = None
protocols = []
if args.protocols:
for protocol in args.protocols:
protocol_enum = volumes_flags.GetVolumeProtocolEnumFromArg(
protocol, client.messages
)
protocols.append(protocol_enum)
capacity_in_gib = args.capacity >> 30 if args.capacity else None
smb_settings = []
if args.smb_settings:
for smb_setting in args.smb_settings:
smb_setting_enum = volumes_flags.GetVolumeSmbSettingsEnumFromArg(
smb_setting, client.messages
)
smb_settings.append(smb_setting_enum)
restricted_actions = []
if args.restricted_actions:
for restricted_action in args.restricted_actions:
restricted_action_enum = (
volumes_flags.GetVolumeRestrictedActionsEnumFromArg(
restricted_action, client.messages
)
)
restricted_actions.append(restricted_action_enum)
snapshot_policy = {}
for name, snapshot_schedule in (
('hourly_snapshot', args.snapshot_hourly),
('daily_snapshot', args.snapshot_daily),
('weekly_snapshot', args.snapshot_weekly),
('monthly_snapshot', args.snapshot_monthly),
):
if snapshot_schedule: # snapshot schedule is set
snapshot_policy[name] = snapshot_schedule
if not snapshot_policy:
# if no snapshot_schedule was set in args, change to None type for
# ParseVolumeConfig to easily parse
snapshot_policy = None
if args.security_style:
security_style = volumes_flags.GetVolumeSecurityStyleEnumFromArg(
args.security_style, client.messages
)
else:
security_style = None
if self._RELEASE_TRACK in [base.ReleaseTrack.BETA, base.ReleaseTrack.GA]:
backup_config = args.backup_config
source_backup = args.source_backup
else:
backup_config = None
source_backup = None
cache_parameters = args.cache_parameters
cache_pre_populate = args.cache_pre_populate
block_devices = args.block_devices
throughput_mibps = args.throughput_mibps
volume = client.ParseUpdatedVolumeConfig(
original_volume,
description=args.description,
labels=labels,
storage_pool=args.storage_pool,
protocols=protocols,
share_name=args.share_name,
export_policy=args.export_policy,
capacity=capacity_in_gib,
unix_permissions=args.unix_permissions,
smb_settings=smb_settings,
snapshot_policy=snapshot_policy,
snap_reserve=args.snap_reserve,
snapshot_directory=args.snapshot_directory,
security_style=security_style,
enable_kerberos=args.enable_kerberos,
snapshot=args.source_snapshot,
backup=source_backup,
restricted_actions=restricted_actions,
backup_config=backup_config,
tiering_policy=args.tiering_policy,
cache_parameters=cache_parameters,
cache_pre_populate=cache_pre_populate,
throughput_mibps=throughput_mibps,
block_devices=block_devices,
)
updated_fields = []
# add possible updated volume fields
# TODO(b/243601146) add config mapping and separate config file for update
if args.IsSpecified('capacity'):
updated_fields.append('capacityGib')
if args.IsSpecified('storage_pool'):
updated_fields.append('storagePool')
if args.IsSpecified('share_name'):
updated_fields.append('shareName')
if args.IsSpecified('export_policy'):
updated_fields.append('exportPolicy')
if args.IsSpecified('protocols'):
updated_fields.append('protocols')
if args.IsSpecified('unix_permissions'):
updated_fields.append('unixPermissions')
if args.IsSpecified('smb_settings'):
updated_fields.append('smbSettings')
if (args.IsSpecified('snapshot_hourly') or
args.IsSpecified('snapshot_daily') or
args.IsSpecified('snapshot_weekly') or
args.IsSpecified('snapshot_monthly')):
updated_fields.append('snapshotPolicy')
if args.IsSpecified('snap_reserve'):
updated_fields.append('snapReserve')
if args.IsSpecified('snapshot_directory'):
updated_fields.append('snapshotDirectory')
if args.IsSpecified('security_style'):
updated_fields.append('securityStyle')
if args.IsSpecified('enable_kerberos'):
updated_fields.append('kerberosEnabled')
if args.IsSpecified('source_snapshot'):
updated_fields.append('restoreParameters')
if args.IsSpecified('restricted_actions'):
updated_fields.append('restrictedActions')
if args.IsSpecified('throughput_mibps'):
updated_fields.append('throughputMibps')
if (self._RELEASE_TRACK == base.ReleaseTrack.BETA or
self._RELEASE_TRACK == base.ReleaseTrack.GA):
if args.IsSpecified('source_backup'):
updated_fields.append('restoreParameters')
if backup_config is not None:
if backup_config.get('backup-policies') is not None:
updated_fields.append('backupConfig.backupPolicies')
if backup_config.get('backup-vault') is not None:
updated_fields.append('backupConfig.backupVault')
if backup_config.get('enable-scheduled-backups') is not None:
updated_fields.append('backupConfig.scheduledBackupEnabled')
if args.IsSpecified('tiering_policy'):
if args.tiering_policy.get('tier-action') is not None:
updated_fields.append('tieringPolicy.tierAction')
if args.tiering_policy.get('cooling-threshold-days') is not None:
updated_fields.append('tieringPolicy.coolingThresholdDays')
if (
self._RELEASE_TRACK == base.ReleaseTrack.BETA
or self._RELEASE_TRACK == base.ReleaseTrack.ALPHA
) and args.tiering_policy.get('enable-hot-tier-bypass-mode') is not None:
updated_fields.append('tieringPolicy.hotTierBypassModeEnabled')
if args.IsSpecified('description'):
updated_fields.append('description')
if (
args.IsSpecified('update_labels')
or args.IsSpecified('remove_labels')
or args.IsSpecified('clear_labels')
):
updated_fields.append('labels')
if (
args.IsSpecified('cache_parameters')
and args.cache_parameters.get('cache-config') is not None
):
for config in args.cache_parameters.get('cache-config'):
if 'cifs-change-notify-enabled' in config:
updated_fields.append(
'cacheParameters.cacheConfig.cifsChangeNotifyEnabled'
)
if 'write-back-enabled' in config:
updated_fields.append(
'cacheParameters.cacheConfig.writebackEnabled'
)
if args.IsSpecified('cache_pre_populate'):
updated_fields.append('cacheParameters.cacheConfig.cachePrePopulate')
if args.IsSpecified('block_devices'):
updated_fields.append('blockDevices')
update_mask = ','.join(updated_fields)
result = client.UpdateVolume(volume_ref, volume, update_mask, args.async_)
if args.async_:
command = 'gcloud {} netapp volumes list'.format(
self.ReleaseTrack().prefix
)
log.status.Print(
'Check the status of the updated volume by listing all volumes:\n '
'$ {} '.format(command)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.BETA
@staticmethod
def Args(parser):
_CommonArgs(parser, UpdateBeta._RELEASE_TRACK)
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(UpdateBeta):
"""Update a Cloud NetApp Volume."""
_RELEASE_TRACK = base.ReleaseTrack.ALPHA
@staticmethod
def Args(parser):
_CommonArgs(parser, UpdateAlpha._RELEASE_TRACK)