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:
zhiyong.dai 2016-12-01 02:20:23 +08:00
parent 3b562ffa90
commit 40ec7a9c96
8 changed files with 95 additions and 11 deletions

View File

@ -269,6 +269,7 @@ Set volume properties
[--name <name>]
[--size <size>]
[--description <description>]
[--no-property]
[--property <key=value> [...] ]
[--image-property <key=value> [...] ]
[--state <state>]
@ -290,6 +291,12 @@ Set volume properties
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>
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
("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*

View File

@ -141,8 +141,9 @@ class VolumeTests(common.BaseVolumeTests):
'--name ' + new_name +
' --size 2 ' +
'--description bbbb ' +
'--property Alpha=c ' +
'--no-property ' +
'--property Beta=b ' +
'--property Gamma=c ' +
'--bootable ' +
name,
)
@ -165,7 +166,7 @@ class VolumeTests(common.BaseVolumeTests):
cmd_output["display_description"],
)
self.assertEqual(
"Alpha='c', Beta='b'",
"Beta='b', Gamma='c'",
cmd_output["properties"],
)
self.assertEqual(
@ -176,7 +177,7 @@ class VolumeTests(common.BaseVolumeTests):
# Test volume unset
raw_output = self.openstack(
'volume unset ' +
'--property Alpha ' +
'--property Beta ' +
new_name,
)
self.assertOutput('', raw_output)
@ -186,7 +187,7 @@ class VolumeTests(common.BaseVolumeTests):
new_name
))
self.assertEqual(
"Beta='b'",
"Gamma='c'",
cmd_output["properties"],
)

View File

@ -104,7 +104,7 @@ class VolumeTests(common.BaseVolumeTests):
# TODO(qiangjiahui): Add project option to filter tests when we can
# specify volume with project
def test_volume_set(self):
def test_volume_set_and_unset(self):
"""Tests create volume, set, unset, show, delete"""
name = uuid.uuid4().hex
new_name = name + "_"
@ -144,8 +144,11 @@ class VolumeTests(common.BaseVolumeTests):
'--name ' + new_name +
' --size 2 ' +
'--description bbbb ' +
'--property Alpha=c ' +
'--no-property ' +
'--property Beta=b ' +
'--property Gamma=c ' +
'--image-property a=b ' +
'--image-property c=d ' +
'--bootable ' +
name,
)
@ -168,9 +171,13 @@ class VolumeTests(common.BaseVolumeTests):
cmd_output["description"],
)
self.assertEqual(
"Alpha='c', Beta='b'",
"Beta='b', Gamma='c'",
cmd_output["properties"],
)
self.assertEqual(
{'a': 'b', 'c': 'd'},
cmd_output["volume_image_metadata"],
)
self.assertEqual(
'true',
cmd_output["bootable"],
@ -179,7 +186,8 @@ class VolumeTests(common.BaseVolumeTests):
# Test volume unset
raw_output = self.openstack(
'volume unset ' +
'--property Alpha ' +
'--property Beta ' +
'--image-property a ' +
new_name,
)
self.assertOutput('', raw_output)
@ -189,9 +197,13 @@ class VolumeTests(common.BaseVolumeTests):
new_name
))
self.assertEqual(
"Beta='b'",
"Gamma='c'",
cmd_output["properties"],
)
self.assertEqual(
{'c': 'd'},
cmd_output["volume_image_metadata"],
)
def test_volume_snapshot(self):
"""Tests volume create from snapshot"""

View File

@ -1071,6 +1071,7 @@ class TestVolumeSet(TestVolume):
def test_volume_set_property(self):
arglist = [
'--no-property',
'--property', 'myprop=myvalue',
self._volume.display_name,
]
@ -1080,6 +1081,7 @@ class TestVolumeSet(TestVolume):
('name', None),
('description', None),
('size', None),
('no_property', True),
('property', {'myprop': 'myvalue'}),
('volume', self._volume.display_name),
('bootable', False),
@ -1097,6 +1099,10 @@ class TestVolumeSet(TestVolume):
self._volume.id,
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.assertIsNone(result)

View File

@ -1368,6 +1368,24 @@ class TestVolumeSet(TestVolume):
# Get the command object to test
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):
arglist = [
'--image-property', 'Alpha=a',

View File

@ -439,6 +439,15 @@ class SetVolume(command.Command):
type=int,
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(
'--property',
metavar='<key=value>',
@ -489,6 +498,15 @@ class SetVolume(command.Command):
except Exception as e:
LOG.error(_("Failed to set volume size: %s"), e)
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:
try:
volume_client.volumes.set_metadata(

View File

@ -523,6 +523,15 @@ class SetVolume(command.Command):
metavar='<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(
'--property',
metavar='<key=value>',
@ -561,7 +570,7 @@ class SetVolume(command.Command):
choices=['never', 'on-demand'],
help=_('Migration policy while re-typing volume '
'("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.add_argument(
@ -607,6 +616,14 @@ class SetVolume(command.Command):
LOG.error(_("Failed to set volume size: %s"), e)
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:
try:
volume_client.volumes.set_metadata(

View File

@ -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>`_]