From 429ceef0c6c9deff521905c149e7600ffa5334ba Mon Sep 17 00:00:00 2001 From: heha Date: Fri, 24 Jul 2015 10:03:06 +0800 Subject: [PATCH] Add set feature to volume type v2 "volume type set" and "volume type unset" is not in the v2. Co-Authored-By: Lin Hua Cheng implements bp: volume-v2 Change-Id: Ia804787d76d2029726c030b43c61eac3b411f66a --- doc/source/command-objects/volume-type.rst | 18 ++- openstackclient/tests/volume/v2/test_type.py | 130 +++++++++++++++++++ openstackclient/volume/v2/volume_type.py | 94 ++++++++++++++ setup.cfg | 2 + 4 files changed, 240 insertions(+), 4 deletions(-) diff --git a/doc/source/command-objects/volume-type.rst b/doc/source/command-objects/volume-type.rst index 4d5651ac90..0edd742aee 100644 --- a/doc/source/command-objects/volume-type.rst +++ b/doc/source/command-objects/volume-type.rst @@ -77,17 +77,29 @@ List volume types volume type set --------------- -*Only supported for Volume API v1* - Set volume type properties .. program:: volume type set .. code:: bash os volume type set + [--name ] + [--description ] [--property [...] ] +.. option:: --name + + Set volume type name + + .. versionadded:: 2 + +.. option:: --description + + Set volume type description + + .. versionadded:: 2 + .. option:: --property Property to add or modify for this volume type (repeat option to set multiple properties) @@ -99,8 +111,6 @@ Set volume type properties volume type unset ----------------- -*Only supported for Volume API v1* - Unset volume type properties .. program:: volume type unset diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py index c5b27fa512..9a07263b5f 100644 --- a/openstackclient/tests/volume/v2/test_type.py +++ b/openstackclient/tests/volume/v2/test_type.py @@ -19,6 +19,20 @@ from openstackclient.tests.volume.v2 import fakes as volume_fakes from openstackclient.volume.v2 import volume_type +class FakeTypeResource(fakes.FakeResource): + + _keys = {'property': 'value'} + + def set_keys(self, args): + self._keys.update(args) + + def unset_keys(self, key): + self._keys.pop(key, None) + + def get_keys(self): + return self._keys + + class TestType(volume_fakes.TestVolume): def setUp(self): @@ -184,6 +198,122 @@ class TestTypeShow(TestType): self.assertEqual(volume_fakes.TYPE_FORMATTED_data, data) +class TestTypeSet(TestType): + + def setUp(self): + super(TestTypeSet, self).setUp() + + self.types_mock.get.return_value = FakeTypeResource( + None, + copy.deepcopy(volume_fakes.TYPE), + loaded=True, + ) + + # Get the command object to test + self.cmd = volume_type.SetVolumeType(self.app, None) + + def test_type_set_name(self): + new_name = 'new_name' + arglist = [ + '--name', new_name, + volume_fakes.type_id, + ] + verifylist = [ + ('name', new_name), + ('description', None), + ('property', None), + ('volume_type', volume_fakes.type_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'name': new_name, + } + self.types_mock.update.assert_called_with( + volume_fakes.type_id, + **kwargs + ) + + def test_type_set_description(self): + new_desc = 'new_desc' + arglist = [ + '--description', new_desc, + volume_fakes.type_id, + ] + verifylist = [ + ('name', None), + ('description', new_desc), + ('property', None), + ('volume_type', volume_fakes.type_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'description': new_desc, + } + self.types_mock.update.assert_called_with( + volume_fakes.type_id, + **kwargs + ) + + def test_type_set_property(self): + arglist = [ + '--property', 'myprop=myvalue', + volume_fakes.type_id, + ] + verifylist = [ + ('name', None), + ('description', None), + ('property', {'myprop': 'myvalue'}), + ('volume_type', volume_fakes.type_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + result = self.types_mock.get.return_value._keys + self.assertIn('myprop', result) + self.assertEqual('myvalue', result['myprop']) + + +class TestTypeUnset(TestType): + + def setUp(self): + super(TestTypeUnset, self).setUp() + + self.types_mock.get.return_value = FakeTypeResource( + None, + copy.deepcopy(volume_fakes.TYPE), + loaded=True, + ) + + self.cmd = volume_type.UnsetVolumeType(self.app, None) + + def test_type_unset(self): + arglist = [ + '--property', 'property', + volume_fakes.type_id, + ] + verifylist = [ + ('property', 'property'), + ('volume_type', volume_fakes.type_id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + result = self.types_mock.get.return_value._keys + + self.assertNotIn('property', result) + + class TestTypeDelete(TestType): def setUp(self): super(TestTypeDelete, self).setUp() diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py index 7f9a1c4b6c..fb0342c555 100644 --- a/openstackclient/volume/v2/volume_type.py +++ b/openstackclient/volume/v2/volume_type.py @@ -143,6 +143,67 @@ class ListVolumeType(lister.Lister): ) for s in data)) +class SetVolumeType(command.Command): + """Set volume type properties""" + + log = logging.getLogger(__name__ + '.SetVolumeType') + + def get_parser(self, prog_name): + parser = super(SetVolumeType, self).get_parser(prog_name) + parser.add_argument( + 'volume_type', + metavar='', + help='Volume type to modify (name or ID)', + ) + parser.add_argument( + '--name', + metavar='', + help='Set volume type name', + ) + parser.add_argument( + '--description', + metavar='', + help='Set volume type description', + ) + parser.add_argument( + '--property', + metavar='', + action=parseractions.KeyValueAction, + help='Property to add or modify for this volume type ' + '(repeat option to set multiple properties)', + ) + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)', parsed_args) + volume_client = self.app.client_manager.volume + volume_type = utils.find_resource( + volume_client.volume_types, parsed_args.volume_type) + + if (not parsed_args.name + and not parsed_args.description + and not parsed_args.property): + self.app.log.error("No changes requested\n") + return + + kwargs = {} + if parsed_args.name: + kwargs['name'] = parsed_args.name + if parsed_args.description: + kwargs['description'] = parsed_args.description + + if kwargs: + volume_client.volume_types.update( + volume_type.id, + **kwargs + ) + + if parsed_args.property: + volume_type.set_keys(parsed_args.property) + + return + + class ShowVolumeType(show.ShowOne): """Display volume type details""" @@ -165,3 +226,36 @@ class ShowVolumeType(show.ShowOne): properties = utils.format_dict(volume_type._info.pop('extra_specs')) volume_type._info.update({'properties': properties}) return zip(*sorted(six.iteritems(volume_type._info))) + + +class UnsetVolumeType(command.Command): + """Unset volume type properties""" + + log = logging.getLogger(__name__ + '.UnsetVolumeType') + + def get_parser(self, prog_name): + parser = super(UnsetVolumeType, self).get_parser(prog_name) + parser.add_argument( + 'volume_type', + metavar='', + help='Volume type to modify (name or ID)', + ) + parser.add_argument( + '--property', + metavar='', + default=[], + required=True, + help='Property to remove from volume type ' + '(repeat option to remove multiple properties)', + ) + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)', parsed_args) + volume_client = self.app.client_manager.volume + volume_type = utils.find_resource( + volume_client.volume_types, + parsed_args.volume_type, + ) + volume_type.unset_keys(parsed_args.property) + return diff --git a/setup.cfg b/setup.cfg index c954073242..fd62407c0b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -398,7 +398,9 @@ openstack.volume.v2 = volume_type_create = openstackclient.volume.v2.volume_type:CreateVolumeType volume_type_delete = openstackclient.volume.v2.volume_type:DeleteVolumeType volume_type_list = openstackclient.volume.v2.volume_type:ListVolumeType + volume_type_set = openstackclient.volume.v2.volume_type:SetVolumeType volume_type_show = openstackclient.volume.v2.volume_type:ShowVolumeType + volume_type_unset = openstackclient.volume.v2.volume_type:UnsetVolumeType volume_qos_associate = openstackclient.volume.v2.qos_specs:AssociateQos volume_qos_create = openstackclient.volume.v2.qos_specs:CreateQos