923 lines
34 KiB
Python
923 lines
34 KiB
Python
# -*- 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.
|
|
"""Commands for interacting with the Cloud NetApp Files Volume API resource."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from apitools.base.py import list_pager
|
|
from googlecloudsdk.api_lib.netapp import constants
|
|
from googlecloudsdk.api_lib.netapp import util
|
|
from googlecloudsdk.api_lib.util import waiter
|
|
from googlecloudsdk.calliope import base
|
|
from googlecloudsdk.core import log
|
|
from googlecloudsdk.core import resources
|
|
from googlecloudsdk.generated_clients.apis.netapp.v1beta1 import netapp_v1beta1_messages
|
|
|
|
|
|
EstablishVolumePeeringRequest = (
|
|
netapp_v1beta1_messages.EstablishVolumePeeringRequest
|
|
)
|
|
Volume = netapp_v1beta1_messages.Volume
|
|
|
|
|
|
class VolumesClient(object):
|
|
"""Wrapper for working with volumes in the Cloud NetApp Files API Client."""
|
|
|
|
def __init__(self, release_track=base.ReleaseTrack.ALPHA):
|
|
self.release_track = release_track
|
|
if self.release_track == base.ReleaseTrack.ALPHA:
|
|
self._adapter = AlphaVolumesAdapter()
|
|
elif self.release_track == base.ReleaseTrack.BETA:
|
|
self._adapter = BetaVolumesAdapter()
|
|
elif self.release_track == base.ReleaseTrack.GA:
|
|
self._adapter = VolumesAdapter()
|
|
else:
|
|
raise ValueError(
|
|
'[{}] is not a valid API version.'.format(
|
|
util.VERSION_MAP[release_track]
|
|
)
|
|
)
|
|
|
|
@property
|
|
def client(self):
|
|
return self._adapter.client
|
|
|
|
@property
|
|
def messages(self):
|
|
return self._adapter.messages
|
|
|
|
def WaitForOperation(self, operation_ref):
|
|
"""Waits on the long-running operation until the done field is True.
|
|
|
|
Args:
|
|
operation_ref: the operation reference.
|
|
|
|
Raises:
|
|
waiter.OperationError: if the operation contains an error.
|
|
|
|
Returns:
|
|
the 'response' field of the Operation.
|
|
"""
|
|
return waiter.WaitFor(
|
|
waiter.CloudOperationPollerNoResources(
|
|
self.client.projects_locations_operations
|
|
),
|
|
operation_ref,
|
|
'Waiting for [{0}] to finish'.format(operation_ref.Name()),
|
|
)
|
|
|
|
def ListVolumes(self, location_ref, limit=None):
|
|
"""Make API calls to List active Cloud NetApp Volumes.
|
|
|
|
Args:
|
|
location_ref: The parsed location of the listed NetApp Volumes.
|
|
limit: The number of Cloud NetApp Volumes to limit the results to. This
|
|
limit is passed to the server and the server does the limiting.
|
|
|
|
Returns:
|
|
Generator that yields the Cloud NetApp Volumes.
|
|
"""
|
|
request = self.messages.NetappProjectsLocationsVolumesListRequest(
|
|
parent=location_ref
|
|
)
|
|
# Check for unreachable locations.
|
|
response = self.client.projects_locations_volumes.List(request)
|
|
for location in response.unreachable:
|
|
log.warning('Location {} may be unreachable.'.format(location))
|
|
return list_pager.YieldFromList(
|
|
self.client.projects_locations_volumes,
|
|
request,
|
|
field=constants.VOLUME_RESOURCE,
|
|
limit=limit,
|
|
batch_size_attribute='pageSize',
|
|
)
|
|
|
|
def CreateVolume(self, volume_ref, async_, config):
|
|
"""Create a Cloud NetApp Volume."""
|
|
request = self.messages.NetappProjectsLocationsVolumesCreateRequest(
|
|
parent=volume_ref.Parent().RelativeName(),
|
|
volumeId=volume_ref.Name(),
|
|
volume=config,
|
|
)
|
|
create_op = self.client.projects_locations_volumes.Create(request)
|
|
if async_:
|
|
return create_op
|
|
operation_ref = resources.REGISTRY.ParseRelativeName(
|
|
create_op.name, collection=constants.OPERATIONS_COLLECTION
|
|
)
|
|
return self.WaitForOperation(operation_ref)
|
|
|
|
def ParseVolumeConfig(
|
|
self,
|
|
name=None,
|
|
capacity=None,
|
|
description=None,
|
|
storage_pool=None,
|
|
protocols=None,
|
|
share_name=None,
|
|
export_policy=None,
|
|
unix_permissions=None,
|
|
smb_settings=None,
|
|
snapshot_policy=None,
|
|
snap_reserve=None,
|
|
snapshot_directory=None,
|
|
security_style=None,
|
|
enable_kerberos=None,
|
|
snapshot=None,
|
|
backup=None,
|
|
restricted_actions=None,
|
|
backup_config=None,
|
|
large_capacity=None,
|
|
multiple_endpoints=None,
|
|
tiering_policy=None,
|
|
hybrid_replication_parameters=None,
|
|
throughput_mibps=None,
|
|
cache_parameters=None,
|
|
cache_pre_populate=None,
|
|
labels=None,
|
|
block_devices=None,
|
|
):
|
|
"""Parses the command line arguments for Create Volume into a config."""
|
|
return self._adapter.ParseVolumeConfig(
|
|
name=name,
|
|
capacity=capacity,
|
|
description=description,
|
|
storage_pool=storage_pool,
|
|
protocols=protocols,
|
|
share_name=share_name,
|
|
export_policy=export_policy,
|
|
unix_permissions=unix_permissions,
|
|
smb_settings=smb_settings,
|
|
snapshot_policy=snapshot_policy,
|
|
snap_reserve=snap_reserve,
|
|
snapshot_directory=snapshot_directory,
|
|
security_style=security_style,
|
|
enable_kerberos=enable_kerberos,
|
|
snapshot=snapshot,
|
|
backup=backup,
|
|
restricted_actions=restricted_actions,
|
|
backup_config=backup_config,
|
|
large_capacity=large_capacity,
|
|
multiple_endpoints=multiple_endpoints,
|
|
tiering_policy=tiering_policy,
|
|
hybrid_replication_parameters=hybrid_replication_parameters,
|
|
throughput_mibps=throughput_mibps,
|
|
cache_parameters=cache_parameters,
|
|
cache_pre_populate=cache_pre_populate,
|
|
labels=labels,
|
|
block_devices=block_devices,
|
|
)
|
|
|
|
def GetVolume(self, volume_ref):
|
|
"""Get Cloud NetApp Volume information."""
|
|
request = self.messages.NetappProjectsLocationsVolumesGetRequest(
|
|
name=volume_ref.RelativeName()
|
|
)
|
|
return self.client.projects_locations_volumes.Get(request)
|
|
|
|
def DeleteVolume(self, volume_ref, async_, force):
|
|
"""Deletes an existing Cloud NetApp Volume."""
|
|
request = self.messages.NetappProjectsLocationsVolumesDeleteRequest(
|
|
name=volume_ref.RelativeName(), force=force
|
|
)
|
|
return self._DeleteVolume(async_, request)
|
|
|
|
def _DeleteVolume(self, async_, request):
|
|
delete_op = self.client.projects_locations_volumes.Delete(request)
|
|
if async_:
|
|
return delete_op
|
|
operation_ref = resources.REGISTRY.ParseRelativeName(
|
|
delete_op.name, collection=constants.OPERATIONS_COLLECTION
|
|
)
|
|
return self.WaitForOperation(operation_ref)
|
|
|
|
def RevertVolume(self, volume_ref, snapshot_id, async_):
|
|
"""Reverts an existing Cloud NetApp Volume."""
|
|
request = self.messages.NetappProjectsLocationsVolumesRevertRequest(
|
|
name=volume_ref.RelativeName(),
|
|
revertVolumeRequest=self.messages.RevertVolumeRequest(
|
|
snapshotId=snapshot_id
|
|
),
|
|
)
|
|
revert_op = self.client.projects_locations_volumes.Revert(request)
|
|
if async_:
|
|
return revert_op
|
|
operation_ref = resources.REGISTRY.ParseRelativeName(
|
|
revert_op.name, collection=constants.OPERATIONS_COLLECTION
|
|
)
|
|
return self.WaitForOperation(operation_ref)
|
|
|
|
def RestoreVolume(
|
|
self, volume_ref, backup, file_list, restore_destination_path, async_
|
|
):
|
|
"""Restores specific files from a backup to a volume."""
|
|
request = self.messages.NetappProjectsLocationsVolumesRestoreRequest(
|
|
name=volume_ref.RelativeName(),
|
|
restoreBackupFilesRequest=self.messages.RestoreBackupFilesRequest(
|
|
backup=backup,
|
|
fileList=file_list,
|
|
restoreDestinationPath=restore_destination_path,
|
|
),
|
|
)
|
|
|
|
restore_op = self.client.projects_locations_volumes.Restore(request)
|
|
if async_:
|
|
return restore_op
|
|
operation_ref = resources.REGISTRY.ParseRelativeName(
|
|
restore_op.name, collection=constants.OPERATIONS_COLLECTION
|
|
)
|
|
return self.WaitForOperation(operation_ref)
|
|
|
|
def ParseUpdatedVolumeConfig(
|
|
self,
|
|
volume_config,
|
|
description=None,
|
|
labels=None,
|
|
storage_pool=None,
|
|
protocols=None,
|
|
share_name=None,
|
|
export_policy=None,
|
|
capacity=None,
|
|
unix_permissions=None,
|
|
smb_settings=None,
|
|
snapshot_policy=None,
|
|
snap_reserve=None,
|
|
snapshot_directory=None,
|
|
security_style=None,
|
|
enable_kerberos=None,
|
|
snapshot=None,
|
|
backup=None,
|
|
restricted_actions=None,
|
|
backup_config=None,
|
|
large_capacity=None,
|
|
multiple_endpoints=None,
|
|
tiering_policy=None,
|
|
cache_parameters=None,
|
|
cache_pre_populate=None,
|
|
throughput_mibps=None,
|
|
block_devices=None,
|
|
):
|
|
"""Parses updates into a volume config."""
|
|
return self._adapter.ParseUpdatedVolumeConfig(
|
|
volume_config,
|
|
description=description,
|
|
labels=labels,
|
|
storage_pool=storage_pool,
|
|
protocols=protocols,
|
|
share_name=share_name,
|
|
export_policy=export_policy,
|
|
capacity=capacity,
|
|
unix_permissions=unix_permissions,
|
|
smb_settings=smb_settings,
|
|
snapshot_policy=snapshot_policy,
|
|
snap_reserve=snap_reserve,
|
|
snapshot_directory=snapshot_directory,
|
|
security_style=security_style,
|
|
enable_kerberos=enable_kerberos,
|
|
snapshot=snapshot,
|
|
backup=backup,
|
|
restricted_actions=restricted_actions,
|
|
backup_config=backup_config,
|
|
large_capacity=large_capacity,
|
|
multiple_endpoints=multiple_endpoints,
|
|
tiering_policy=tiering_policy,
|
|
cache_parameters=cache_parameters,
|
|
cache_pre_populate=cache_pre_populate,
|
|
throughput_mibps=throughput_mibps,
|
|
block_devices=block_devices,
|
|
)
|
|
|
|
def UpdateVolume(self, volume_ref, volume_config, update_mask, async_):
|
|
"""Updates a Cloud NetApp Volume.
|
|
|
|
Args:
|
|
volume_ref: the reference to the Volume.
|
|
volume_config: Volume config, the updated volume.
|
|
update_mask: str, a comma-separated list of updated fields.
|
|
async_: bool, if False, wait for the operation to complete.
|
|
|
|
Returns:
|
|
an Operation or Volume message.
|
|
"""
|
|
update_op = self._adapter.UpdateVolume(
|
|
volume_ref, volume_config, update_mask
|
|
)
|
|
if async_:
|
|
return update_op
|
|
operation_ref = resources.REGISTRY.ParseRelativeName(
|
|
update_op.name, collection=constants.OPERATIONS_COLLECTION
|
|
)
|
|
return self.WaitForOperation(operation_ref)
|
|
|
|
def ParseEstablishVolumePeeringRequestConfig(
|
|
self,
|
|
peer_cluster_name: str,
|
|
peer_svm_name: str,
|
|
peer_volume_name: str,
|
|
peer_ip_addresses=None,
|
|
) -> EstablishVolumePeeringRequest:
|
|
"""Parses the command line arguments for EstablishPeering into a config.
|
|
|
|
Args:
|
|
peer_cluster_name: The name of the peer cluster.
|
|
peer_svm_name: The name of the peer SVM.
|
|
peer_volume_name: The name of the peer volume.
|
|
peer_ip_addresses: The list of peer IP addresses.
|
|
|
|
Returns:
|
|
An EstablishVolumePeeringRequest message.
|
|
"""
|
|
return self.messages.EstablishVolumePeeringRequest(
|
|
peerClusterName=peer_cluster_name,
|
|
peerSvmName=peer_svm_name,
|
|
peerVolumeName=peer_volume_name,
|
|
peerIpAddresses=peer_ip_addresses if peer_ip_addresses else [],
|
|
)
|
|
|
|
def EstablishPeering(
|
|
self,
|
|
volume_ref: Volume,
|
|
establish_volume_peering_request_config: EstablishVolumePeeringRequest,
|
|
async_: bool,
|
|
):
|
|
"""Establish peering between GCNV volume and an onprem ONTAP volume.
|
|
|
|
Args:
|
|
volume_ref: The reference to the volume.
|
|
establish_volume_peering_request_config: The config for the peering
|
|
request.
|
|
async_: If true, the call will return immediately, otherwise wait for
|
|
operation to complete.
|
|
|
|
Returns:
|
|
An EstablishVolumePeering operation.
|
|
"""
|
|
request = self.messages.NetappProjectsLocationsVolumesEstablishPeeringRequest(
|
|
name=volume_ref.RelativeName(),
|
|
establishVolumePeeringRequest=establish_volume_peering_request_config,
|
|
)
|
|
establish_peering_op = (
|
|
self.client.projects_locations_volumes.EstablishPeering(request)
|
|
)
|
|
if async_:
|
|
return establish_peering_op
|
|
operation_ref = resources.REGISTRY.ParseRelativeName(
|
|
establish_peering_op.name, collection=constants.OPERATIONS_COLLECTION
|
|
)
|
|
return self.WaitForOperation(operation_ref)
|
|
|
|
|
|
class VolumesAdapter(object):
|
|
"""Adapter for the Cloud NetApp Files API Volume resource."""
|
|
|
|
def __init__(self):
|
|
self.release_track = base.ReleaseTrack.GA
|
|
self.client = util.GetClientInstance(release_track=self.release_track)
|
|
self.messages = util.GetMessagesModule(release_track=self.release_track)
|
|
|
|
def ParseExportPolicy(self, volume, export_policy):
|
|
"""Parses Export Policy for Volume into a config.
|
|
|
|
Args:
|
|
volume: The Cloud NetApp Volume message object
|
|
export_policy: the Export Policy message object.
|
|
|
|
Returns:
|
|
Volume message populated with Export Policy values.
|
|
"""
|
|
if not export_policy:
|
|
return
|
|
export_policy_config = self.messages.ExportPolicy()
|
|
for policy in export_policy:
|
|
simple_export_policy_rule = self.messages.SimpleExportPolicyRule()
|
|
for key, val in policy.items():
|
|
# Support for structural pattern matching with `match` was introduced in
|
|
# Python 3.10, but gcloud still supports older Python versions (e.g.
|
|
# 3.9). Using an `if` statement instead for the time being.
|
|
if key == 'allowed-clients':
|
|
simple_export_policy_rule.allowedClients = val
|
|
elif key == 'access-type':
|
|
simple_export_policy_rule.accessType = (
|
|
self.messages.SimpleExportPolicyRule.AccessTypeValueValuesEnum.lookup_by_name(
|
|
val
|
|
)
|
|
)
|
|
elif key == 'has-root-access':
|
|
simple_export_policy_rule.hasRootAccess = val
|
|
elif key == 'kerberos-5-read-only':
|
|
simple_export_policy_rule.kerberos5ReadOnly = val
|
|
elif key == 'kerberos-5-read-write':
|
|
simple_export_policy_rule.kerberos5ReadWrite = val
|
|
elif key == 'kerberos-5i-read-only':
|
|
simple_export_policy_rule.kerberos5iReadOnly = val
|
|
elif key == 'kerberos-5i-read-write':
|
|
simple_export_policy_rule.kerberos5iReadWrite = val
|
|
elif key == 'kerberos-5p-read-only':
|
|
simple_export_policy_rule.kerberos5pReadOnly = val
|
|
elif key == 'kerberos-5p-read-write':
|
|
simple_export_policy_rule.kerberos5pReadWrite = val
|
|
elif key == 'nfsv3':
|
|
simple_export_policy_rule.nfsv3 = val
|
|
elif key == 'nfsv4':
|
|
simple_export_policy_rule.nfsv4 = val
|
|
elif key == 'squash-mode':
|
|
simple_export_policy_rule.squashMode = val
|
|
elif key == 'anon-uid':
|
|
simple_export_policy_rule.anonUid = val
|
|
export_policy_config.rules.append(simple_export_policy_rule)
|
|
volume.exportPolicy = export_policy_config
|
|
|
|
def ParseBlockDevices(self, volume, block_devices):
|
|
"""Parses Block Devices for Volume into a config."""
|
|
|
|
volume.blockDevices = [] # clear volume block devices
|
|
if block_devices is None:
|
|
return
|
|
for block_device_args in block_devices:
|
|
block_device_message = self.messages.BlockDevice()
|
|
if 'name' in block_device_args:
|
|
block_device_message.name = block_device_args['name']
|
|
for host_group in block_device_args.get('host-groups', []):
|
|
block_device_message.hostGroups.append(host_group)
|
|
if 'os-type' in block_device_args:
|
|
block_device_message.osType = block_device_args['os-type']
|
|
if 'size-gib' in block_device_args:
|
|
block_device_message.sizeGib = block_device_args['size-gib']
|
|
volume.blockDevices.append(block_device_message)
|
|
|
|
def ParseProtocols(self, volume, protocols):
|
|
"""Parses Protocols from a list of Protocol Enums into the given volume.
|
|
|
|
Args:
|
|
volume: The Cloud NetApp Volume message object
|
|
protocols: A list of protocol enums
|
|
|
|
Returns:
|
|
Volume message populated with protocol values.
|
|
"""
|
|
protocols_config = []
|
|
for protocol in protocols:
|
|
protocols_config.append(protocol)
|
|
volume.protocols = protocols_config
|
|
|
|
def ParseSnapshotPolicy(self, volume, snapshot_policy):
|
|
"""Parses Snapshot Policy from a list of snapshot schedules into a given Volume.
|
|
|
|
Args:
|
|
volume: The Cloud NetApp Volume message object
|
|
snapshot_policy: A list of snapshot policies (schedules) to parse
|
|
|
|
Returns:
|
|
Volume messages populated with snapshotPolicy field
|
|
"""
|
|
if not snapshot_policy:
|
|
return
|
|
volume.snapshotPolicy = self.messages.SnapshotPolicy()
|
|
volume.snapshotPolicy.enabled = True
|
|
for name, snapshot_schedule in snapshot_policy.items():
|
|
if name == 'hourly_snapshot':
|
|
schedule = self.messages.HourlySchedule()
|
|
schedule.snapshotsToKeep = snapshot_schedule.get('snapshots-to-keep')
|
|
schedule.minute = snapshot_schedule.get('minute', 0)
|
|
volume.snapshotPolicy.hourlySchedule = schedule
|
|
elif name == 'daily_snapshot':
|
|
schedule = self.messages.DailySchedule()
|
|
schedule.snapshotsToKeep = snapshot_schedule.get('snapshots-to-keep')
|
|
schedule.minute = snapshot_schedule.get('minute', 0)
|
|
schedule.hour = snapshot_schedule.get('hour', 0)
|
|
volume.snapshotPolicy.dailySchedule = schedule
|
|
elif name == 'weekly_snapshot':
|
|
schedule = self.messages.WeeklySchedule()
|
|
schedule.snapshotsToKeep = snapshot_schedule.get('snapshots-to-keep')
|
|
schedule.minute = snapshot_schedule.get('minute', 0)
|
|
schedule.hour = snapshot_schedule.get('hour', 0)
|
|
schedule.day = snapshot_schedule.get('day', 'Sunday')
|
|
volume.snapshotPolicy.weeklySchedule = schedule
|
|
elif name == 'monthly-snapshot':
|
|
schedule = self.messages.MonthlySchedule()
|
|
schedule.snapshotsToKeep = snapshot_schedule.get('snapshots-to-keep')
|
|
schedule.minute = snapshot_schedule.get('minute', 0)
|
|
schedule.hour = snapshot_schedule.get('hour', 0)
|
|
schedule.day = snapshot_schedule.get('day', 1)
|
|
volume.snapshotPolicy.monthlySchedule = schedule
|
|
|
|
def UpdateVolume(self, volume_ref, volume_config, update_mask):
|
|
"""Send a Patch request for the Cloud NetApp Volume."""
|
|
update_request = self.messages.NetappProjectsLocationsVolumesPatchRequest(
|
|
volume=volume_config,
|
|
name=volume_ref.RelativeName(),
|
|
updateMask=update_mask,
|
|
)
|
|
update_op = self.client.projects_locations_volumes.Patch(update_request)
|
|
return update_op
|
|
|
|
def ParseVolumeConfig(
|
|
self,
|
|
name=None,
|
|
capacity=None,
|
|
description=None,
|
|
storage_pool=None,
|
|
protocols=None,
|
|
share_name=None,
|
|
export_policy=None,
|
|
unix_permissions=None,
|
|
smb_settings=None,
|
|
snapshot_policy=None,
|
|
snap_reserve=None,
|
|
snapshot_directory=None,
|
|
security_style=None,
|
|
enable_kerberos=None,
|
|
snapshot=None,
|
|
backup=None,
|
|
restricted_actions=None,
|
|
backup_config=None,
|
|
large_capacity=None,
|
|
multiple_endpoints=None,
|
|
tiering_policy=None,
|
|
hybrid_replication_parameters=None,
|
|
throughput_mibps=None,
|
|
cache_parameters=None,
|
|
cache_pre_populate=None,
|
|
labels=None,
|
|
block_devices=None,
|
|
):
|
|
"""Parses the command line arguments for Create Volume into a config.
|
|
|
|
Args:
|
|
name: the name of the Volume
|
|
capacity: the storage capacity of the Volume.
|
|
description: the description of the Volume.
|
|
storage_pool: the Storage Pool the Volume is attached to.
|
|
protocols: the type of fileshare protocol of the Volume.
|
|
share_name: the share name or mount point of the Volume.
|
|
export_policy: the export policy of the Volume if NFS.
|
|
unix_permissions: the Unix permissions for the Volume.
|
|
smb_settings: the SMB settings for the Volume.
|
|
snapshot_policy: the Snapshot Policy for the Volume
|
|
snap_reserve: the snap reserve (double) for the Volume
|
|
snapshot_directory: Bool on whether to use snapshot directory for Volume
|
|
security_style: the security style of the Volume
|
|
enable_kerberos: Bool on whether to use kerberos for Volume
|
|
snapshot: the snapshot name to create Volume from
|
|
backup: the backup to create the Volume from.
|
|
restricted_actions: the actions to be restricted on a Volume
|
|
backup_config: the Backup Config attached to the Volume
|
|
large_capacity: Bool on whether to use large capacity for Volume
|
|
multiple_endpoints: Bool on whether to use multiple endpoints for Volume
|
|
tiering_policy: the tiering policy for the volume.
|
|
hybrid_replication_parameters: the hybrid replication parameters for the
|
|
volume.
|
|
throughput_mibps: throughput of the Volume (in MiB/s).
|
|
cache_parameters: the cache parameters for the volume.
|
|
cache_pre_populate: the cache pre-populate parameters for the volume.
|
|
labels: the parsed labels value.
|
|
block_devices: the block devices for the volume.
|
|
|
|
Returns:
|
|
the configuration that will be used as the request body for creating a
|
|
Cloud NetApp Files Volume.
|
|
"""
|
|
volume = self.messages.Volume()
|
|
volume.name = name
|
|
volume.capacityGib = capacity
|
|
volume.description = description
|
|
volume.labels = labels
|
|
volume.storagePool = storage_pool
|
|
volume.shareName = share_name
|
|
self.ParseExportPolicy(volume, export_policy)
|
|
self.ParseProtocols(volume, protocols)
|
|
volume.unixPermissions = unix_permissions
|
|
volume.smbSettings = smb_settings
|
|
self.ParseSnapshotPolicy(volume, snapshot_policy)
|
|
volume.snapReserve = snap_reserve
|
|
volume.snapshotDirectory = snapshot_directory
|
|
volume.securityStyle = security_style
|
|
volume.kerberosEnabled = enable_kerberos
|
|
restore_parameters = self.messages.RestoreParameters()
|
|
if snapshot is not None:
|
|
restore_parameters.sourceSnapshot = snapshot
|
|
if backup is not None:
|
|
restore_parameters.sourceBackup = backup
|
|
if backup is None and snapshot is None:
|
|
restore_parameters = None
|
|
volume.restoreParameters = restore_parameters
|
|
volume.restrictedActions = restricted_actions
|
|
volume.throughputMibps = throughput_mibps
|
|
if backup_config is not None:
|
|
self.ParseBackupConfig(volume, backup_config)
|
|
if large_capacity is not None:
|
|
volume.largeCapacity = large_capacity
|
|
if multiple_endpoints is not None:
|
|
volume.multipleEndpoints = multiple_endpoints
|
|
if tiering_policy is not None:
|
|
self.ParseTieringPolicy(volume, tiering_policy)
|
|
if hybrid_replication_parameters is not None:
|
|
self.ParseHybridReplicationParameters(
|
|
volume, hybrid_replication_parameters, self.release_track
|
|
)
|
|
if block_devices is not None:
|
|
self.ParseBlockDevices(volume, block_devices)
|
|
if cache_parameters is not None:
|
|
self.ParseCacheParameters(volume, cache_parameters)
|
|
if cache_pre_populate is not None:
|
|
self.ParseCachePrePopulate(volume, cache_pre_populate)
|
|
return volume
|
|
|
|
def ParseUpdatedVolumeConfig(
|
|
self,
|
|
volume_config,
|
|
description=None,
|
|
labels=None,
|
|
storage_pool=None,
|
|
protocols=None,
|
|
share_name=None,
|
|
export_policy=None,
|
|
capacity=None,
|
|
unix_permissions=None,
|
|
smb_settings=None,
|
|
snapshot_policy=None,
|
|
snap_reserve=None,
|
|
snapshot_directory=None,
|
|
security_style=None,
|
|
enable_kerberos=None,
|
|
active_directory=None,
|
|
snapshot=None,
|
|
backup=None,
|
|
restricted_actions=None,
|
|
backup_config=None,
|
|
large_capacity=None,
|
|
multiple_endpoints=None,
|
|
tiering_policy=None,
|
|
cache_parameters=None,
|
|
cache_pre_populate=None,
|
|
throughput_mibps=None,
|
|
block_devices=None,
|
|
):
|
|
"""Parse update information into an updated Volume message."""
|
|
if description is not None:
|
|
volume_config.description = description
|
|
if labels is not None:
|
|
volume_config.labels = labels
|
|
if capacity is not None:
|
|
volume_config.capacityGib = capacity
|
|
if storage_pool is not None:
|
|
volume_config.storagePool = storage_pool
|
|
if protocols is not None:
|
|
self.ParseProtocols(volume_config, protocols)
|
|
if share_name is not None:
|
|
volume_config.shareName = share_name
|
|
if export_policy is not None:
|
|
self.ParseExportPolicy(volume_config, export_policy)
|
|
if unix_permissions is not None:
|
|
volume_config.unixPermissions = unix_permissions
|
|
if smb_settings is not None:
|
|
volume_config.smbSettings = smb_settings
|
|
if snapshot_policy is not None:
|
|
self.ParseSnapshotPolicy(volume_config, snapshot_policy)
|
|
if snap_reserve is not None:
|
|
volume_config.snapReserve = snap_reserve
|
|
if snapshot_directory is not None:
|
|
volume_config.snapshotDirectory = snapshot_directory
|
|
if security_style is not None:
|
|
volume_config.securityStyle = security_style
|
|
if enable_kerberos is not None:
|
|
volume_config.kerberosEnabled = enable_kerberos
|
|
if active_directory is not None:
|
|
volume_config.activeDirectory = active_directory
|
|
if snapshot is not None or backup is not None:
|
|
self.ParseRestoreParameters(volume_config, snapshot, backup)
|
|
if restricted_actions is not None:
|
|
volume_config.restrictedActions = restricted_actions
|
|
if backup_config is not None:
|
|
self.ParseBackupConfig(volume_config, backup_config)
|
|
if large_capacity is not None:
|
|
volume_config.largeCapacity = large_capacity
|
|
if multiple_endpoints is not None:
|
|
volume_config.multipleEndpoints = multiple_endpoints
|
|
if tiering_policy is not None:
|
|
self.ParseTieringPolicy(volume_config, tiering_policy)
|
|
if cache_parameters is not None:
|
|
self.ParseCacheParameters(volume_config, cache_parameters)
|
|
if cache_pre_populate is not None:
|
|
self.ParseCachePrePopulate(volume_config, cache_pre_populate)
|
|
if throughput_mibps is not None:
|
|
volume_config.throughputMibps = throughput_mibps
|
|
if block_devices is not None:
|
|
self.ParseBlockDevices(volume_config, block_devices)
|
|
return volume_config
|
|
|
|
def ParseBackupConfig(self, volume, backup_config):
|
|
"""Parses Backup Config for Volume into a config.
|
|
|
|
Args:
|
|
volume: The Cloud NetApp Volume message object.
|
|
backup_config: the Backup Config message object.
|
|
|
|
Returns:
|
|
Volume message populated with Backup Config values.
|
|
"""
|
|
backup_config_message = self.messages.BackupConfig()
|
|
# Iterate through backup_config.
|
|
for backup_policy in backup_config.get('backup-policies', []):
|
|
backup_config_message.backupPolicies.append(backup_policy)
|
|
backup_config_message.backupVault = backup_config.get('backup-vault', '')
|
|
backup_config_message.scheduledBackupEnabled = backup_config.get(
|
|
'enable-scheduled-backups', None
|
|
)
|
|
volume.backupConfig = backup_config_message
|
|
|
|
def ParseRestoreParameters(self, volume, snapshot, backup):
|
|
"""Parses Restore Parameters for Volume into a config."""
|
|
restore_parameters = self.messages.RestoreParameters()
|
|
if snapshot:
|
|
restore_parameters.sourceSnapshot = snapshot
|
|
if backup:
|
|
restore_parameters.sourceBackup = backup
|
|
volume.restoreParameters = restore_parameters
|
|
|
|
def ParseTieringPolicy(self, volume, tiering_policy):
|
|
"""Parses Tiering Policy for Volume into a config.
|
|
|
|
Args:
|
|
volume: The Cloud NetApp Volume message object.
|
|
tiering_policy: the tiering policy message object.
|
|
|
|
Returns:
|
|
Volume message populated with Tiering Policy values.
|
|
"""
|
|
tiering_policy_message = self.messages.TieringPolicy()
|
|
tiering_policy_message.tierAction = tiering_policy.get('tier-action')
|
|
tiering_policy_message.coolingThresholdDays = tiering_policy.get(
|
|
'cooling-threshold-days'
|
|
)
|
|
if (
|
|
self.release_track == base.ReleaseTrack.BETA
|
|
or self.release_track == base.ReleaseTrack.ALPHA
|
|
):
|
|
tiering_policy_message.hotTierBypassModeEnabled = tiering_policy.get(
|
|
'enable-hot-tier-bypass-mode'
|
|
)
|
|
volume.tieringPolicy = tiering_policy_message
|
|
|
|
def ParseHybridReplicationParameters(
|
|
self,
|
|
volume,
|
|
hybrid_replication_parameters,
|
|
release_track=base.ReleaseTrack.GA,
|
|
):
|
|
"""Parses Hybrid Replication Parameters for Volume into a config.
|
|
|
|
Args:
|
|
volume: The Cloud NetApp Volume message object.
|
|
hybrid_replication_parameters: The hybrid replication params message
|
|
object.
|
|
release_track: The release track of the command.
|
|
|
|
Returns:
|
|
Volume message populated with Hybrid Replication Parameters
|
|
"""
|
|
del release_track
|
|
hybrid_replication_parameters_message = (
|
|
self.messages.HybridReplicationParameters()
|
|
)
|
|
hybrid_replication_parameters_message.replication = (
|
|
hybrid_replication_parameters.get('replication')
|
|
)
|
|
hybrid_replication_parameters_message.peerVolumeName = (
|
|
hybrid_replication_parameters.get('peer-volume-name')
|
|
)
|
|
hybrid_replication_parameters_message.peerClusterName = (
|
|
hybrid_replication_parameters.get('peer-cluster-name')
|
|
)
|
|
hybrid_replication_parameters_message.peerSvmName = (
|
|
hybrid_replication_parameters.get('peer-svm-name')
|
|
)
|
|
for ip_address in hybrid_replication_parameters.get(
|
|
'peer-ip-addresses', []
|
|
):
|
|
hybrid_replication_parameters_message.peerIpAddresses.append(ip_address)
|
|
hybrid_replication_parameters_message.clusterLocation = (
|
|
hybrid_replication_parameters.get('cluster-location')
|
|
)
|
|
hybrid_replication_parameters_message.description = (
|
|
hybrid_replication_parameters.get('description')
|
|
)
|
|
hybrid_replication_parameters_message.labels = self.messages.HybridReplicationParameters.LabelsValue(
|
|
additionalProperties=[
|
|
self.messages.HybridReplicationParameters.LabelsValue.AdditionalProperty(
|
|
key=key_value_pair.split(':')[0],
|
|
value=key_value_pair.split(':')[1],
|
|
)
|
|
for key_value_pair in hybrid_replication_parameters.get(
|
|
'labels', []
|
|
)
|
|
]
|
|
)
|
|
hybrid_replication_parameters_message.replicationSchedule = (
|
|
hybrid_replication_parameters.get('replication-schedule')
|
|
)
|
|
hybrid_replication_parameters_message.hybridReplicationType = (
|
|
hybrid_replication_parameters.get('hybrid-replication-type')
|
|
)
|
|
hybrid_replication_parameters_message.largeVolumeConstituentCount = (
|
|
hybrid_replication_parameters.get('large-volume-constituent-count')
|
|
)
|
|
|
|
volume.hybridReplicationParameters = hybrid_replication_parameters_message
|
|
|
|
def ParseCacheParameters(self, volume, cache_parameters):
|
|
"""Parses Cache Parameters for Volume into a config.
|
|
|
|
Args:
|
|
volume: The Cloud NetApp Volume message object.
|
|
cache_parameters: The cache params message object.
|
|
|
|
Returns:
|
|
Volume message populated with Cache Parameters
|
|
"""
|
|
cache_parameters_message = self.messages.CacheParameters()
|
|
cache_parameters_message.peerVolumeName = cache_parameters.get(
|
|
'peer-volume-name'
|
|
)
|
|
cache_parameters_message.peerClusterName = cache_parameters.get(
|
|
'peer-cluster-name'
|
|
)
|
|
cache_parameters_message.peerSvmName = cache_parameters.get('peer-svm-name')
|
|
for ip_address in cache_parameters.get('peer-ip-addresses', []):
|
|
cache_parameters_message.peerIpAddresses.append(ip_address)
|
|
cache_parameters_message.enableGlobalFileLock = cache_parameters.get(
|
|
'enable-global-file-lock'
|
|
)
|
|
cache_config_message = self.messages.CacheConfig()
|
|
for config in cache_parameters.get('cache-config', []):
|
|
if 'cifs-change-notify-enabled' in config:
|
|
cache_config_message.cifsChangeNotifyEnabled = (
|
|
config['cifs-change-notify-enabled'].lower() == 'true'
|
|
)
|
|
if 'write-back-enabled' in config:
|
|
cache_config_message.writebackEnabled = (
|
|
config['write-back-enabled'].lower() == 'true'
|
|
)
|
|
cache_parameters_message.cacheConfig = cache_config_message
|
|
volume.cacheParameters = cache_parameters_message
|
|
|
|
def ParseCachePrePopulate(self, volume, cache_pre_populate):
|
|
"""Parses Cache Pre-populate for Volume into a config.
|
|
|
|
Args:
|
|
volume: The Cloud NetApp Volume message object.
|
|
cache_pre_populate: The cache pre-populate params message object.
|
|
|
|
Returns:
|
|
Volume message populated with Cache Pre-populate Parameters
|
|
"""
|
|
cache_pre_populate_message = self.messages.CachePrePopulate()
|
|
for path in cache_pre_populate.get('path-list', []):
|
|
cache_pre_populate_message.pathList.append(path)
|
|
for path in cache_pre_populate.get('exclude-path-list', []):
|
|
cache_pre_populate_message.excludePathList.append(path)
|
|
cache_pre_populate_message.recursion = cache_pre_populate.get(
|
|
'recursion'
|
|
)
|
|
if volume.cacheParameters is None:
|
|
volume.cacheParameters = self.messages.CacheParameters()
|
|
if volume.cacheParameters.cacheConfig is None:
|
|
volume.cacheParameters.cacheConfig = self.messages.CacheConfig()
|
|
volume.cacheParameters.cacheConfig.cachePrePopulate = (
|
|
cache_pre_populate_message
|
|
)
|
|
|
|
|
|
class BetaVolumesAdapter(VolumesAdapter):
|
|
"""Adapter for the Beta Cloud NetApp Files API Volume resource."""
|
|
|
|
def __init__(self):
|
|
super(BetaVolumesAdapter, self).__init__()
|
|
self.release_track = base.ReleaseTrack.BETA
|
|
self.client = util.GetClientInstance(release_track=self.release_track)
|
|
self.messages = util.GetMessagesModule(release_track=self.release_track)
|
|
|
|
|
|
class AlphaVolumesAdapter(BetaVolumesAdapter):
|
|
"""Adapter for the Alpha Cloud NetApp Files API Volume resource."""
|
|
|
|
def __init__(self):
|
|
super(AlphaVolumesAdapter, self).__init__()
|
|
self.release_track = base.ReleaseTrack.ALPHA
|
|
self.client = util.GetClientInstance(release_track=self.release_track)
|
|
self.messages = util.GetMessagesModule(release_track=self.release_track)
|