Add get_datastore_by_ref method to oslo.vmware

Two methods are added as part of this patch:-

1. get_datastore_by_ref - returns a Datastore object given a
datastore reference.

2. get_object_properties_dict - a vim utility method to retrieve
properties of an object as a dictionary.

Currently, Glance needs these methods to find datastore
objects from datastore references.

Change-Id: I516536ea4098357540531105b4f97e6668fb3f08
This commit is contained in:
Sabari Kumar Murugesan 2015-02-17 20:16:56 -08:00
parent 14339755ce
commit a95c0ae05f
4 changed files with 112 additions and 0 deletions

View File

@ -28,6 +28,30 @@ LOG = logging.getLogger(__name__)
random = _random.SystemRandom() random = _random.SystemRandom()
def get_datastore_by_ref(session, ds_ref):
"""Returns a datastore object for a given reference.
:param session: a vmware api session object
:param ds_ref: managed object reference of a datastore
:rtype : a datastore object
"""
lst_properties = ["summary.type",
"summary.name",
"summary.capacity",
"summary.freeSpace"]
props = session.invoke_api(
vim_util,
"get_object_properties_dict",
session.vim,
ds_ref,
lst_properties)
# TODO(sabari): Instantiate with datacenter info.
return Datastore(ds_ref, props["summary.name"],
capacity=props.get("summary.capacity"),
freespace=props.get("summary.freeSpace"),
type=props.get("summary.type"))
class Datastore(object): class Datastore(object):
def __init__(self, ref, name, capacity=None, freespace=None, def __init__(self, ref, name, capacity=None, freespace=None,

View File

@ -17,9 +17,15 @@
The VMware API utility module. The VMware API utility module.
""" """
import logging
from suds import sudsobject from suds import sudsobject
from oslo.utils import timeutils from oslo.utils import timeutils
from oslo_vmware._i18n import _LW
LOG = logging.getLogger(__name__)
def get_moref(value, type_): def get_moref(value, type_):
@ -316,6 +322,36 @@ def get_object_properties(vim, moref, properties_to_collect):
return retrieve_result.objects return retrieve_result.objects
def get_object_properties_dict(vim, moref, properties_to_collect):
"""Get properties of the given managed object as a dict.
:param vim: Vim object
:param moref: managed object reference
:param properties_to_collect: names of the managed object properties to be
collected
:returns: a dict of properties of the given managed object
:raises: VimException, VimFaultException, VimAttributeException,
VimSessionOverLoadException, VimConnectionException
"""
obj_contents = get_object_properties(vim, moref, properties_to_collect)
if obj_contents is None:
return {}
property_dict = {}
if hasattr(obj_contents[0], 'propSet'):
dynamic_properties = obj_contents[0].propSet
if dynamic_properties:
for prop in dynamic_properties:
property_dict[prop.name] = prop.val
# The object may have information useful for logging
if hasattr(obj_contents[0], 'missingSet'):
for m in obj_contents[0].missingSet:
LOG.warning(_LW("Unable to retrieve value for %(path)s "
"Reason: %(reason)s"),
{'path': m.path,
'reason': m.fault.localizedMessage})
return property_dict
def _get_token(retrieve_result): def _get_token(retrieve_result):
"""Get token from result to obtain next set of results. """Get token from result to obtain next set of results.

View File

@ -383,3 +383,18 @@ class DatastoreURLTestCase(base.TestCase):
ticket = ds_url.get_transfer_ticket(session, 'PUT') ticket = ds_url.get_transfer_ticket(session, 'PUT')
self.assertEqual('%s="%s"' % (constants.CGI_COOKIE_KEY, 'fake_id'), self.assertEqual('%s="%s"' % (constants.CGI_COOKIE_KEY, 'fake_id'),
ticket) ticket)
def test_get_datastore_by_ref(self):
session = mock.Mock()
ds_ref = mock.Mock()
expected_props = {'summary.name': 'datastore1',
'summary.type': 'NFS',
'summary.freeSpace': 1000,
'summary.capacity': 2000}
session.invoke_api = mock.Mock()
session.invoke_api.return_value = expected_props
ds_obj = datastore.get_datastore_by_ref(session, ds_ref)
self.assertEqual(expected_props['summary.name'], ds_obj.name)
self.assertEqual(expected_props['summary.type'], ds_obj.type)
self.assertEqual(expected_props['summary.freeSpace'], ds_obj.freespace)
self.assertEqual(expected_props['summary.capacity'], ds_obj.capacity)

View File

@ -253,6 +253,43 @@ class VimUtilTest(base.TestCase):
self.assertTrue(res is retrieve_result.objects) self.assertTrue(res is retrieve_result.objects)
cancel_retrieval.assert_called_once_with(vim, retrieve_result) cancel_retrieval.assert_called_once_with(vim, retrieve_result)
@mock.patch('oslo_vmware.vim_util.get_object_properties')
def test_get_object_properties_dict_empty(self, mock_obj_prop):
mock_obj_prop.return_value = None
vim = mock.Mock()
moref = mock.Mock()
res = vim_util.get_object_properties_dict(vim, moref, None)
self.assertEqual({}, res)
@mock.patch('oslo_vmware.vim_util.get_object_properties')
def test_get_object_properties_dict(self, mock_obj_prop):
expected_prop_dict = {'name': 'vm01'}
mock_obj_content = mock.Mock()
prop = mock.Mock()
prop.name = "name"
prop.val = "vm01"
mock_obj_content.propSet = [prop]
del mock_obj_content.missingSet
mock_obj_prop.return_value = [mock_obj_content]
vim = mock.Mock()
moref = mock.Mock()
res = vim_util.get_object_properties_dict(vim, moref, None)
self.assertEqual(expected_prop_dict, res)
@mock.patch('oslo_vmware.vim_util.get_object_properties')
def test_get_object_properties_dict_missing(self, mock_obj_prop):
mock_obj_content = mock.Mock()
missing_prop = mock.Mock()
missing_prop.path = "name"
missing_prop.fault = mock.Mock()
mock_obj_content.missingSet = [missing_prop]
del mock_obj_content.propSet
mock_obj_prop.return_value = [mock_obj_content]
vim = mock.Mock()
moref = mock.Mock()
res = vim_util.get_object_properties_dict(vim, moref, None)
self.assertEqual({}, res)
@mock.patch('oslo_vmware.vim_util._get_token') @mock.patch('oslo_vmware.vim_util._get_token')
def test_cancel_retrieval(self, get_token): def test_cancel_retrieval(self, get_token):
token = mock.Mock() token = mock.Mock()