Support --no-property in "volume set" command
Add "--no-property" option to "volume set" command in v1 and v2 and update the test cases. Change-Id: Id5660f23b3b2d9aa72f4c16b19ce83f3f7ed2fa4
This commit is contained in:
parent
3b562ffa90
commit
40ec7a9c96
@ -269,6 +269,7 @@ Set volume properties
|
|||||||
[--name <name>]
|
[--name <name>]
|
||||||
[--size <size>]
|
[--size <size>]
|
||||||
[--description <description>]
|
[--description <description>]
|
||||||
|
[--no-property]
|
||||||
[--property <key=value> [...] ]
|
[--property <key=value> [...] ]
|
||||||
[--image-property <key=value> [...] ]
|
[--image-property <key=value> [...] ]
|
||||||
[--state <state>]
|
[--state <state>]
|
||||||
@ -290,6 +291,12 @@ Set volume properties
|
|||||||
|
|
||||||
New volume description
|
New volume description
|
||||||
|
|
||||||
|
.. option:: --no-property
|
||||||
|
|
||||||
|
Remove all properties from :ref:`\<volume\> <volume_set-volume>`
|
||||||
|
(specify both :option:`--no-property` and :option:`--property` to
|
||||||
|
remove the current properties before setting new properties.)
|
||||||
|
|
||||||
.. option:: --property <key=value>
|
.. option:: --property <key=value>
|
||||||
|
|
||||||
Set a property on this volume (repeat option to set multiple properties)
|
Set a property on this volume (repeat option to set multiple properties)
|
||||||
@ -304,7 +311,7 @@ Set volume properties
|
|||||||
|
|
||||||
Migration policy while re-typing volume
|
Migration policy while re-typing volume
|
||||||
("never" or "on-demand", default is "never" )
|
("never" or "on-demand", default is "never" )
|
||||||
(available only when "--type" option is specified)
|
(available only when :option:`--type` option is specified)
|
||||||
|
|
||||||
*Volume version 2 only*
|
*Volume version 2 only*
|
||||||
|
|
||||||
|
@ -141,8 +141,9 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
'--name ' + new_name +
|
'--name ' + new_name +
|
||||||
' --size 2 ' +
|
' --size 2 ' +
|
||||||
'--description bbbb ' +
|
'--description bbbb ' +
|
||||||
'--property Alpha=c ' +
|
'--no-property ' +
|
||||||
'--property Beta=b ' +
|
'--property Beta=b ' +
|
||||||
|
'--property Gamma=c ' +
|
||||||
'--bootable ' +
|
'--bootable ' +
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
@ -165,7 +166,7 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
cmd_output["display_description"],
|
cmd_output["display_description"],
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"Alpha='c', Beta='b'",
|
"Beta='b', Gamma='c'",
|
||||||
cmd_output["properties"],
|
cmd_output["properties"],
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -176,7 +177,7 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
# Test volume unset
|
# Test volume unset
|
||||||
raw_output = self.openstack(
|
raw_output = self.openstack(
|
||||||
'volume unset ' +
|
'volume unset ' +
|
||||||
'--property Alpha ' +
|
'--property Beta ' +
|
||||||
new_name,
|
new_name,
|
||||||
)
|
)
|
||||||
self.assertOutput('', raw_output)
|
self.assertOutput('', raw_output)
|
||||||
@ -186,7 +187,7 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
new_name
|
new_name
|
||||||
))
|
))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"Beta='b'",
|
"Gamma='c'",
|
||||||
cmd_output["properties"],
|
cmd_output["properties"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
# TODO(qiangjiahui): Add project option to filter tests when we can
|
# TODO(qiangjiahui): Add project option to filter tests when we can
|
||||||
# specify volume with project
|
# specify volume with project
|
||||||
|
|
||||||
def test_volume_set(self):
|
def test_volume_set_and_unset(self):
|
||||||
"""Tests create volume, set, unset, show, delete"""
|
"""Tests create volume, set, unset, show, delete"""
|
||||||
name = uuid.uuid4().hex
|
name = uuid.uuid4().hex
|
||||||
new_name = name + "_"
|
new_name = name + "_"
|
||||||
@ -144,8 +144,11 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
'--name ' + new_name +
|
'--name ' + new_name +
|
||||||
' --size 2 ' +
|
' --size 2 ' +
|
||||||
'--description bbbb ' +
|
'--description bbbb ' +
|
||||||
'--property Alpha=c ' +
|
'--no-property ' +
|
||||||
'--property Beta=b ' +
|
'--property Beta=b ' +
|
||||||
|
'--property Gamma=c ' +
|
||||||
|
'--image-property a=b ' +
|
||||||
|
'--image-property c=d ' +
|
||||||
'--bootable ' +
|
'--bootable ' +
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
@ -168,9 +171,13 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
cmd_output["description"],
|
cmd_output["description"],
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"Alpha='c', Beta='b'",
|
"Beta='b', Gamma='c'",
|
||||||
cmd_output["properties"],
|
cmd_output["properties"],
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
{'a': 'b', 'c': 'd'},
|
||||||
|
cmd_output["volume_image_metadata"],
|
||||||
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'true',
|
'true',
|
||||||
cmd_output["bootable"],
|
cmd_output["bootable"],
|
||||||
@ -179,7 +186,8 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
# Test volume unset
|
# Test volume unset
|
||||||
raw_output = self.openstack(
|
raw_output = self.openstack(
|
||||||
'volume unset ' +
|
'volume unset ' +
|
||||||
'--property Alpha ' +
|
'--property Beta ' +
|
||||||
|
'--image-property a ' +
|
||||||
new_name,
|
new_name,
|
||||||
)
|
)
|
||||||
self.assertOutput('', raw_output)
|
self.assertOutput('', raw_output)
|
||||||
@ -189,9 +197,13 @@ class VolumeTests(common.BaseVolumeTests):
|
|||||||
new_name
|
new_name
|
||||||
))
|
))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"Beta='b'",
|
"Gamma='c'",
|
||||||
cmd_output["properties"],
|
cmd_output["properties"],
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
{'c': 'd'},
|
||||||
|
cmd_output["volume_image_metadata"],
|
||||||
|
)
|
||||||
|
|
||||||
def test_volume_snapshot(self):
|
def test_volume_snapshot(self):
|
||||||
"""Tests volume create from snapshot"""
|
"""Tests volume create from snapshot"""
|
||||||
|
@ -1071,6 +1071,7 @@ class TestVolumeSet(TestVolume):
|
|||||||
|
|
||||||
def test_volume_set_property(self):
|
def test_volume_set_property(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
|
'--no-property',
|
||||||
'--property', 'myprop=myvalue',
|
'--property', 'myprop=myvalue',
|
||||||
self._volume.display_name,
|
self._volume.display_name,
|
||||||
]
|
]
|
||||||
@ -1080,6 +1081,7 @@ class TestVolumeSet(TestVolume):
|
|||||||
('name', None),
|
('name', None),
|
||||||
('description', None),
|
('description', None),
|
||||||
('size', None),
|
('size', None),
|
||||||
|
('no_property', True),
|
||||||
('property', {'myprop': 'myvalue'}),
|
('property', {'myprop': 'myvalue'}),
|
||||||
('volume', self._volume.display_name),
|
('volume', self._volume.display_name),
|
||||||
('bootable', False),
|
('bootable', False),
|
||||||
@ -1097,6 +1099,10 @@ class TestVolumeSet(TestVolume):
|
|||||||
self._volume.id,
|
self._volume.id,
|
||||||
metadata
|
metadata
|
||||||
)
|
)
|
||||||
|
self.volumes_mock.delete_metadata.assert_called_with(
|
||||||
|
self._volume.id,
|
||||||
|
self._volume.metadata.keys()
|
||||||
|
)
|
||||||
self.volumes_mock.update_readonly_flag.assert_not_called()
|
self.volumes_mock.update_readonly_flag.assert_not_called()
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
@ -1368,6 +1368,24 @@ class TestVolumeSet(TestVolume):
|
|||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = volume.SetVolume(self.app, None)
|
self.cmd = volume.SetVolume(self.app, None)
|
||||||
|
|
||||||
|
def test_volume_set_property(self):
|
||||||
|
arglist = [
|
||||||
|
'--property', 'a=b',
|
||||||
|
'--property', 'c=d',
|
||||||
|
self.new_volume.id,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('property', {'a': 'b', 'c': 'd'}),
|
||||||
|
('volume', self.new_volume.id),
|
||||||
|
('bootable', False),
|
||||||
|
('non_bootable', False)
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.volumes_mock.set_metadata.assert_called_with(
|
||||||
|
self.new_volume.id, parsed_args.property)
|
||||||
|
|
||||||
def test_volume_set_image_property(self):
|
def test_volume_set_image_property(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
'--image-property', 'Alpha=a',
|
'--image-property', 'Alpha=a',
|
||||||
|
@ -439,6 +439,15 @@ class SetVolume(command.Command):
|
|||||||
type=int,
|
type=int,
|
||||||
help=_('Extend volume size in GB'),
|
help=_('Extend volume size in GB'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-property",
|
||||||
|
dest="no_property",
|
||||||
|
action="store_true",
|
||||||
|
help=_("Remove all properties from <volume> "
|
||||||
|
"(specify both --no-property and --property to "
|
||||||
|
"remove the current properties before setting "
|
||||||
|
"new properties.)"),
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--property',
|
'--property',
|
||||||
metavar='<key=value>',
|
metavar='<key=value>',
|
||||||
@ -489,6 +498,15 @@ class SetVolume(command.Command):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error(_("Failed to set volume size: %s"), e)
|
LOG.error(_("Failed to set volume size: %s"), e)
|
||||||
result += 1
|
result += 1
|
||||||
|
|
||||||
|
if parsed_args.no_property:
|
||||||
|
try:
|
||||||
|
volume_client.volumes.delete_metadata(
|
||||||
|
volume.id, volume.metadata.keys())
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error(_("Failed to clean volume properties: %s"), e)
|
||||||
|
result += 1
|
||||||
|
|
||||||
if parsed_args.property:
|
if parsed_args.property:
|
||||||
try:
|
try:
|
||||||
volume_client.volumes.set_metadata(
|
volume_client.volumes.set_metadata(
|
||||||
|
@ -523,6 +523,15 @@ class SetVolume(command.Command):
|
|||||||
metavar='<description>',
|
metavar='<description>',
|
||||||
help=_('New volume description'),
|
help=_('New volume description'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--no-property",
|
||||||
|
dest="no_property",
|
||||||
|
action="store_true",
|
||||||
|
help=_("Remove all properties from <volume> "
|
||||||
|
"(specify both --no-property and --property to "
|
||||||
|
"remove the current properties before setting "
|
||||||
|
"new properties.)"),
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--property',
|
'--property',
|
||||||
metavar='<key=value>',
|
metavar='<key=value>',
|
||||||
@ -561,7 +570,7 @@ class SetVolume(command.Command):
|
|||||||
choices=['never', 'on-demand'],
|
choices=['never', 'on-demand'],
|
||||||
help=_('Migration policy while re-typing volume '
|
help=_('Migration policy while re-typing volume '
|
||||||
'("never" or "on-demand", default is "never" ) '
|
'("never" or "on-demand", default is "never" ) '
|
||||||
'(available only when "--type" option is specified)'),
|
'(available only when --type option is specified)'),
|
||||||
)
|
)
|
||||||
bootable_group = parser.add_mutually_exclusive_group()
|
bootable_group = parser.add_mutually_exclusive_group()
|
||||||
bootable_group.add_argument(
|
bootable_group.add_argument(
|
||||||
@ -607,6 +616,14 @@ class SetVolume(command.Command):
|
|||||||
LOG.error(_("Failed to set volume size: %s"), e)
|
LOG.error(_("Failed to set volume size: %s"), e)
|
||||||
result += 1
|
result += 1
|
||||||
|
|
||||||
|
if parsed_args.no_property:
|
||||||
|
try:
|
||||||
|
volume_client.volumes.delete_metadata(
|
||||||
|
volume.id, volume.metadata.keys())
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error(_("Failed to clean volume properties: %s"), e)
|
||||||
|
result += 1
|
||||||
|
|
||||||
if parsed_args.property:
|
if parsed_args.property:
|
||||||
try:
|
try:
|
||||||
volume_client.volumes.set_metadata(
|
volume_client.volumes.set_metadata(
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add ``--no-property`` option in ``volume set``, this removes all properties from a volume.
|
||||||
|
[Blueprint `allow-overwrite-set-options <https://blueprints.launchpad.net/python-openstackclient/+spec/allow-overwrite-set-options>`_]
|
Loading…
Reference in New Issue
Block a user