From 9cccebbc82fcb42195e1fd1822f01422f1fd565e Mon Sep 17 00:00:00 2001 From: Vipin Balachandran Date: Wed, 25 Nov 2015 17:36:21 +0530 Subject: [PATCH] VMware: Validate extra spec opt vmware:clone_type This patch validates the value of extra spec option 'vmware:clone_type'. It raises an exception if the value is invalid. Change-Id: Idab59a090184e1ea1446e9e9ed18c753d5c803cc Closes-Bug: #1288254 --- cinder/tests/unit/test_vmware_vmdk.py | 25 +++++++++++++++++++++++++ cinder/volume/drivers/vmware/vmdk.py | 21 ++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/cinder/tests/unit/test_vmware_vmdk.py b/cinder/tests/unit/test_vmware_vmdk.py index a9cbd29dc..23fc94a54 100644 --- a/cinder/tests/unit/test_vmware_vmdk.py +++ b/cinder/tests/unit/test_vmware_vmdk.py @@ -1682,6 +1682,31 @@ class VMwareVcVmdkDriverTestCase(test.TestCase): vops.create_vm_inventory_folder.assert_called_once_with( datacenter, ['OpenStack', project_folder_name, self.VOLUME_FOLDER]) + @mock.patch('cinder.volume.drivers.vmware.vmdk.' + '_get_volume_type_extra_spec') + @ddt.data('full', 'linked') + def test_get_clone_type(self, clone_type, get_volume_type_extra_spec): + get_volume_type_extra_spec.return_value = clone_type + + volume = self._create_volume_dict() + self.assertEqual(clone_type, self._driver._get_clone_type(volume)) + get_volume_type_extra_spec.assert_called_once_with( + volume['volume_type_id'], 'clone_type', + default_value=volumeops.FULL_CLONE_TYPE) + + @mock.patch('cinder.volume.drivers.vmware.vmdk.' + '_get_volume_type_extra_spec') + def test_get_clone_type_invalid( + self, get_volume_type_extra_spec): + get_volume_type_extra_spec.return_value = 'foo' + + volume = self._create_volume_dict() + self.assertRaises( + cinder_exceptions.Invalid, self._driver._get_clone_type, volume) + get_volume_type_extra_spec.assert_called_once_with( + volume['volume_type_id'], 'clone_type', + default_value=volumeops.FULL_CLONE_TYPE) + @mock.patch.object(VMDK_DRIVER, '_extend_backing') @mock.patch.object(VMDK_DRIVER, 'volumeops') def test_clone_backing_linked(self, volume_ops, extend_backing): diff --git a/cinder/volume/drivers/vmware/vmdk.py b/cinder/volume/drivers/vmware/vmdk.py index 7c65e805b..d01b87ebc 100644 --- a/cinder/volume/drivers/vmware/vmdk.py +++ b/cinder/volume/drivers/vmware/vmdk.py @@ -1813,11 +1813,22 @@ class VMwareVcVmdkDriver(driver.VolumeDriver): :return: Clone type from the extra spec if present, else return default 'full' clone type """ - return _get_volume_type_extra_spec(volume['volume_type_id'], - 'clone_type', - (volumeops.FULL_CLONE_TYPE, - volumeops.LINKED_CLONE_TYPE), - volumeops.FULL_CLONE_TYPE) + clone_type = _get_volume_type_extra_spec( + volume['volume_type_id'], + 'clone_type', + default_value=volumeops.FULL_CLONE_TYPE) + + if (clone_type != volumeops.FULL_CLONE_TYPE + and clone_type != volumeops.LINKED_CLONE_TYPE): + msg = (_("Clone type '%(clone_type)s' is invalid; valid values" + " are: '%(full_clone)s' and '%(linked_clone)s'.") % + {'clone_type': clone_type, + 'full_clone': volumeops.FULL_CLONE_TYPE, + 'linked_clone': volumeops.LINKED_CLONE_TYPE}) + LOG.error(msg) + raise exception.Invalid(message=msg) + + return clone_type def _clone_backing(self, volume, backing, snapshot, clone_type, src_vsize): """Clone the backing. -- 2.45.2