File: //snap/google-cloud-cli/current/lib/surface/filestore/instances/update.py
# -*- coding: utf-8 -*- #
# Copyright 2018 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 Filestore instance."""
import textwrap
from googlecloudsdk.api_lib.filestore import filestore_client
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import exceptions
from googlecloudsdk.command_lib.filestore.instances import dp_util
from googlecloudsdk.command_lib.filestore.instances import flags as instances_flags
from googlecloudsdk.command_lib.util.args import labels_util
from googlecloudsdk.core import log
def _CommonArgs(parser, api_version=filestore_client.V1_API_VERSION):
instances_flags.AddInstanceUpdateArgs(parser, api_version)
@base.UniverseCompatible
@base.ReleaseTracks(base.ReleaseTrack.GA)
class Update(base.CreateCommand):
"""Update a Filestore instance."""
_API_VERSION = filestore_client.V1_API_VERSION
detailed_help = {
'DESCRIPTION':
'Update a Filestore instance.',
'EXAMPLES':
textwrap.dedent("""\
The following command updates the Filestore instance NAME to change the
description to "A new description."
$ {command} NAME --description="A new description."
The following command updates a Filestore instance named NAME to add the label
"key1=value1" and remove any metadata with the label "key2".
$ {command} NAME --update-labels=key1=value1 --remove-labels=key2
$ {command} NAME --zone=ZONE --flags-file=FILE_PATH
Example json configuration file:
{
"--file-share":
{
"capacity": "102400",
"name": "my_vol",
"nfs-export-options": [
{
"access-mode": "READ_WRITE",
"ip-ranges": [
"10.0.0.0/29",
"10.2.0.0/29"
],
"squash-mode": "ROOT_SQUASH",
"anon_uid": 1003,
"anon_gid": 1003
}
]
}
}
The following command updates a Filestore instance named NAME to change the
capacity to CAPACITY.
$ {command} NAME --project=PROJECT_ID --zone=ZONE\
--file-share=name=VOLUME_NAME,capacity=CAPACITY
The following command updates a Filestore instance named NAME to configure the
max-iops-per-tb to MAX-IOPS-PER-TB.
$ {command} NAME --project=PROJECT_ID --zone=ZONE\
--performance=max-iops-per-tb=MAX-IOPS-PER-TB
"""),
}
@staticmethod
def Args(parser):
_CommonArgs(parser, Update._API_VERSION)
def Run(self, args):
"""Runs command line arguments.
Args:
args: Command line arguments.
Returns:
The client instance.
Raises:
InvalidArgumentException: For invalid JSON formatted --file-args.
"""
instance_ref = args.CONCEPTS.instance.Parse()
client = filestore_client.FilestoreClient(self._API_VERSION)
labels_diff = labels_util.Diff.FromUpdateArgs(args)
dp_util.ValidateDeletionProtectionUpdateArgs(args)
orig_instance = client.GetInstance(instance_ref)
try:
if args.file_share:
client.MakeNFSExportOptionsMsg(
messages=client.messages,
nfs_export_options=args.file_share.get('nfs-export-options', []),
)
except KeyError as err:
raise exceptions.InvalidArgumentException(
'--file-share', str(err)
)
if labels_diff.MayHaveUpdates():
labels = labels_diff.Apply(
client.messages.Instance.LabelsValue, orig_instance.labels
).GetOrNone()
else:
labels = None
try:
instance = client.ParseUpdatedInstanceConfig(
orig_instance,
description=args.description,
labels=labels,
file_share=args.file_share,
performance=args.performance,
ldap=args.ldap,
disconnect_ldap=args.disconnect_ldap,
clear_nfs_export_options=args.clear_nfs_export_options,
deletion_protection_enabled=args.deletion_protection,
deletion_protection_reason=args.deletion_protection_reason,
)
except filestore_client.InvalidDisconnectLdapError as e:
raise exceptions.InvalidArgumentException(
'--disconnect-ldap', str(e)
)
except filestore_client.InvalidDisconnectManagedADError as e:
raise exceptions.InvalidArgumentException(
'--disconnect-managed-ad', str(e)
)
except filestore_client.Error as e:
raise exceptions.InvalidArgumentException(
'--file-share', str(e)
)
updated_fields = []
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('file_share'):
updated_fields.append('fileShares')
if args.IsSpecified('performance'):
updated_fields.append('performanceConfig')
updated_fields += dp_util.GetDeletionProtectionUpdateMask(args)
if args.IsSpecified('ldap') or args.IsSpecified('disconnect_ldap'):
updated_fields.append('directoryServices')
update_mask = ','.join(updated_fields)
result = client.UpdateInstance(
instance_ref, instance, update_mask, args.async_
)
if args.async_:
log.status.Print(
'To check the status of the operation, run `gcloud filestore '
'operations describe {}`'.format(result.name)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.ALPHA)
class UpdateAlpha(Update):
"""Update a Filestore instance."""
_API_VERSION = filestore_client.ALPHA_API_VERSION
detailed_help = {
'DESCRIPTION':
'Update a Filestore instance.',
'EXAMPLES':
textwrap.dedent("""\
The following command updates the Filestore instance NAME to change the
description to "A new description."
$ {command} NAME --description="A new description."
The following command updates a Filestore instance named NAME to add the label
"key1=value1" and remove any metadata with the label "key2".
$ {command} NAME --update-labels=key1=value1 --remove-labels=key2
$ {command} NAME --zone=ZONE --flags-file=FILE_PATH
Example json configuration file:
{
"--file-share":
{
"capacity": "102400",
"name": "my_vol",
"nfs-export-options": [
{
"access-mode": "READ_WRITE",
"ip-ranges": [
"10.0.0.0/29",
"10.2.0.0/29"
],
"squash-mode": "ROOT_SQUASH",
"anon_uid": 1003,
"anon_gid": 1003
}
]
}
}
The following command updates a Filestore instance named NAME to change the
capacity to CAPACITY.
$ {command} NAME --project=PROJECT_ID --zone=ZONE\
--file-share=name=VOLUME_NAME,capacity=CAPACITY
"""),
}
@staticmethod
def Args(parser):
_CommonArgs(parser, UpdateAlpha._API_VERSION)
def Run(self, args):
"""Runs command line arguments.
Args:
args: Command line arguments.
Returns:
The client instance.
Raises:
InvalidArgumentException: For invalid JSON formatted --file-args.
"""
instance_ref = args.CONCEPTS.instance.Parse()
client = filestore_client.FilestoreClient(self._API_VERSION)
labels_diff = labels_util.Diff.FromUpdateArgs(args)
orig_instance = client.GetInstance(instance_ref)
try:
if args.file_share:
client.MakeNFSExportOptionsMsg(
messages=client.messages,
nfs_export_options=args.file_share.get('nfs-export-options', []),
)
except KeyError as err:
raise exceptions.InvalidArgumentException(
'--file-share', str(err)
)
if labels_diff.MayHaveUpdates():
labels = labels_diff.Apply(
client.messages.Instance.LabelsValue, orig_instance.labels
).GetOrNone()
else:
labels = None
try:
instance = client.ParseUpdatedInstanceConfig(
orig_instance,
description=args.description,
labels=labels,
file_share=args.file_share,
clear_nfs_export_options=args.clear_nfs_export_options,
)
except filestore_client.Error as e:
raise exceptions.InvalidArgumentException(
'--file-share', str(e)
)
updated_fields = []
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('file_share'):
updated_fields.append('fileShares')
update_mask = ','.join(updated_fields)
result = client.UpdateInstance(
instance_ref, instance, update_mask, args.async_
)
if args.async_:
log.status.Print(
'To check the status of the operation, run `gcloud alpha filestore '
'operations describe {}`'.format(result.name)
)
return result
@base.ReleaseTracks(base.ReleaseTrack.BETA)
class UpdateBeta(Update):
"""Update a Filestore instance."""
_API_VERSION = filestore_client.BETA_API_VERSION
detailed_help = {
'DESCRIPTION':
'Update a Filestore instance.',
'EXAMPLES':
textwrap.dedent("""\
The following command updates the Filestore instance NAME to change the
description to "A new description."
$ {command} NAME --description="A new description."
The following command updates a Filestore instance named NAME to add the label
"key1=value1" and remove any metadata with the label "key2".
$ {command} NAME --update-labels=key1=value1 --remove-labels=key2
$ {command} NAME --zone=ZONE --flags-file=FILE_PATH
Example json configuration file:
{
"--file-share":
{
"capacity": "102400",
"name": "my_vol",
"nfs-export-options": [
{
"access-mode": "READ_WRITE",
"ip-ranges": [
"10.0.0.0/29",
"10.2.0.0/29"
],
"squash-mode": "ROOT_SQUASH",
"anon_uid": 1003,
"anon_gid": 1003
}
]
}
}
The following command updates a Filestore instance named NAME to change the
capacity to CAPACITY.
$ {command} NAME --project=PROJECT_ID --zone=ZONE\
--file-share=name=VOLUME_NAME,capacity=CAPACITY
The following command updates a Filestore instance named NAME to configure the
max-iops-per-tb to MAX-IOPS-PER-TB.
$ {command} NAME --project=PROJECT_ID --zone=ZONE\
--performance=max-iops-per-tb=MAX-IOPS-PER-TB
"""),
}
@staticmethod
def Args(parser):
_CommonArgs(parser, UpdateBeta._API_VERSION)
def Run(self, args):
"""Runs a command line string arguments.
Args:
args: cmd line string arguments.
Returns:
client: A FilestoreClient instance.
Raises:
InvalidArgumentException: for invalid JSON formatted --file-args.
KeyError: for key errors in JSON values.
"""
instance_ref = args.CONCEPTS.instance.Parse()
client = filestore_client.FilestoreClient(self._API_VERSION)
labels_diff = labels_util.Diff.FromUpdateArgs(args)
dp_util.ValidateDeletionProtectionUpdateArgs(args)
orig_instance = client.GetInstance(instance_ref)
try:
if args.file_share:
client.MakeNFSExportOptionsMsgBeta(
messages=client.messages,
nfs_export_options=args.file_share.get('nfs-export-options', []),
)
except KeyError as e:
raise exceptions.InvalidArgumentException(
'--file-share', str(e)
)
if labels_diff.MayHaveUpdates():
labels = labels_diff.Apply(
client.messages.Instance.LabelsValue, orig_instance.labels
).GetOrNone()
else:
labels = None
try:
instance = client.ParseUpdatedInstanceConfig(
orig_instance,
description=args.description,
labels=labels,
file_share=args.file_share,
performance=args.performance,
managed_ad=args.managed_ad,
disconnect_managed_ad=args.disconnect_managed_ad,
ldap=args.ldap,
disconnect_ldap=args.disconnect_ldap,
clear_nfs_export_options=args.clear_nfs_export_options,
deletion_protection_enabled=args.deletion_protection,
deletion_protection_reason=args.deletion_protection_reason,
)
except filestore_client.InvalidDisconnectLdapError as e:
raise exceptions.InvalidArgumentException(
'--disconnect-ldap', str(e)
)
except filestore_client.InvalidDisconnectManagedADError as e:
raise exceptions.InvalidArgumentException(
'--disconnect-managed-ad', str(e)
)
except filestore_client.Error as e:
raise exceptions.InvalidArgumentException(
'--file-share', str(e)
)
updated_fields = []
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('file_share'):
updated_fields.append('fileShares')
if args.IsSpecified('performance'):
updated_fields.append('performanceConfig')
if args.IsSpecified('managed_ad') or args.IsSpecified(
'disconnect_managed_ad'
) or args.IsSpecified('ldap') or args.IsSpecified('disconnect_ldap'):
updated_fields.append('directoryServices')
updated_fields += dp_util.GetDeletionProtectionUpdateMask(args)
update_mask = ','.join(updated_fields)
result = client.UpdateInstance(
instance_ref, instance, update_mask, args.async_
)
if args.async_:
log.status.Print(
'To check the status of the operation, run `gcloud beta filestore '
'operations describe {}`'.format(result.name)
)
return result