summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-08-15 18:45:15 +0000
committerGerrit Code Review <review@openstack.org>2014-08-15 18:45:15 +0000
commit7d78f5ae08037542aa12f051c710653bb313a17e (patch)
treeb16c67d9186690a8c484300dade3f063a7217778
parent5ec923e2bde9d52281be388452f37bdf924c0cc6 (diff)
parente5c22fa8571c447ad9753980340ce2c6efa18a1d (diff)
downloadoslo-vmware-7d78f5ae08037542aa12f051c710653bb313a17e.tar.gz
Merge "Add methods to the Datastore objects"
-rw-r--r--oslo/vmware/objects/datastore.py46
-rw-r--r--tests/objects/test_datastore.py69
2 files changed, 115 insertions, 0 deletions
diff --git a/oslo/vmware/objects/datastore.py b/oslo/vmware/objects/datastore.py
index 83b09a4..9f41a0d 100644
--- a/oslo/vmware/objects/datastore.py
+++ b/oslo/vmware/objects/datastore.py
@@ -15,6 +15,7 @@
import posixpath
from oslo.vmware.openstack.common.gettextutils import _
+from oslo.vmware import vim_util
class Datastore(object):
@@ -70,6 +71,51 @@ class Datastore(object):
def __str__(self):
return '[%s]' % self._name
+ def get_summary(self, session):
+ """Get datastore summary.
+
+ :param datastore: Reference to the datastore
+ :return: 'summary' property of the datastore
+ """
+ return session.invoke_api(vim_util, 'get_object_property',
+ session.vim, self.ref, 'summary')
+
+ def get_connected_hosts(self, session):
+ """Get a list of usable (accessible, mounted, read-writable) hosts where
+ the datastore is mounted.
+
+ :param: session: session
+ :return: list of HostSystem managed object references
+ """
+ hosts = []
+ summary = self.get_summary()
+ if not summary.accessible:
+ return hosts
+ host_mounts = session.invoke_api(vim_util, 'get_object_property',
+ session.vim, self.ref, 'host')
+ if not hasattr(host_mounts, 'DatastoreHostMount'):
+ return hosts
+ for host_mount in host_mounts.DatastoreHostMount:
+ if self.is_datastore_mount_usable(host_mount.mountInfo):
+ hosts.append(host_mount.key)
+ return hosts
+
+ @staticmethod
+ def is_datastore_mount_usable(mount_info):
+ """Check if a datastore is usable as per the given mount info.
+
+ The datastore is considered to be usable for a host only if it is
+ writable, mounted and accessible.
+
+ :param mount_info: HostMountInfo data object
+ :return: True if datastore is usable
+ """
+ writable = mount_info.accessMode == 'readWrite'
+ mounted = getattr(mount_info, 'mounted', True)
+ accessible = getattr(mount_info, 'accessible', False)
+
+ return writable and mounted and accessible
+
class DatastorePath(object):
diff --git a/tests/objects/test_datastore.py b/tests/objects/test_datastore.py
index 7044cfb..411c786 100644
--- a/tests/objects/test_datastore.py
+++ b/tests/objects/test_datastore.py
@@ -12,11 +12,29 @@
# License for the specific language governing permissions and limitations
# under the License.
+import mock
+
from oslo.vmware.objects import datastore
from oslo.vmware.openstack.common import units
+from oslo.vmware import vim_util
from tests import base
+class HostMount(object):
+
+ def __init__(self, key, mountInfo):
+ self.key = key
+ self.mountInfo = mountInfo
+
+
+class MountInfo(object):
+
+ def __init__(self, accessMode, mounted, accessible):
+ self.accessMode = accessMode
+ self.mounted = mounted
+ self.accessible = accessible
+
+
class DatastoreTestCase(base.TestCase):
"""Test the Datastore object."""
@@ -49,6 +67,57 @@ class DatastoreTestCase(base.TestCase):
ds_path = ds.build_path("some_dir", "foo.vmdk")
self.assertEqual('[ds_name] some_dir/foo.vmdk', str(ds_path))
+ def test_get_summary(self):
+ ds_ref = vim_util.get_moref('ds-0', 'Datastore')
+ ds = datastore.Datastore(ds_ref, 'ds-name')
+ summary = mock.sentinel.summary
+ session = mock.Mock()
+ session.invoke_api = mock.Mock()
+ session.invoke_api.return_value = summary
+ ret = ds.get_summary(session)
+ self.assertEqual(summary, ret)
+ session.invoke_api.assert_called_once_with(vim_util,
+ 'get_object_property',
+ session.vim,
+ ds.ref, 'summary')
+
+ def test_get_connected_hosts(self):
+ session = mock.Mock()
+ ds_ref = vim_util.get_moref('ds-0', 'Datastore')
+ ds = datastore.Datastore(ds_ref, 'ds-name')
+ ds.get_summary = mock.Mock()
+ ds.get_summary.return_value.accessible = False
+ self.assertEqual([], ds.get_connected_hosts(session))
+ ds.get_summary.return_value.accessible = True
+ m1 = HostMount("m1", MountInfo('readWrite', True, True))
+ m2 = HostMount("m2", MountInfo('read', True, True))
+ m3 = HostMount("m3", MountInfo('readWrite', False, True))
+ m4 = HostMount("m4", MountInfo('readWrite', True, False))
+
+ class Prop(object):
+ DatastoreHostMount = [m1, m2, m3, m4]
+ session.invoke_api = mock.Mock()
+ session.invoke_api.return_value = Prop()
+ hosts = ds.get_connected_hosts(session)
+ self.assertEqual(1, len(hosts))
+ self.assertEqual("m1", hosts.pop())
+
+ def test_is_datastore_mount_usable(self):
+ m = MountInfo('readWrite', True, True)
+ self.assertTrue(datastore.Datastore.is_datastore_mount_usable(m))
+ m = MountInfo('read', True, True)
+ self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m))
+ m = MountInfo('readWrite', False, True)
+ self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m))
+ m = MountInfo('readWrite', True, False)
+ self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m))
+ m = MountInfo('readWrite', False, False)
+ self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m))
+ m = MountInfo('readWrite', None, None)
+ self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m))
+ m = MountInfo('readWrite', None, True)
+ self.assertFalse(datastore.Datastore.is_datastore_mount_usable(m))
+
class DatastorePathTestCase(base.TestCase):