From 6592d8cff58b34fca96b9f57454173da4df68a81 Mon Sep 17 00:00:00 2001 From: Vipin Balachandran Date: Tue, 25 Aug 2015 17:06:16 +0530 Subject: [PATCH] Enable certificate verification during image copy The VMDK driver config options 'vmware_ca_file' and 'vmware_insecure' are ignored while copying sparse or preallocated vmdk images to vCenter datastores for volume creation. Therefore, the vCenter certificate is not verified during image copy. This patch sets appropriate parameters in the oslo.vmware API (for copying images) call to enable vCenter certificate verification. Closes-bug: #1493331 Change-Id: I04f6a6def9867a573258b0d37693b1824e415838 --- cinder/tests/unit/test_vmware_vmdk.py | 45 +++++++++++++++++++++++++++ cinder/volume/drivers/vmware/vmdk.py | 12 ++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/cinder/tests/unit/test_vmware_vmdk.py b/cinder/tests/unit/test_vmware_vmdk.py index 14a770a5f..b59d824b2 100644 --- a/cinder/tests/unit/test_vmware_vmdk.py +++ b/cinder/tests/unit/test_vmware_vmdk.py @@ -2389,6 +2389,51 @@ class VMwareVcVmdkDriverTestCase(VMwareEsxVmdkDriverTestCase): generate_uuid, extend_disk) + def _test_copy_image(self, download_flat_image, session, vops, + expected_cacerts=False): + + dc_name = mock.sentinel.dc_name + vops.get_entity_name.return_value = dc_name + + context = mock.sentinel.context + dc_ref = mock.sentinel.dc_ref + image_service = mock.sentinel.image_service + image_id = mock.sentinel.image_id + image_size_in_bytes = 102400 + ds_name = mock.sentinel.ds_name + upload_file_path = mock.sentinel.upload_file_path + self._driver._copy_image( + context, dc_ref, image_service, image_id, image_size_in_bytes, + ds_name, upload_file_path) + + vops.get_entity_name.assert_called_once_with(dc_ref) + cookies = session.vim.client.options.transport.cookiejar + download_flat_image.assert_called_once_with( + context, self.IMG_TX_TIMEOUT, image_service, image_id, + image_size=image_size_in_bytes, host=self.IP, port=self.PORT, + data_center_name=dc_name, datastore_name=ds_name, cookies=cookies, + file_path=upload_file_path, cacerts=expected_cacerts) + + @mock.patch.object(VMDK_DRIVER, 'volumeops') + @mock.patch.object(VMDK_DRIVER, 'session') + @mock.patch('oslo_vmware.image_transfer.download_flat_image') + def test_copy_image(self, download_flat_image, session, vops): + # Default value of vmware_ca_file is not None; it should be passed + # to download_flat_image as cacerts. + self._test_copy_image(download_flat_image, session, vops, + expected_cacerts=self._config.vmware_ca_file) + + @mock.patch.object(VMDK_DRIVER, 'volumeops') + @mock.patch.object(VMDK_DRIVER, 'session') + @mock.patch('oslo_vmware.image_transfer.download_flat_image') + def test_copy_image_insecure(self, download_flat_image, session, vops): + # Set config options to allow insecure connections. + self._config.vmware_ca_file = None + self._config.vmware_insecure = True + # Since vmware_ca_file is unset and vmware_insecure is True, + # dowload_flat_image should be called with cacerts=False. + self._test_copy_image(download_flat_image, session, vops) + @mock.patch.object(VMDK_DRIVER, '_copy_temp_virtual_disk') @mock.patch.object(VMDK_DRIVER, '_get_temp_image_folder') @mock.patch( diff --git a/cinder/volume/drivers/vmware/vmdk.py b/cinder/volume/drivers/vmware/vmdk.py index 72de97cba..5f365786f 100644 --- a/cinder/volume/drivers/vmware/vmdk.py +++ b/cinder/volume/drivers/vmware/vmdk.py @@ -813,6 +813,8 @@ class VMwareEsxVmdkDriver(driver.VolumeDriver): timeout = self.configuration.vmware_image_transfer_timeout_secs host_ip = self.configuration.vmware_host_ip + ca_file = self.configuration.vmware_ca_file + insecure = self.configuration.vmware_insecure cookies = self.session.vim.client.options.transport.cookiejar dc_name = self.volumeops.get_entity_name(dc_ref) @@ -820,6 +822,13 @@ class VMwareEsxVmdkDriver(driver.VolumeDriver): {'image_id': image_id, 'path': upload_file_path}) # TODO(vbala): add config option to override non-default port + + # ca_file is used for verifying vCenter certificate if it is set. + # If ca_file is unset and insecure is False, the default CA truststore + # is used for verification. We should pass cacerts=True in this + # case. If ca_file is unset and insecure is True, there is no + # certificate verification, and we should pass cacerts=False. + cacerts = ca_file if ca_file else not insecure image_transfer.download_flat_image(context, timeout, image_service, @@ -830,7 +839,8 @@ class VMwareEsxVmdkDriver(driver.VolumeDriver): data_center_name=dc_name, datastore_name=ds_name, cookies=cookies, - file_path=upload_file_path) + file_path=upload_file_path, + cacerts=cacerts) LOG.debug("Image: %(image_id)s copied to %(path)s.", {'image_id': image_id, 'path': upload_file_path}) -- 2.45.2