From 629eb33c4dcb73d44d1a4c6105e40d28f6cebdfc Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 17 May 2023 12:27:45 +0100 Subject: [PATCH] volume: Add 'volume qos set --no-property' option Supporting "--no-property" option will apply user a convenient way to clean all properties of volume qos in a short command. The patch adds "--no-property" option in "volume qos set" command and update related test cases and docs. Change-Id: I1fb5b4f0a923bbf557a3af3f63809bde9e84ffd4 --- doc/source/cli/command-objects/volume-qos.rst | 7 ++++ .../tests/functional/volume/v1/test_qos.py | 16 ++++++--- .../tests/functional/volume/v2/test_qos.py | 16 ++++++--- .../tests/functional/volume/v3/test_qos.py | 16 ++++++--- .../tests/unit/volume/v1/test_qos_specs.py | 16 ++++++--- .../tests/unit/volume/v2/test_qos_specs.py | 15 ++++++--- openstackclient/volume/v1/qos_specs.py | 33 ++++++++++++++++++- openstackclient/volume/v2/qos_specs.py | 33 ++++++++++++++++++- ...t-no-property-option-348480dfc42a0a64.yaml | 4 +++ 9 files changed, 131 insertions(+), 25 deletions(-) create mode 100644 releasenotes/notes/add-volume-qos-set-no-property-option-348480dfc42a0a64.yaml diff --git a/doc/source/cli/command-objects/volume-qos.rst b/doc/source/cli/command-objects/volume-qos.rst index 8fdbc1228..52c1f2d48 100644 --- a/doc/source/cli/command-objects/volume-qos.rst +++ b/doc/source/cli/command-objects/volume-qos.rst @@ -116,9 +116,16 @@ Set QoS specification properties .. code:: bash openstack volume qos set + [--no-property] [--property [...] ] +.. option:: --no-property + + Remove all properties from :ref:`\ ` + (specify both :option:`--no-property` and :option:`--property` to + remove the current properties before setting new properties.) + .. option:: --property Property to add or modify for this QoS specification (repeat option to set multiple properties) diff --git a/openstackclient/tests/functional/volume/v1/test_qos.py b/openstackclient/tests/functional/volume/v1/test_qos.py index cabcd19e8..5d0aa41f6 100644 --- a/openstackclient/tests/functional/volume/v1/test_qos.py +++ b/openstackclient/tests/functional/volume/v1/test_qos.py @@ -52,8 +52,10 @@ class QosTests(common.BaseVolumeTests): name = uuid.uuid4().hex cmd_output = self.openstack( - 'volume qos create ' + '--consumer front-end ' - '--property Alpha=a ' + name, + 'volume qos create ' + + '--consumer front-end ' + + '--property Alpha=a ' + + name, parse_output=True, ) self.addCleanup(self.openstack, 'volume qos delete ' + name) @@ -64,8 +66,9 @@ class QosTests(common.BaseVolumeTests): # Test volume qos set raw_output = self.openstack( 'volume qos set ' - + '--property Alpha=c ' + + '--no-property ' + '--property Beta=b ' + + '--property Charlie=c ' + name, ) self.assertOutput('', raw_output) @@ -76,11 +79,14 @@ class QosTests(common.BaseVolumeTests): parse_output=True, ) self.assertEqual(name, cmd_output['name']) - self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties']) + self.assertEqual( + {'Beta': 'b', 'Charlie': 'c'}, + cmd_output['properties'], + ) # Test volume qos unset raw_output = self.openstack( - 'volume qos unset ' + '--property Alpha ' + name, + 'volume qos unset ' + '--property Charlie ' + name, ) self.assertOutput('', raw_output) diff --git a/openstackclient/tests/functional/volume/v2/test_qos.py b/openstackclient/tests/functional/volume/v2/test_qos.py index 4f07084ad..fc4c52de2 100644 --- a/openstackclient/tests/functional/volume/v2/test_qos.py +++ b/openstackclient/tests/functional/volume/v2/test_qos.py @@ -52,8 +52,10 @@ class QosTests(common.BaseVolumeTests): name = uuid.uuid4().hex cmd_output = self.openstack( - 'volume qos create ' + '--consumer front-end ' - '--property Alpha=a ' + name, + 'volume qos create ' + + '--consumer front-end ' + + '--property Alpha=a ' + + name, parse_output=True, ) self.addCleanup(self.openstack, 'volume qos delete ' + name) @@ -65,8 +67,9 @@ class QosTests(common.BaseVolumeTests): # Test volume qos set raw_output = self.openstack( 'volume qos set ' - + '--property Alpha=c ' + + '--no-property ' + '--property Beta=b ' + + '--property Charlie=c ' + name, ) self.assertOutput('', raw_output) @@ -77,11 +80,14 @@ class QosTests(common.BaseVolumeTests): parse_output=True, ) self.assertEqual(name, cmd_output['name']) - self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties']) + self.assertEqual( + {'Beta': 'b', 'Charlie': 'c'}, + cmd_output['properties'], + ) # Test volume qos unset raw_output = self.openstack( - 'volume qos unset ' + '--property Alpha ' + name, + 'volume qos unset ' + '--property Charlie ' + name, ) self.assertOutput('', raw_output) diff --git a/openstackclient/tests/functional/volume/v3/test_qos.py b/openstackclient/tests/functional/volume/v3/test_qos.py index 2a09e549b..54dffbc0e 100644 --- a/openstackclient/tests/functional/volume/v3/test_qos.py +++ b/openstackclient/tests/functional/volume/v3/test_qos.py @@ -52,8 +52,10 @@ class QosTests(common.BaseVolumeTests): name = uuid.uuid4().hex cmd_output = self.openstack( - 'volume qos create ' + '--consumer front-end ' - '--property Alpha=a ' + name, + 'volume qos create ' + + '--consumer front-end ' + + '--property Alpha=a ' + + name, parse_output=True, ) self.addCleanup(self.openstack, 'volume qos delete ' + name) @@ -65,8 +67,9 @@ class QosTests(common.BaseVolumeTests): # Test volume qos set raw_output = self.openstack( 'volume qos set ' - + '--property Alpha=c ' + + '--no-property ' + '--property Beta=b ' + + '--property Charlie=c ' + name, ) self.assertOutput('', raw_output) @@ -77,11 +80,14 @@ class QosTests(common.BaseVolumeTests): parse_output=True, ) self.assertEqual(name, cmd_output['name']) - self.assertEqual({'Alpha': 'c', 'Beta': 'b'}, cmd_output['properties']) + self.assertEqual( + {'Beta': 'b', 'Charlie': 'c'}, + cmd_output['properties'], + ) # Test volume qos unset raw_output = self.openstack( - 'volume qos unset ' + '--property Alpha ' + name, + 'volume qos unset ' + '--property Charlie ' + name, ) self.assertOutput('', raw_output) diff --git a/openstackclient/tests/unit/volume/v1/test_qos_specs.py b/openstackclient/tests/unit/volume/v1/test_qos_specs.py index 7e26e2237..cbfd1fa4c 100644 --- a/openstackclient/tests/unit/volume/v1/test_qos_specs.py +++ b/openstackclient/tests/unit/volume/v1/test_qos_specs.py @@ -366,22 +366,30 @@ class TestQosSet(TestQos): def test_qos_set_with_properties_with_id(self): arglist = [ + '--no-property', '--property', - 'foo=bar', + 'a=b', '--property', - 'iops=9001', + 'c=d', self.qos_spec.id, ] + new_property = {"a": "b", "c": "d"} verifylist = [ - ('property', self.qos_spec.specs), + ('no_property', True), + ('property', new_property), ('qos_spec', self.qos_spec.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) + self.qos_mock.unset_keys.assert_called_with( + self.qos_spec.id, + list(self.qos_spec.specs.keys()), + ) self.qos_mock.set_keys.assert_called_with( - self.qos_spec.id, self.qos_spec.specs + self.qos_spec.id, + {"a": "b", "c": "d"}, ) self.assertIsNone(result) diff --git a/openstackclient/tests/unit/volume/v2/test_qos_specs.py b/openstackclient/tests/unit/volume/v2/test_qos_specs.py index 994bcf964..54a13efcd 100644 --- a/openstackclient/tests/unit/volume/v2/test_qos_specs.py +++ b/openstackclient/tests/unit/volume/v2/test_qos_specs.py @@ -362,22 +362,29 @@ class TestQosSet(TestQos): def test_qos_set_with_properties_with_id(self): arglist = [ + '--no-property', '--property', - 'foo=bar', + 'a=b', '--property', - 'iops=9001', + 'c=d', self.qos_spec.id, ] + new_property = {"a": "b", "c": "d"} verifylist = [ - ('property', self.qos_spec.specs), + ('no_property', True), + ('property', new_property), ('qos_spec', self.qos_spec.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) + self.qos_mock.unset_keys.assert_called_with( + self.qos_spec.id, + list(self.qos_spec.specs.keys()), + ) self.qos_mock.set_keys.assert_called_with( - self.qos_spec.id, self.qos_spec.specs + self.qos_spec.id, {"a": "b", "c": "d"} ) self.assertIsNone(result) diff --git a/openstackclient/volume/v1/qos_specs.py b/openstackclient/volume/v1/qos_specs.py index 87e32ff45..830d5d827 100644 --- a/openstackclient/volume/v1/qos_specs.py +++ b/openstackclient/volume/v1/qos_specs.py @@ -255,6 +255,16 @@ class SetQos(command.Command): metavar='', help=_('QoS specification to modify (name or ID)'), ) + parser.add_argument( + '--no-property', + dest='no_property', + action='store_true', + help=_( + 'Remove all properties from ' + '(specify both --no-property and --property to remove the ' + 'current properties before setting new properties)' + ), + ) parser.add_argument( '--property', metavar='', @@ -272,8 +282,29 @@ class SetQos(command.Command): volume_client.qos_specs, parsed_args.qos_spec ) + result = 0 + if parsed_args.no_property: + try: + key_list = list(qos_spec._info['specs'].keys()) + volume_client.qos_specs.unset_keys(qos_spec.id, key_list) + except Exception as e: + LOG.error(_("Failed to clean qos properties: %s"), e) + result += 1 + if parsed_args.property: - volume_client.qos_specs.set_keys(qos_spec.id, parsed_args.property) + try: + volume_client.qos_specs.set_keys( + qos_spec.id, + parsed_args.property, + ) + except Exception as e: + LOG.error(_("Failed to set qos property: %s"), e) + result += 1 + + if result > 0: + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class ShowQos(command.ShowOne): diff --git a/openstackclient/volume/v2/qos_specs.py b/openstackclient/volume/v2/qos_specs.py index 2c06ee341..0454ecae8 100644 --- a/openstackclient/volume/v2/qos_specs.py +++ b/openstackclient/volume/v2/qos_specs.py @@ -257,6 +257,16 @@ class SetQos(command.Command): metavar='', help=_('QoS specification to modify (name or ID)'), ) + parser.add_argument( + '--no-property', + dest='no_property', + action='store_true', + help=_( + 'Remove all properties from ' + '(specify both --no-property and --property to remove the ' + 'current properties before setting new properties)' + ), + ) parser.add_argument( '--property', metavar='', @@ -274,8 +284,29 @@ class SetQos(command.Command): volume_client.qos_specs, parsed_args.qos_spec ) + result = 0 + if parsed_args.no_property: + try: + key_list = list(qos_spec._info['specs'].keys()) + volume_client.qos_specs.unset_keys(qos_spec.id, key_list) + except Exception as e: + LOG.error(_("Failed to clean qos properties: %s"), e) + result += 1 + if parsed_args.property: - volume_client.qos_specs.set_keys(qos_spec.id, parsed_args.property) + try: + volume_client.qos_specs.set_keys( + qos_spec.id, + parsed_args.property, + ) + except Exception as e: + LOG.error(_("Failed to set qos property: %s"), e) + result += 1 + + if result > 0: + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class ShowQos(command.ShowOne): diff --git a/releasenotes/notes/add-volume-qos-set-no-property-option-348480dfc42a0a64.yaml b/releasenotes/notes/add-volume-qos-set-no-property-option-348480dfc42a0a64.yaml new file mode 100644 index 000000000..51b214506 --- /dev/null +++ b/releasenotes/notes/add-volume-qos-set-no-property-option-348480dfc42a0a64.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Add ``--no-property`` option in ``volume qos set``.