VMware: Add 'managedBy' info
Add vCenter managedBy info to volumes in the backend so that they would be displayed as 'managed by OpenStack Cinder'. It also warns the vSphere admin if an operation is attempted using vSphere client. Change-Id: I42c00b7df6aa0576b928e49f6eb21f45b56fa647
This commit is contained in:
parent
6cb68e10b5
commit
14ff0cc2bd
@ -1344,18 +1344,71 @@ class VMwareVcVmdkDriverTestCase(test.TestCase):
|
||||
self._driver._validate_vcenter_version,
|
||||
'5.1')
|
||||
|
||||
@mock.patch('oslo_vmware.vim_util.find_extension')
|
||||
@mock.patch('oslo_vmware.vim_util.register_extension')
|
||||
@mock.patch.object(VMDK_DRIVER, 'session')
|
||||
def _test_register_extension(
|
||||
self, session, register_extension, find_extension,
|
||||
ext_exists=False):
|
||||
if not ext_exists:
|
||||
find_extension.return_value = None
|
||||
|
||||
self._driver._register_extension()
|
||||
|
||||
find_extension.assert_called_once_with(session.vim, vmdk.EXTENSION_KEY)
|
||||
if not ext_exists:
|
||||
register_extension.assert_called_once_with(
|
||||
session.vim, vmdk.EXTENSION_KEY, vmdk.EXTENSION_TYPE,
|
||||
label='OpenStack Cinder')
|
||||
|
||||
def test_register_extension(self):
|
||||
self._test_register_extension()
|
||||
|
||||
def test_register_extension_with_existing_extension(self):
|
||||
self._test_register_extension(ext_exists=True)
|
||||
|
||||
@mock.patch('oslo_vmware.vim_util.find_extension', return_value=None)
|
||||
@mock.patch('oslo_vmware.vim_util.register_extension')
|
||||
@mock.patch.object(VMDK_DRIVER, 'session')
|
||||
def test_concurrent_register_extension(
|
||||
self, session, register_extension, find_extension):
|
||||
register_extension.side_effect = exceptions.VimFaultException(
|
||||
['InvalidArgument'], 'error')
|
||||
self._driver._register_extension()
|
||||
|
||||
find_extension.assert_called_once_with(session.vim, vmdk.EXTENSION_KEY)
|
||||
register_extension.assert_called_once_with(
|
||||
session.vim, vmdk.EXTENSION_KEY, vmdk.EXTENSION_TYPE,
|
||||
label='OpenStack Cinder')
|
||||
|
||||
@mock.patch('oslo_vmware.vim_util.find_extension', return_value=None)
|
||||
@mock.patch('oslo_vmware.vim_util.register_extension')
|
||||
@mock.patch.object(VMDK_DRIVER, 'session')
|
||||
def test_register_extension_failure(
|
||||
self, session, register_extension, find_extension):
|
||||
register_extension.side_effect = exceptions.VimFaultException(
|
||||
['RuntimeFault'], 'error')
|
||||
|
||||
self.assertRaises(exceptions.VimFaultException,
|
||||
self._driver._register_extension)
|
||||
find_extension.assert_called_once_with(session.vim, vmdk.EXTENSION_KEY)
|
||||
register_extension.assert_called_once_with(
|
||||
session.vim, vmdk.EXTENSION_KEY, vmdk.EXTENSION_TYPE,
|
||||
label='OpenStack Cinder')
|
||||
|
||||
@mock.patch.object(VMDK_DRIVER, '_validate_params')
|
||||
@mock.patch.object(VMDK_DRIVER, '_get_vc_version')
|
||||
@mock.patch.object(VMDK_DRIVER, '_validate_vcenter_version')
|
||||
@mock.patch('oslo_vmware.pbm.get_pbm_wsdl_location')
|
||||
@mock.patch.object(VMDK_DRIVER, '_register_extension')
|
||||
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps')
|
||||
@mock.patch('cinder.volume.drivers.vmware.datastore.DatastoreSelector')
|
||||
@mock.patch.object(VMDK_DRIVER, 'volumeops')
|
||||
@mock.patch.object(VMDK_DRIVER, 'session')
|
||||
def _test_do_setup(
|
||||
self, session, vops, ds_sel_cls, vops_cls, get_pbm_wsdl_loc,
|
||||
validate_vc_version, get_vc_version, validate_params,
|
||||
enable_pbm=True):
|
||||
self, session, vops, ds_sel_cls, vops_cls, register_extension,
|
||||
get_pbm_wsdl_loc, validate_vc_version, get_vc_version,
|
||||
validate_params, enable_pbm=True):
|
||||
if enable_pbm:
|
||||
ver_str = '5.5'
|
||||
pbm_wsdl = mock.sentinel.pbm_wsdl
|
||||
@ -1378,8 +1431,10 @@ class VMwareVcVmdkDriverTestCase(test.TestCase):
|
||||
get_pbm_wsdl_loc.assert_called_once_with(ver_str)
|
||||
self.assertEqual(pbm_wsdl, self._driver.pbm_wsdl)
|
||||
self.assertEqual(enable_pbm, self._driver._storage_policy_enabled)
|
||||
register_extension.assert_called_once()
|
||||
vops_cls.assert_called_once_with(
|
||||
session, self._driver.configuration.vmware_max_objects_retrieval)
|
||||
session, self._driver.configuration.vmware_max_objects_retrieval,
|
||||
vmdk.EXTENSION_KEY, vmdk.EXTENSION_TYPE)
|
||||
self.assertEqual(vops_cls.return_value, self._driver._volumeops)
|
||||
ds_sel_cls.assert_called_once_with(
|
||||
vops,
|
||||
|
@ -37,7 +37,9 @@ class VolumeOpsTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(VolumeOpsTestCase, self).setUp()
|
||||
self.session = mock.MagicMock()
|
||||
self.vops = volumeops.VMwareVolumeOps(self.session, self.MAX_OBJECTS)
|
||||
self.vops = volumeops.VMwareVolumeOps(
|
||||
self.session, self.MAX_OBJECTS, mock.sentinel.extension_key,
|
||||
mock.sentinel.extension_type)
|
||||
|
||||
def test_split_datastore_path(self):
|
||||
test1 = '[datastore1] myfolder/mysubfolder/myvm.vmx'
|
||||
@ -604,10 +606,14 @@ class VolumeOpsTestCase(test.TestCase):
|
||||
self.assertEqual(1, len(ret.extraConfig))
|
||||
self.assertEqual(option_key, ret.extraConfig[0].key)
|
||||
self.assertEqual(option_value, ret.extraConfig[0].value)
|
||||
self.assertEqual(mock.sentinel.extension_key,
|
||||
ret.managedBy.extensionKey)
|
||||
self.assertEqual(mock.sentinel.extension_type, ret.managedBy.type)
|
||||
expected = [mock.call.create('ns0:VirtualMachineFileInfo'),
|
||||
mock.call.create('ns0:VirtualMachineConfigSpec'),
|
||||
mock.call.create('ns0:VirtualMachineDefinedProfileSpec'),
|
||||
mock.call.create('ns0:OptionValue')]
|
||||
mock.call.create('ns0:OptionValue'),
|
||||
mock.call.create('ns0:ManagedByInfo')]
|
||||
factory.create.assert_has_calls(expected, any_order=True)
|
||||
|
||||
@mock.patch('cinder.volume.drivers.vmware.volumeops.VMwareVolumeOps.'
|
||||
@ -1004,6 +1010,10 @@ class VolumeOpsTestCase(test.TestCase):
|
||||
self.assertFalse(ret.template)
|
||||
self.assertEqual(snapshot, ret.snapshot)
|
||||
self.assertEqual(mock.sentinel.uuid, ret.config.instanceUuid)
|
||||
self.assertEqual(mock.sentinel.extension_key,
|
||||
ret.config.managedBy.extensionKey)
|
||||
self.assertEqual(mock.sentinel.extension_type,
|
||||
ret.config.managedBy.type)
|
||||
get_relocate_spec.assert_called_once_with(datastore, rp, host,
|
||||
disk_move_type, disk_type,
|
||||
disk_device)
|
||||
|
@ -63,6 +63,9 @@ TMP_IMAGES_DATASTORE_FOLDER_PATH = "cinder_temp/"
|
||||
|
||||
EXTRA_CONFIG_VOLUME_ID_KEY = "cinder.volume.id"
|
||||
|
||||
EXTENSION_KEY = 'org.openstack.storage'
|
||||
EXTENSION_TYPE = 'volume'
|
||||
|
||||
vmdk_opts = [
|
||||
cfg.StrOpt('vmware_host_ip',
|
||||
help='IP address for connecting to VMware vCenter server.'),
|
||||
@ -1679,6 +1682,24 @@ class VMwareVcVmdkDriver(driver.VolumeDriver):
|
||||
' to %(ver)s in a future release.',
|
||||
{'ver': self.NEXT_MIN_SUPPORTED_VC_VERSION})
|
||||
|
||||
def _register_extension(self):
|
||||
ext = vim_util.find_extension(self.session.vim, EXTENSION_KEY)
|
||||
if ext:
|
||||
LOG.debug('Extension %s already exists.', EXTENSION_KEY)
|
||||
else:
|
||||
try:
|
||||
vim_util.register_extension(self.session.vim,
|
||||
EXTENSION_KEY,
|
||||
EXTENSION_TYPE,
|
||||
label='OpenStack Cinder')
|
||||
LOG.info('Registered extension %s.', EXTENSION_KEY)
|
||||
except exceptions.VimFaultException as e:
|
||||
if 'InvalidArgument' in e.fault_list:
|
||||
LOG.debug('Extension %s is already registered.',
|
||||
EXTENSION_KEY)
|
||||
else:
|
||||
raise
|
||||
|
||||
def do_setup(self, context):
|
||||
"""Any initialization the volume driver does while starting."""
|
||||
self._validate_params()
|
||||
@ -1701,10 +1722,13 @@ class VMwareVcVmdkDriver(driver.VolumeDriver):
|
||||
# Destroy current session so that it is recreated with pbm enabled
|
||||
self._session = None
|
||||
|
||||
self._register_extension()
|
||||
|
||||
# recreate session and initialize volumeops and ds_sel
|
||||
# TODO(vbala) remove properties: session, volumeops and ds_sel
|
||||
max_objects = self.configuration.vmware_max_objects_retrieval
|
||||
self._volumeops = volumeops.VMwareVolumeOps(self.session, max_objects)
|
||||
self._volumeops = volumeops.VMwareVolumeOps(
|
||||
self.session, max_objects, EXTENSION_KEY, EXTENSION_TYPE)
|
||||
self._ds_sel = hub.DatastoreSelector(
|
||||
self.volumeops, self.session, max_objects)
|
||||
|
||||
|
@ -278,9 +278,11 @@ class ControllerType(object):
|
||||
class VMwareVolumeOps(object):
|
||||
"""Manages volume operations."""
|
||||
|
||||
def __init__(self, session, max_objects):
|
||||
def __init__(self, session, max_objects, extension_key, extension_type):
|
||||
self._session = session
|
||||
self._max_objects = max_objects
|
||||
self._extension_key = extension_key
|
||||
self._extension_type = extension_type
|
||||
self._folder_cache = {}
|
||||
|
||||
def get_backing(self, name):
|
||||
@ -683,6 +685,13 @@ class VMwareVolumeOps(object):
|
||||
|
||||
return option_values
|
||||
|
||||
def _create_managed_by_info(self):
|
||||
managed_by = self._session.vim.client.factory.create(
|
||||
'ns0:ManagedByInfo')
|
||||
managed_by.extensionKey = self._extension_key
|
||||
managed_by.type = self._extension_type
|
||||
return managed_by
|
||||
|
||||
def _get_create_spec_disk_less(self, name, ds_name, profileId=None,
|
||||
extra_config=None):
|
||||
"""Return spec for creating disk-less backing.
|
||||
@ -721,6 +730,7 @@ class VMwareVolumeOps(object):
|
||||
create_spec.extraConfig = self._get_extra_config_option_values(
|
||||
extra_config)
|
||||
|
||||
create_spec.managedBy = self._create_managed_by_info()
|
||||
return create_spec
|
||||
|
||||
def get_create_spec(self, name, size_kb, disk_type, ds_name,
|
||||
@ -1076,9 +1086,9 @@ class VMwareVolumeOps(object):
|
||||
clone_spec.template = False
|
||||
clone_spec.snapshot = snapshot
|
||||
|
||||
if extra_config or disks_to_clone:
|
||||
config_spec = cf.create('ns0:VirtualMachineConfigSpec')
|
||||
clone_spec.config = config_spec
|
||||
config_spec = cf.create('ns0:VirtualMachineConfigSpec')
|
||||
config_spec.managedBy = self._create_managed_by_info()
|
||||
clone_spec.config = config_spec
|
||||
|
||||
if extra_config:
|
||||
if BACKING_UUID_KEY in extra_config:
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The volumes created by VMware VMDK driver will be displayed as
|
||||
"managed by OpenStack Cinder" in vCenter server.
|
||||
|
Loading…
x
Reference in New Issue
Block a user