Use RetrievePropertiesEx instead of RetrieveProperties
Fixes bug 1183654 The fix also adds a configuration variable enabling the user to configure the maximum amount of objects that can be retrieved by the aforementioned function. When using RetrievePropertiesEx the server may allocate resources in case additional calls are made. These are addressed by reading the extra resources using ContinueRetrievePropertiesEx (if necessary) or CancelRetrievePropertiesEx (when the necessary result has been found). DocImpact Change-Id: I894d9698461b0ce22b01211fd196f6c32899a8fd
This commit is contained in:
parent
4b67e4c34a
commit
e331287cdd
@ -3118,6 +3118,20 @@
|
|||||||
#wsdl_location=<None>
|
#wsdl_location=<None>
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Options defined in nova.virt.vmwareapi.vim_util
|
||||||
|
#
|
||||||
|
|
||||||
|
# The maximum number of ObjectContent data objects that should
|
||||||
|
# be returned in a single result. A positive value will cause
|
||||||
|
# the operation to suspend the retrieval when the count of
|
||||||
|
# objects reaches the specified maximum. The server may still
|
||||||
|
# limit the count to something less than the configured value.
|
||||||
|
# Any remaining objects may be retrieved with additional
|
||||||
|
# requests. (integer value)
|
||||||
|
#maximum_objects=100
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Options defined in nova.virt.vmwareapi.vmops
|
# Options defined in nova.virt.vmwareapi.vmops
|
||||||
#
|
#
|
||||||
|
@ -175,7 +175,7 @@ class VMwareAPIVMTestCase(test.TestCase):
|
|||||||
|
|
||||||
# Get record for VM
|
# Get record for VM
|
||||||
vms = vmwareapi_fake._get_objects("VirtualMachine")
|
vms = vmwareapi_fake._get_objects("VirtualMachine")
|
||||||
vm = vms[0]
|
vm = vms.objects[0]
|
||||||
|
|
||||||
# Check that m1.large above turned into the right thing.
|
# Check that m1.large above turned into the right thing.
|
||||||
mem_kib = long(self.type_data['memory_mb']) << 10
|
mem_kib = long(self.type_data['memory_mb']) << 10
|
||||||
@ -521,10 +521,10 @@ class VMwareAPIVMTestCase(test.TestCase):
|
|||||||
|
|
||||||
def fake_get_vm_ref_from_name(session, vm_name):
|
def fake_get_vm_ref_from_name(session, vm_name):
|
||||||
self.assertEquals(self.vm_name, vm_name)
|
self.assertEquals(self.vm_name, vm_name)
|
||||||
return vmwareapi_fake._get_objects("VirtualMachine")[0]
|
return vmwareapi_fake._get_objects("VirtualMachine").objects[0]
|
||||||
|
|
||||||
def fake_get_vm_ref_from_uuid(session, vm_uuid):
|
def fake_get_vm_ref_from_uuid(session, vm_uuid):
|
||||||
return vmwareapi_fake._get_objects("VirtualMachine")[0]
|
return vmwareapi_fake._get_objects("VirtualMachine").objects[0]
|
||||||
|
|
||||||
def fake_call_method(*args, **kwargs):
|
def fake_call_method(*args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
@ -42,8 +42,10 @@ class VMwareVMUtilTestCase(test.TestCase):
|
|||||||
fake.reset()
|
fake.reset()
|
||||||
|
|
||||||
def test_get_datastore_ref_and_name(self):
|
def test_get_datastore_ref_and_name(self):
|
||||||
|
fake_objects = fake.FakeRetrieveResult()
|
||||||
|
fake_objects.add_object(fake.Datastore())
|
||||||
result = vm_util.get_datastore_ref_and_name(
|
result = vm_util.get_datastore_ref_and_name(
|
||||||
fake_session([fake.Datastore()]))
|
fake_session(fake_objects))
|
||||||
|
|
||||||
self.assertEquals(result[1], "fake-ds")
|
self.assertEquals(result[1], "fake-ds")
|
||||||
self.assertEquals(result[2], 1024 * 1024 * 1024 * 1024)
|
self.assertEquals(result[2], 1024 * 1024 * 1024 * 1024)
|
||||||
@ -66,9 +68,10 @@ class VMwareVMUtilTestCase(test.TestCase):
|
|||||||
|
|
||||||
fake_host_id = fake_host_sys.obj.value
|
fake_host_id = fake_host_sys.obj.value
|
||||||
fake_host_name = "ha-host"
|
fake_host_name = "ha-host"
|
||||||
|
fake_objects = fake.FakeRetrieveResult()
|
||||||
|
fake_objects.add_object(fake_host_sys)
|
||||||
ref = vm_util.get_host_ref_from_id(
|
ref = vm_util.get_host_ref_from_id(
|
||||||
fake_session([fake_host_sys]), fake_host_id, ['name'])
|
fake_session(fake_objects), fake_host_id, ['name'])
|
||||||
|
|
||||||
self.assertIsInstance(ref, fake.HostSystem)
|
self.assertIsInstance(ref, fake.HostSystem)
|
||||||
self.assertEqual(fake_host_id, ref.obj.value)
|
self.assertEqual(fake_host_id, ref.obj.value)
|
||||||
@ -84,9 +87,11 @@ class VMwareVMUtilTestCase(test.TestCase):
|
|||||||
"vm-123", "VirtualMachine"))
|
"vm-123", "VirtualMachine"))
|
||||||
fake_vm.propSet.append(
|
fake_vm.propSet.append(
|
||||||
fake.Property('name', 'vm-123'))
|
fake.Property('name', 'vm-123'))
|
||||||
|
fake_objects = fake.FakeRetrieveResult()
|
||||||
|
fake_objects.add_object(fake_vm)
|
||||||
|
|
||||||
vm_ref = vm_util.get_vm_ref_from_name(
|
vm_ref = vm_util.get_vm_ref_from_name(
|
||||||
fake_session([fake_vm]), 'vm-123')
|
fake_session(fake_objects), 'vm-123')
|
||||||
|
|
||||||
self.assertIsNotNone(vm_ref)
|
self.assertIsNotNone(vm_ref)
|
||||||
|
|
||||||
@ -98,8 +103,12 @@ class VMwareVMUtilTestCase(test.TestCase):
|
|||||||
'host-123', 'HostSystem'))
|
'host-123', 'HostSystem'))
|
||||||
])]
|
])]
|
||||||
|
|
||||||
|
fake_objects = fake.FakeRetrieveResult()
|
||||||
|
for results in fake_results:
|
||||||
|
fake_objects.add_object(results)
|
||||||
|
|
||||||
host_id = vm_util.get_host_id_from_vm_ref(
|
host_id = vm_util.get_host_id_from_vm_ref(
|
||||||
fake_session(fake_results), vm_ref)
|
fake_session(fake_objects), vm_ref)
|
||||||
|
|
||||||
self.assertEqual('host-123', host_id)
|
self.assertEqual('host-123', host_id)
|
||||||
|
|
||||||
@ -109,6 +118,7 @@ class VMwareVMUtilTestCase(test.TestCase):
|
|||||||
DynamicProperty = namedtuple('Property', ['name', 'val'])
|
DynamicProperty = namedtuple('Property', ['name', 'val'])
|
||||||
MoRef = namedtuple('Val', ['value'])
|
MoRef = namedtuple('Val', ['value'])
|
||||||
|
|
||||||
|
good_objects = fake.FakeRetrieveResult()
|
||||||
results_good = [
|
results_good = [
|
||||||
ObjectContent(propSet=[
|
ObjectContent(propSet=[
|
||||||
DynamicProperty(name='name', val=MoRef(value='vm-123'))]),
|
DynamicProperty(name='name', val=MoRef(value='vm-123'))]),
|
||||||
@ -121,7 +131,10 @@ class VMwareVMUtilTestCase(test.TestCase):
|
|||||||
ObjectContent(propSet=[
|
ObjectContent(propSet=[
|
||||||
DynamicProperty(
|
DynamicProperty(
|
||||||
name='something', val=MoRef(value='thing'))]), ]
|
name='something', val=MoRef(value='thing'))]), ]
|
||||||
|
for result in results_good:
|
||||||
|
good_objects.add_object(result)
|
||||||
|
|
||||||
|
bad_objects = fake.FakeRetrieveResult()
|
||||||
results_bad = [
|
results_bad = [
|
||||||
ObjectContent(propSet=[
|
ObjectContent(propSet=[
|
||||||
DynamicProperty(name='name', val=MoRef(value='vm-123'))]),
|
DynamicProperty(name='name', val=MoRef(value='vm-123'))]),
|
||||||
@ -131,22 +144,24 @@ class VMwareVMUtilTestCase(test.TestCase):
|
|||||||
ObjectContent(propSet=[
|
ObjectContent(propSet=[
|
||||||
DynamicProperty(
|
DynamicProperty(
|
||||||
name='something', val=MoRef(value='thing'))]), ]
|
name='something', val=MoRef(value='thing'))]), ]
|
||||||
|
for result in results_bad:
|
||||||
|
bad_objects.add_object(result)
|
||||||
|
|
||||||
prop = vm_util.property_from_property_set(
|
prop = vm_util.property_from_property_set(
|
||||||
'runtime.host', results_good)
|
'runtime.host', good_objects)
|
||||||
self.assertIsNotNone(prop)
|
self.assertIsNotNone(prop)
|
||||||
value = prop.val.value
|
value = prop.val.value
|
||||||
self.assertEqual('host-123', value)
|
self.assertEqual('host-123', value)
|
||||||
|
|
||||||
prop2 = vm_util.property_from_property_set(
|
prop2 = vm_util.property_from_property_set(
|
||||||
'runtime.host', results_bad)
|
'runtime.host', bad_objects)
|
||||||
self.assertIsNone(prop2)
|
self.assertIsNone(prop2)
|
||||||
|
|
||||||
prop3 = vm_util.property_from_property_set('foo', results_good)
|
prop3 = vm_util.property_from_property_set('foo', good_objects)
|
||||||
self.assertIsNotNone(prop3)
|
self.assertIsNotNone(prop3)
|
||||||
val3 = prop3.val.value
|
val3 = prop3.val.value
|
||||||
self.assertEqual('bar1', val3)
|
self.assertEqual('bar1', val3)
|
||||||
|
|
||||||
prop4 = vm_util.property_from_property_set('foo', results_bad)
|
prop4 = vm_util.property_from_property_set('foo', bad_objects)
|
||||||
self.assertIsNotNone(prop4)
|
self.assertIsNotNone(prop4)
|
||||||
self.assertEqual('bar1', prop4.val)
|
self.assertEqual('bar1', prop4.val)
|
||||||
|
@ -67,7 +67,7 @@ class FaultCheckers(object):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def retrieveproperties_fault_checker(resp_obj):
|
def retrieveproperties_fault_checker(resp_obj):
|
||||||
"""
|
"""
|
||||||
Checks the RetrieveProperties response for errors. Certain faults
|
Checks the RetrievePropertiesEx response for errors. Certain faults
|
||||||
are sent as part of the SOAP body as property of missingSet.
|
are sent as part of the SOAP body as property of missingSet.
|
||||||
For example NotAuthenticated fault.
|
For example NotAuthenticated fault.
|
||||||
"""
|
"""
|
||||||
@ -91,5 +91,5 @@ class FaultCheckers(object):
|
|||||||
if fault_list:
|
if fault_list:
|
||||||
exc_msg_list = ', '.join(fault_list)
|
exc_msg_list = ', '.join(fault_list)
|
||||||
raise VimFaultException(fault_list, Exception(_("Error(s) %s "
|
raise VimFaultException(fault_list, Exception(_("Error(s) %s "
|
||||||
"occurred in the call to RetrieveProperties") %
|
"occurred in the call to RetrievePropertiesEx") %
|
||||||
exc_msg_list))
|
exc_msg_list))
|
||||||
|
@ -77,12 +77,22 @@ def _create_object(table, table_obj):
|
|||||||
|
|
||||||
def _get_objects(obj_type):
|
def _get_objects(obj_type):
|
||||||
"""Get objects of the type."""
|
"""Get objects of the type."""
|
||||||
lst_objs = []
|
lst_objs = FakeRetrieveResult()
|
||||||
for key in _db_content[obj_type]:
|
for key in _db_content[obj_type]:
|
||||||
lst_objs.append(_db_content[obj_type][key])
|
lst_objs.add_object(_db_content[obj_type][key])
|
||||||
return lst_objs
|
return lst_objs
|
||||||
|
|
||||||
|
|
||||||
|
class FakeRetrieveResult(object):
|
||||||
|
"""Object to retrieve a ObjectContent list."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.objects = []
|
||||||
|
|
||||||
|
def add_object(self, object):
|
||||||
|
self.objects.append(object)
|
||||||
|
|
||||||
|
|
||||||
class Property(object):
|
class Property(object):
|
||||||
"""Property Object base class."""
|
"""Property Object base class."""
|
||||||
|
|
||||||
@ -317,16 +327,19 @@ class ClusterComputeResource(ManagedObject):
|
|||||||
super(ClusterComputeResource, self).__init__("ClusterComputeResource",
|
super(ClusterComputeResource, self).__init__("ClusterComputeResource",
|
||||||
value="domain-test")
|
value="domain-test")
|
||||||
r_pool = DataObject()
|
r_pool = DataObject()
|
||||||
r_pool.ManagedObjectReference = [_get_objects("ResourcePool")[0].obj]
|
obj = _get_objects("ResourcePool").objects[0].obj
|
||||||
|
r_pool.ManagedObjectReference = [obj]
|
||||||
self.set("resourcePool", r_pool)
|
self.set("resourcePool", r_pool)
|
||||||
|
|
||||||
host_sys = DataObject()
|
host_sys = DataObject()
|
||||||
host_sys.ManagedObjectReference = [_get_objects("HostSystem")[0].obj]
|
obj = _get_objects("HostSystem").objects[0].obj
|
||||||
|
host_sys.ManagedObjectReference = [obj]
|
||||||
self.set("host", host_sys)
|
self.set("host", host_sys)
|
||||||
self.set("name", "test_cluster")
|
self.set("name", "test_cluster")
|
||||||
|
|
||||||
datastore = DataObject()
|
datastore = DataObject()
|
||||||
datastore.ManagedObjectReference = [_get_objects("Datastore")[0].obj]
|
obj = _get_objects("Datastore").objects[0].obj
|
||||||
|
datastore.ManagedObjectReference = [obj]
|
||||||
self.set("datastore", datastore)
|
self.set("datastore", datastore)
|
||||||
|
|
||||||
|
|
||||||
@ -773,6 +786,14 @@ class FakeVim(object):
|
|||||||
task_mdo = create_task(method, "success")
|
task_mdo = create_task(method, "success")
|
||||||
return task_mdo.obj
|
return task_mdo.obj
|
||||||
|
|
||||||
|
def _retrieve_properties_continue(self, method, *args, **kwargs):
|
||||||
|
"""Continues the retrieve."""
|
||||||
|
return FakeRetrieveResult()
|
||||||
|
|
||||||
|
def _retrieve_properties_cancel(self, method, *args, **kwargs):
|
||||||
|
"""Cancels the retrieve."""
|
||||||
|
return None
|
||||||
|
|
||||||
def _retrieve_properties(self, method, *args, **kwargs):
|
def _retrieve_properties(self, method, *args, **kwargs):
|
||||||
"""Retrieves properties based on the type."""
|
"""Retrieves properties based on the type."""
|
||||||
spec_set = kwargs.get("specSet")[0]
|
spec_set = kwargs.get("specSet")[0]
|
||||||
@ -781,7 +802,7 @@ class FakeVim(object):
|
|||||||
if not isinstance(properties, list):
|
if not isinstance(properties, list):
|
||||||
properties = properties.split()
|
properties = properties.split()
|
||||||
objs = spec_set.objectSet
|
objs = spec_set.objectSet
|
||||||
lst_ret_objs = []
|
lst_ret_objs = FakeRetrieveResult()
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
try:
|
try:
|
||||||
obj_ref = obj.obj
|
obj_ref = obj.obj
|
||||||
@ -797,14 +818,14 @@ class FakeVim(object):
|
|||||||
temp_mdo = ManagedObject(mdo.objName, mdo.obj)
|
temp_mdo = ManagedObject(mdo.objName, mdo.obj)
|
||||||
for prop in properties:
|
for prop in properties:
|
||||||
temp_mdo.set(prop, mdo.get(prop))
|
temp_mdo.set(prop, mdo.get(prop))
|
||||||
lst_ret_objs.append(temp_mdo)
|
lst_ret_objs.add_object(temp_mdo)
|
||||||
else:
|
else:
|
||||||
if obj_ref in _db_content[type]:
|
if obj_ref in _db_content[type]:
|
||||||
mdo = _db_content[type][obj_ref]
|
mdo = _db_content[type][obj_ref]
|
||||||
temp_mdo = ManagedObject(mdo.objName, obj_ref)
|
temp_mdo = ManagedObject(mdo.objName, obj_ref)
|
||||||
for prop in properties:
|
for prop in properties:
|
||||||
temp_mdo.set(prop, mdo.get(prop))
|
temp_mdo.set(prop, mdo.get(prop))
|
||||||
lst_ret_objs.append(temp_mdo)
|
lst_ret_objs.add_object(temp_mdo)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
LOG.exception(exc)
|
LOG.exception(exc)
|
||||||
continue
|
continue
|
||||||
@ -872,9 +893,15 @@ class FakeVim(object):
|
|||||||
elif attr_name == "MakeDirectory":
|
elif attr_name == "MakeDirectory":
|
||||||
return lambda *args, **kwargs: self._make_dir(attr_name,
|
return lambda *args, **kwargs: self._make_dir(attr_name,
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
elif attr_name == "RetrieveProperties":
|
elif attr_name == "RetrievePropertiesEx":
|
||||||
return lambda *args, **kwargs: self._retrieve_properties(
|
return lambda *args, **kwargs: self._retrieve_properties(
|
||||||
attr_name, *args, **kwargs)
|
attr_name, *args, **kwargs)
|
||||||
|
elif attr_name == "ContinueRetrievePropertiesEx":
|
||||||
|
return lambda *args, **kwargs: self._retrieve_properties_continue(
|
||||||
|
attr_name, *args, **kwargs)
|
||||||
|
elif attr_name == "CancelRetrievePropertiesEx":
|
||||||
|
return lambda *args, **kwargs: self._retrieve_properties_cancel(
|
||||||
|
attr_name, *args, **kwargs)
|
||||||
elif attr_name == "AcquireCloneTicket":
|
elif attr_name == "AcquireCloneTicket":
|
||||||
return lambda *args, **kwargs: self._just_return()
|
return lambda *args, **kwargs: self._just_return()
|
||||||
elif attr_name == "AddPortGroup":
|
elif attr_name == "AddPortGroup":
|
||||||
|
@ -35,8 +35,7 @@ class Host(object):
|
|||||||
|
|
||||||
def host_power_action(self, host, action):
|
def host_power_action(self, host, action):
|
||||||
"""Reboots or shuts down the host."""
|
"""Reboots or shuts down the host."""
|
||||||
host_mor = self._session._call_method(vim_util, "get_objects",
|
host_mor = vm_util.get_host_ref(self._session)
|
||||||
"HostSystem")[0].obj
|
|
||||||
LOG.debug(_("%(action)s %(host)s"), {'action': action, 'host': host})
|
LOG.debug(_("%(action)s %(host)s"), {'action': action, 'host': host})
|
||||||
if action == "reboot":
|
if action == "reboot":
|
||||||
host_task = self._session._call_method(
|
host_task = self._session._call_method(
|
||||||
@ -59,8 +58,7 @@ class Host(object):
|
|||||||
"""Start/Stop host maintenance window. On start, it triggers
|
"""Start/Stop host maintenance window. On start, it triggers
|
||||||
guest VMs evacuation.
|
guest VMs evacuation.
|
||||||
"""
|
"""
|
||||||
host_mor = self._session._call_method(vim_util, "get_objects",
|
host_mor = vm_util.get_host_ref(self._session)
|
||||||
"HostSystem")[0].obj
|
|
||||||
LOG.debug(_("Set maintenance mod on %(host)s to %(mode)s"),
|
LOG.debug(_("Set maintenance mod on %(host)s to %(mode)s"),
|
||||||
{'host': host, 'mode': mode})
|
{'host': host, 'mode': mode})
|
||||||
if mode:
|
if mode:
|
||||||
@ -103,8 +101,7 @@ class HostState(object):
|
|||||||
def update_status(self):
|
def update_status(self):
|
||||||
"""Update the current state of the host.
|
"""Update the current state of the host.
|
||||||
"""
|
"""
|
||||||
host_mor = self._session._call_method(vim_util, "get_objects",
|
host_mor = vm_util.get_host_ref(self._session)
|
||||||
"HostSystem")[0].obj
|
|
||||||
summary = self._session._call_method(vim_util,
|
summary = self._session._call_method(vim_util,
|
||||||
"get_dynamic_property",
|
"get_dynamic_property",
|
||||||
host_mor,
|
host_mor,
|
||||||
|
@ -19,6 +19,22 @@
|
|||||||
The VMware API utility module.
|
The VMware API utility module.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
|
||||||
|
vmware_opts = cfg.IntOpt('maximum_objects', default=100,
|
||||||
|
help='The maximum number of ObjectContent data '
|
||||||
|
'objects that should be returned in a single '
|
||||||
|
'result. A positive value will cause the '
|
||||||
|
'operation to suspend the retrieval when the '
|
||||||
|
'count of objects reaches the specified '
|
||||||
|
'maximum. The server may still limit the count '
|
||||||
|
'to something less than the configured value. '
|
||||||
|
'Any remaining objects may be retrieved with '
|
||||||
|
'additional requests.')
|
||||||
|
CONF = cfg.CONF
|
||||||
|
CONF.register_opt(vmware_opts, 'vmware')
|
||||||
|
|
||||||
|
|
||||||
def build_selection_spec(client_factory, name):
|
def build_selection_spec(client_factory, name):
|
||||||
"""Builds the selection spec."""
|
"""Builds the selection spec."""
|
||||||
@ -143,15 +159,20 @@ def get_object_properties(vim, collector, mobj, type, properties):
|
|||||||
object_spec.skip = False
|
object_spec.skip = False
|
||||||
property_filter_spec.propSet = [property_spec]
|
property_filter_spec.propSet = [property_spec]
|
||||||
property_filter_spec.objectSet = [object_spec]
|
property_filter_spec.objectSet = [object_spec]
|
||||||
return vim.RetrieveProperties(usecoll, specSet=[property_filter_spec])
|
options = client_factory.create('ns0:RetrieveOptions')
|
||||||
|
options.maxObjects = CONF.vmware.maximum_objects
|
||||||
|
return vim.RetrievePropertiesEx(usecoll, specSet=[property_filter_spec],
|
||||||
|
options=options)
|
||||||
|
|
||||||
|
|
||||||
def get_dynamic_property(vim, mobj, type, property_name):
|
def get_dynamic_property(vim, mobj, type, property_name):
|
||||||
"""Gets a particular property of the Managed Object."""
|
"""Gets a particular property of the Managed Object."""
|
||||||
obj_content = get_object_properties(vim, None, mobj, type, [property_name])
|
obj_content = get_object_properties(vim, None, mobj, type, [property_name])
|
||||||
|
if hasattr(obj_content, 'token'):
|
||||||
|
vim.CancelRetrievePropertiesEx(token=obj_content.token)
|
||||||
property_value = None
|
property_value = None
|
||||||
if obj_content:
|
if obj_content.objects:
|
||||||
dynamic_property = obj_content[0].propSet
|
dynamic_property = obj_content.objects[0].propSet
|
||||||
if dynamic_property:
|
if dynamic_property:
|
||||||
property_value = dynamic_property[0].val
|
property_value = dynamic_property[0].val
|
||||||
return property_value
|
return property_value
|
||||||
@ -172,8 +193,25 @@ def get_objects(vim, type, properties_to_collect=None, all=False):
|
|||||||
property_filter_spec = build_property_filter_spec(client_factory,
|
property_filter_spec = build_property_filter_spec(client_factory,
|
||||||
[property_spec],
|
[property_spec],
|
||||||
[object_spec])
|
[object_spec])
|
||||||
return vim.RetrieveProperties(vim.get_service_content().propertyCollector,
|
options = client_factory.create('ns0:RetrieveOptions')
|
||||||
specSet=[property_filter_spec])
|
options.maxObjects = CONF.vmware.maximum_objects
|
||||||
|
return vim.RetrievePropertiesEx(
|
||||||
|
vim.get_service_content().propertyCollector,
|
||||||
|
specSet=[property_filter_spec], options=options)
|
||||||
|
|
||||||
|
|
||||||
|
def cancel_retrieve(vim, token):
|
||||||
|
"""Cancels the retrieve operation."""
|
||||||
|
return vim.CancelRetrievePropertiesEx(
|
||||||
|
vim.get_service_content().propertyCollector,
|
||||||
|
token=token)
|
||||||
|
|
||||||
|
|
||||||
|
def continue_to_get_objects(vim, token):
|
||||||
|
"""Continues to get the list of objects of the type specified."""
|
||||||
|
return vim.ContinueRetrievePropertiesEx(
|
||||||
|
vim.get_service_content().propertyCollector,
|
||||||
|
token=token)
|
||||||
|
|
||||||
|
|
||||||
def get_prop_spec(client_factory, spec_type, properties):
|
def get_prop_spec(client_factory, spec_type, properties):
|
||||||
@ -217,5 +255,8 @@ def get_properties_for_a_collection_of_objects(vim, type,
|
|||||||
lst_obj_specs.append(get_obj_spec(client_factory, obj))
|
lst_obj_specs.append(get_obj_spec(client_factory, obj))
|
||||||
prop_filter_spec = get_prop_filter_spec(client_factory,
|
prop_filter_spec = get_prop_filter_spec(client_factory,
|
||||||
lst_obj_specs, [prop_spec])
|
lst_obj_specs, [prop_spec])
|
||||||
return vim.RetrieveProperties(vim.get_service_content().propertyCollector,
|
options = client_factory.create('ns0:RetrieveOptions')
|
||||||
specSet=[prop_filter_spec])
|
options.maxObjects = CONF.vmware.maximum_objects
|
||||||
|
return vim.RetrievePropertiesEx(
|
||||||
|
vim.get_service_content().propertyCollector,
|
||||||
|
specSet=[prop_filter_spec], options=options)
|
||||||
|
@ -498,23 +498,64 @@ def search_datastore_spec(client_factory, file_name):
|
|||||||
return search_spec
|
return search_spec
|
||||||
|
|
||||||
|
|
||||||
|
def _get_token(results):
|
||||||
|
"""Get the token from the property results."""
|
||||||
|
return getattr(results, 'token', None)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_reference_for_value(results, value):
|
||||||
|
for object in results.objects:
|
||||||
|
if object.obj.value == value:
|
||||||
|
return object
|
||||||
|
|
||||||
|
|
||||||
|
def _get_object_for_value(results, value):
|
||||||
|
for object in results.objects:
|
||||||
|
if object.propSet[0].val == value:
|
||||||
|
return object.obj
|
||||||
|
|
||||||
|
|
||||||
|
def _get_object_from_results(session, results, value, func):
|
||||||
|
while results:
|
||||||
|
token = _get_token(results)
|
||||||
|
object = func(results, value)
|
||||||
|
if object:
|
||||||
|
if token:
|
||||||
|
session._call_method(vim_util,
|
||||||
|
"cancel_retrieve",
|
||||||
|
token)
|
||||||
|
return object
|
||||||
|
|
||||||
|
if token:
|
||||||
|
results = session._call_method(vim_util,
|
||||||
|
"continue_to_get_objects",
|
||||||
|
token)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _cancel_retrieve_if_necessary(session, results):
|
||||||
|
token = _get_token(results)
|
||||||
|
if token:
|
||||||
|
results = session._call_method(vim_util,
|
||||||
|
"cancel_retrieve",
|
||||||
|
token)
|
||||||
|
|
||||||
|
|
||||||
def get_vm_ref_from_name(session, vm_name):
|
def get_vm_ref_from_name(session, vm_name):
|
||||||
"""Get reference to the VM with the name specified."""
|
"""Get reference to the VM with the name specified."""
|
||||||
vms = session._call_method(vim_util, "get_objects",
|
vms = session._call_method(vim_util, "get_objects",
|
||||||
"VirtualMachine", ["name"])
|
"VirtualMachine", ["name"])
|
||||||
for vm in vms:
|
return _get_object_from_results(session, vms, vm_name,
|
||||||
if vm.propSet[0].val == vm_name:
|
_get_object_for_value)
|
||||||
return vm.obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def get_vm_ref_from_uuid(session, instance_uuid):
|
def get_vm_ref_from_uuid(session, instance_uuid):
|
||||||
"""Get reference to the VM with the uuid specified."""
|
"""Get reference to the VM with the uuid specified."""
|
||||||
vms = session._call_method(vim_util, "get_objects",
|
vms = session._call_method(vim_util, "get_objects",
|
||||||
"VirtualMachine", ["name"])
|
"VirtualMachine", ["name"])
|
||||||
for vm in vms:
|
return _get_object_from_results(session, vms, instance_uuid,
|
||||||
if vm.propSet[0].val == instance_uuid:
|
_get_object_for_value)
|
||||||
return vm.obj
|
|
||||||
|
|
||||||
|
|
||||||
def get_vm_ref(session, instance):
|
def get_vm_ref(session, instance):
|
||||||
@ -536,10 +577,8 @@ def get_host_ref_from_id(session, host_id, property_list=None):
|
|||||||
host_refs = session._call_method(
|
host_refs = session._call_method(
|
||||||
vim_util, "get_objects",
|
vim_util, "get_objects",
|
||||||
"HostSystem", property_list)
|
"HostSystem", property_list)
|
||||||
|
return _get_object_from_results(session, host_refs, host_id,
|
||||||
for ref in host_refs:
|
_get_reference_for_value)
|
||||||
if ref.obj.value == host_id:
|
|
||||||
return ref
|
|
||||||
|
|
||||||
|
|
||||||
def get_host_id_from_vm_ref(session, vm_ref):
|
def get_host_id_from_vm_ref(session, vm_ref):
|
||||||
@ -600,7 +639,7 @@ def property_from_property_set(property_name, property_set):
|
|||||||
:return: the value of the property.
|
:return: the value of the property.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
for prop in property_set:
|
for prop in property_set.objects:
|
||||||
p = _property_from_propSet(prop.propSet, property_name)
|
p = _property_from_propSet(prop.propSet, property_name)
|
||||||
if p is not None:
|
if p is not None:
|
||||||
return p
|
return p
|
||||||
@ -643,17 +682,17 @@ def get_cluster_ref_from_name(session, cluster_name):
|
|||||||
"""Get reference to the cluster with the name specified."""
|
"""Get reference to the cluster with the name specified."""
|
||||||
cls = session._call_method(vim_util, "get_objects",
|
cls = session._call_method(vim_util, "get_objects",
|
||||||
"ClusterComputeResource", ["name"])
|
"ClusterComputeResource", ["name"])
|
||||||
for cluster in cls:
|
return _get_object_from_results(session, cls, cluster_name,
|
||||||
if cluster.propSet[0].val == cluster_name:
|
_get_object_for_value)
|
||||||
return cluster.obj
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def get_host_ref(session, cluster=None):
|
def get_host_ref(session, cluster=None):
|
||||||
"""Get reference to a host within the cluster specified."""
|
"""Get reference to a host within the cluster specified."""
|
||||||
if cluster is None:
|
if cluster is None:
|
||||||
host_mor = session._call_method(vim_util, "get_objects",
|
results = session._call_method(vim_util, "get_objects",
|
||||||
"HostSystem")[0].obj
|
"HostSystem")
|
||||||
|
_cancel_retrieve_if_necessary(session, results)
|
||||||
|
host_mor = results.objects[0].obj
|
||||||
else:
|
else:
|
||||||
host_ret = session._call_method(vim_util, "get_dynamic_property",
|
host_ret = session._call_method(vim_util, "get_dynamic_property",
|
||||||
cluster, "ClusterComputeResource",
|
cluster, "ClusterComputeResource",
|
||||||
@ -667,6 +706,26 @@ def get_host_ref(session, cluster=None):
|
|||||||
return host_mor
|
return host_mor
|
||||||
|
|
||||||
|
|
||||||
|
def _get_datastore_ref_and_name(data_stores):
|
||||||
|
for elem in data_stores.objects:
|
||||||
|
ds_name = None
|
||||||
|
ds_type = None
|
||||||
|
ds_cap = None
|
||||||
|
ds_free = None
|
||||||
|
for prop in elem.propSet:
|
||||||
|
if prop.name == "summary.type":
|
||||||
|
ds_type = prop.val
|
||||||
|
elif prop.name == "summary.name":
|
||||||
|
ds_name = prop.val
|
||||||
|
elif prop.name == "summary.capacity":
|
||||||
|
ds_cap = prop.val
|
||||||
|
elif prop.name == "summary.freeSpace":
|
||||||
|
ds_free = prop.val
|
||||||
|
# Local storage identifier
|
||||||
|
if ds_type == "VMFS" or ds_type == "NFS":
|
||||||
|
return elem.obj, ds_name, ds_cap, ds_free
|
||||||
|
|
||||||
|
|
||||||
def get_datastore_ref_and_name(session, cluster=None, host=None):
|
def get_datastore_ref_and_name(session, cluster=None, host=None):
|
||||||
"""Get the datastore list and choose the first local storage."""
|
"""Get the datastore list and choose the first local storage."""
|
||||||
if cluster is None and host is None:
|
if cluster is None and host is None:
|
||||||
@ -693,22 +752,20 @@ def get_datastore_ref_and_name(session, cluster=None, host=None):
|
|||||||
"Datastore", data_store_mors,
|
"Datastore", data_store_mors,
|
||||||
["summary.type", "summary.name",
|
["summary.type", "summary.name",
|
||||||
"summary.capacity", "summary.freeSpace"])
|
"summary.capacity", "summary.freeSpace"])
|
||||||
for elem in data_stores:
|
|
||||||
ds_name = None
|
|
||||||
ds_type = None
|
|
||||||
ds_cap = None
|
|
||||||
ds_free = None
|
|
||||||
for prop in elem.propSet:
|
|
||||||
if prop.name == "summary.type":
|
|
||||||
ds_type = prop.val
|
|
||||||
elif prop.name == "summary.name":
|
|
||||||
ds_name = prop.val
|
|
||||||
elif prop.name == "summary.capacity":
|
|
||||||
ds_cap = prop.val
|
|
||||||
elif prop.name == "summary.freeSpace":
|
|
||||||
ds_free = prop.val
|
|
||||||
# Local storage identifier
|
|
||||||
if ds_type == "VMFS" or ds_type == "NFS":
|
|
||||||
return elem.obj, ds_name, ds_cap, ds_free
|
|
||||||
|
|
||||||
|
while data_stores:
|
||||||
|
token = _get_token(data_stores)
|
||||||
|
results = _get_datastore_ref_and_name(data_stores)
|
||||||
|
if results:
|
||||||
|
if token:
|
||||||
|
session._call_method(vim_util,
|
||||||
|
"cancel_retrieve",
|
||||||
|
token)
|
||||||
|
return results
|
||||||
|
if token:
|
||||||
|
data_stores = session._call_method(vim_util,
|
||||||
|
"continue_to_get_objects",
|
||||||
|
token)
|
||||||
|
else:
|
||||||
|
raise exception.DatastoreNotFound()
|
||||||
raise exception.DatastoreNotFound()
|
raise exception.DatastoreNotFound()
|
||||||
|
@ -94,7 +94,10 @@ class VMwareVMOps(object):
|
|||||||
"VirtualMachine",
|
"VirtualMachine",
|
||||||
["name", "runtime.connectionState"])
|
["name", "runtime.connectionState"])
|
||||||
lst_vm_names = []
|
lst_vm_names = []
|
||||||
for vm in vms:
|
|
||||||
|
while vms:
|
||||||
|
token = vm_util._get_token(vms)
|
||||||
|
for vm in vms.objects:
|
||||||
vm_name = None
|
vm_name = None
|
||||||
conn_state = None
|
conn_state = None
|
||||||
for prop in vm.propSet:
|
for prop in vm.propSet:
|
||||||
@ -105,6 +108,13 @@ class VMwareVMOps(object):
|
|||||||
# Ignoring the orphaned or inaccessible VMs
|
# Ignoring the orphaned or inaccessible VMs
|
||||||
if conn_state not in ["orphaned", "inaccessible"]:
|
if conn_state not in ["orphaned", "inaccessible"]:
|
||||||
lst_vm_names.append(vm_name)
|
lst_vm_names.append(vm_name)
|
||||||
|
if token:
|
||||||
|
vms = self._session._call_method(vim_util,
|
||||||
|
"continue_to_get_objects",
|
||||||
|
token)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
LOG.debug(_("Got total of %s instances") % str(len(lst_vm_names)))
|
LOG.debug(_("Got total of %s instances") % str(len(lst_vm_names)))
|
||||||
return lst_vm_names
|
return lst_vm_names
|
||||||
|
|
||||||
@ -579,6 +589,22 @@ class VMwareVMOps(object):
|
|||||||
|
|
||||||
_clean_temp_data()
|
_clean_temp_data()
|
||||||
|
|
||||||
|
def _get_values_from_object_properties(self, props, query):
|
||||||
|
while props:
|
||||||
|
token = vm_util._get_token(props)
|
||||||
|
for elem in props.objects:
|
||||||
|
for prop in elem.propSet:
|
||||||
|
for key in query.keys():
|
||||||
|
if prop.name == key:
|
||||||
|
query[key] = prop.val
|
||||||
|
break
|
||||||
|
if token:
|
||||||
|
props = self._session._call_method(vim_util,
|
||||||
|
"continue_to_get_objects",
|
||||||
|
token)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
def reboot(self, instance, network_info):
|
def reboot(self, instance, network_info):
|
||||||
"""Reboot a VM instance."""
|
"""Reboot a VM instance."""
|
||||||
vm_ref = vm_util.get_vm_ref(self._session, instance)
|
vm_ref = vm_util.get_vm_ref(self._session, instance)
|
||||||
@ -589,17 +615,13 @@ class VMwareVMOps(object):
|
|||||||
props = self._session._call_method(vim_util, "get_object_properties",
|
props = self._session._call_method(vim_util, "get_object_properties",
|
||||||
None, vm_ref, "VirtualMachine",
|
None, vm_ref, "VirtualMachine",
|
||||||
lst_properties)
|
lst_properties)
|
||||||
pwr_state = None
|
query = {'runtime.powerState': None,
|
||||||
tools_status = None
|
'summary.guest.toolsStatus': None,
|
||||||
tools_running_status = False
|
'summary.guest.toolsRunningStatus': False}
|
||||||
for elem in props:
|
self._get_values_from_object_properties(props, query)
|
||||||
for prop in elem.propSet:
|
pwr_state = query['runtime.powerState']
|
||||||
if prop.name == "runtime.powerState":
|
tools_status = query['summary.guest.toolsStatus']
|
||||||
pwr_state = prop.val
|
tools_running_status = query['summary.guest.toolsRunningStatus']
|
||||||
elif prop.name == "summary.guest.toolsStatus":
|
|
||||||
tools_status = prop.val
|
|
||||||
elif prop.name == "summary.guest.toolsRunningStatus":
|
|
||||||
tools_running_status = prop.val
|
|
||||||
|
|
||||||
# Raise an exception if the VM is not powered On.
|
# Raise an exception if the VM is not powered On.
|
||||||
if pwr_state not in ["poweredOn"]:
|
if pwr_state not in ["poweredOn"]:
|
||||||
@ -659,14 +681,11 @@ class VMwareVMOps(object):
|
|||||||
props = self._session._call_method(vim_util,
|
props = self._session._call_method(vim_util,
|
||||||
"get_object_properties",
|
"get_object_properties",
|
||||||
None, vm_ref, "VirtualMachine", lst_properties)
|
None, vm_ref, "VirtualMachine", lst_properties)
|
||||||
pwr_state = None
|
query = {'runtime.powerState': None,
|
||||||
for elem in props:
|
'config.files.vmPathName': None}
|
||||||
vm_config_pathname = None
|
self._get_values_from_object_properties(props, query)
|
||||||
for prop in elem.propSet:
|
pwr_state = query['runtime.powerState']
|
||||||
if prop.name == "runtime.powerState":
|
vm_config_pathname = query['config.files.vmPathName']
|
||||||
pwr_state = prop.val
|
|
||||||
elif prop.name == "config.files.vmPathName":
|
|
||||||
vm_config_pathname = prop.val
|
|
||||||
if vm_config_pathname:
|
if vm_config_pathname:
|
||||||
_ds_path = vm_util.split_datastore_path(vm_config_pathname)
|
_ds_path = vm_util.split_datastore_path(vm_config_pathname)
|
||||||
datastore_name, vmx_file_path = _ds_path
|
datastore_name, vmx_file_path = _ds_path
|
||||||
@ -1039,23 +1058,15 @@ class VMwareVMOps(object):
|
|||||||
vm_props = self._session._call_method(vim_util,
|
vm_props = self._session._call_method(vim_util,
|
||||||
"get_object_properties", None, vm_ref, "VirtualMachine",
|
"get_object_properties", None, vm_ref, "VirtualMachine",
|
||||||
lst_properties)
|
lst_properties)
|
||||||
max_mem = None
|
query = {'summary.config.numCpu': None,
|
||||||
pwr_state = None
|
'summary.config.memorySizeMB': None,
|
||||||
num_cpu = None
|
'runtime.powerState': None}
|
||||||
for elem in vm_props:
|
self._get_values_from_object_properties(vm_props, query)
|
||||||
for prop in elem.propSet:
|
max_mem = int(query['summary.config.memorySizeMB']) * 1024
|
||||||
if prop.name == "summary.config.numCpu":
|
return {'state': VMWARE_POWER_STATES[query['runtime.powerState']],
|
||||||
num_cpu = int(prop.val)
|
|
||||||
elif prop.name == "summary.config.memorySizeMB":
|
|
||||||
# In MB, but we want in KB
|
|
||||||
max_mem = int(prop.val) * 1024
|
|
||||||
elif prop.name == "runtime.powerState":
|
|
||||||
pwr_state = VMWARE_POWER_STATES[prop.val]
|
|
||||||
|
|
||||||
return {'state': pwr_state,
|
|
||||||
'max_mem': max_mem,
|
'max_mem': max_mem,
|
||||||
'mem': max_mem,
|
'mem': max_mem,
|
||||||
'num_cpu': num_cpu,
|
'num_cpu': int(query['summary.config.numCpu']),
|
||||||
'cpu_time': 0}
|
'cpu_time': 0}
|
||||||
|
|
||||||
def get_diagnostics(self, instance):
|
def get_diagnostics(self, instance):
|
||||||
@ -1190,12 +1201,14 @@ class VMwareVMOps(object):
|
|||||||
"""Get the datacenter name and the reference."""
|
"""Get the datacenter name and the reference."""
|
||||||
dc_obj = self._session._call_method(vim_util, "get_objects",
|
dc_obj = self._session._call_method(vim_util, "get_objects",
|
||||||
"Datacenter", ["name"])
|
"Datacenter", ["name"])
|
||||||
return dc_obj[0].obj, dc_obj[0].propSet[0].val
|
vm_util._cancel_retrieve_if_necessary(self._session, dc_obj)
|
||||||
|
return dc_obj.objects[0].obj, dc_obj.objects[0].propSet[0].val
|
||||||
|
|
||||||
def _get_host_ref_from_name(self, host_name):
|
def _get_host_ref_from_name(self, host_name):
|
||||||
"""Get reference to the host with the name specified."""
|
"""Get reference to the host with the name specified."""
|
||||||
host_objs = self._session._call_method(vim_util, "get_objects",
|
host_objs = self._session._call_method(vim_util, "get_objects",
|
||||||
"HostSystem", ["name"])
|
"HostSystem", ["name"])
|
||||||
|
vm_util._cancel_retrieve_if_necessary(self._session, host_objs)
|
||||||
for host in host_objs:
|
for host in host_objs:
|
||||||
if host.propSet[0].val == host_name:
|
if host.propSet[0].val == host_name:
|
||||||
return host.obj
|
return host.obj
|
||||||
@ -1205,16 +1218,19 @@ class VMwareVMOps(object):
|
|||||||
"""Get the Vm folder ref from the datacenter."""
|
"""Get the Vm folder ref from the datacenter."""
|
||||||
dc_objs = self._session._call_method(vim_util, "get_objects",
|
dc_objs = self._session._call_method(vim_util, "get_objects",
|
||||||
"Datacenter", ["vmFolder"])
|
"Datacenter", ["vmFolder"])
|
||||||
|
vm_util._cancel_retrieve_if_necessary(self._session, dc_objs)
|
||||||
# There is only one default datacenter in a standalone ESX host
|
# There is only one default datacenter in a standalone ESX host
|
||||||
vm_folder_ref = dc_objs[0].propSet[0].val
|
vm_folder_ref = dc_objs.objects[0].propSet[0].val
|
||||||
return vm_folder_ref
|
return vm_folder_ref
|
||||||
|
|
||||||
def _get_res_pool_ref(self):
|
def _get_res_pool_ref(self):
|
||||||
# Get the resource pool. Taking the first resource pool coming our
|
# Get the resource pool. Taking the first resource pool coming our
|
||||||
# way. Assuming that is the default resource pool.
|
# way. Assuming that is the default resource pool.
|
||||||
if self._cluster is None:
|
if self._cluster is None:
|
||||||
res_pool_ref = self._session._call_method(vim_util, "get_objects",
|
results = self._session._call_method(vim_util, "get_objects",
|
||||||
"ResourcePool")[0].obj
|
"ResourcePool")
|
||||||
|
vm_util._cancel_retrieve_if_necessary(self._session, results)
|
||||||
|
res_pool_ref = results.objects[0].obj
|
||||||
else:
|
else:
|
||||||
res_pool_ref = self._session._call_method(vim_util,
|
res_pool_ref = self._session._call_method(vim_util,
|
||||||
"get_dynamic_property",
|
"get_dynamic_property",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user