summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Legendre <alegendre@vmware.com>2014-08-15 14:51:58 -0700
committerArnaud Legendre <arnaudleg@gmail.com>2014-08-15 17:35:15 -0700
commite434d1b81976378c0971ab645ea789ca484834a6 (patch)
tree5de801fe6beea469174a89009ceb569fa66fb32b
parent7d78f5ae08037542aa12f051c710653bb313a17e (diff)
downloadoslo-vmware-e434d1b81976378c0971ab645ea789ca484834a6.tar.gz
Add support for the DatastoreURL object
The DatastoreURL object represents a URL that can be used to access a file in a datastore through HTTP(S). The object comes with several methods that makes the manipulation of datastore URLs much simpler. This is needed by Glance and Nova. Change-Id: I6647ef0acb6afa2cacbe81c3fde2db0453c596ca
-rw-r--r--oslo/vmware/objects/datastore.py54
-rw-r--r--tests/objects/test_datastore.py82
2 files changed, 136 insertions, 0 deletions
diff --git a/oslo/vmware/objects/datastore.py b/oslo/vmware/objects/datastore.py
index 9f41a0d..b46d8cd 100644
--- a/oslo/vmware/objects/datastore.py
+++ b/oslo/vmware/objects/datastore.py
@@ -14,6 +14,8 @@
import posixpath
+import six.moves.urllib.parse as urlparse
+
from oslo.vmware.openstack.common.gettextutils import _
from oslo.vmware import vim_util
@@ -209,3 +211,55 @@ class DatastorePath(object):
else:
datastore_name, path = spl
return cls(datastore_name, path.strip())
+
+
+class DatastoreURL(object):
+
+ """Class for representing a URL to HTTP access a file in a datastore.
+
+ This provides various helper methods to access components and useful
+ variants of the datastore URL.
+ """
+
+ def __init__(self, scheme, server, path, datacenter_path, datastore_name):
+ self._scheme = scheme
+ self._server = server
+ self._path = path
+ self._datacenter_path = datacenter_path
+ self._datastore_name = datastore_name
+
+ @classmethod
+ def urlparse(cls, url):
+ scheme, server, path, params, query, fragment = urlparse.urlparse(url)
+ if not query:
+ path = path.split('?')
+ query = path[1]
+ path = path[0]
+ params = urlparse.parse_qs(query)
+ dc_path = params.get('dcPath')
+ if dc_path is not None and len(dc_path) > 0:
+ datacenter_path = dc_path[0]
+ ds_name = params.get('dsName')
+ if ds_name is not None and len(ds_name) > 0:
+ datastore_name = ds_name[0]
+ path = path[len('/folder'):]
+ return cls(scheme, server, path, datacenter_path, datastore_name)
+
+ @property
+ def path(self):
+ return self._path.strip('/')
+
+ @property
+ def datacenter_path(self):
+ return self._datacenter_path
+
+ @property
+ def datastore_name(self):
+ return self._datastore_name
+
+ def __str__(self):
+ params = {'dcPath': self._datacenter_path,
+ 'dsName': self._datastore_name}
+ query = urlparse.urlencode(params)
+ return '%s://%s/folder/%s?%s' % (self._scheme, self._server,
+ self.path, query)
diff --git a/tests/objects/test_datastore.py b/tests/objects/test_datastore.py
index 411c786..e9f1242 100644
--- a/tests/objects/test_datastore.py
+++ b/tests/objects/test_datastore.py
@@ -13,6 +13,7 @@
# under the License.
import mock
+import six.moves.urllib.parse as urlparse
from oslo.vmware.objects import datastore
from oslo.vmware.openstack.common import units
@@ -258,3 +259,84 @@ class DatastorePathTestCase(base.TestCase):
for p in ['bad path', '/a/b/c', 'a/b/c']:
self.assertRaises(IndexError, datastore.DatastorePath.parse, p)
+
+
+class DatastoreURLTestCase(base.TestCase):
+
+ """Test the DatastoreURL object."""
+
+ def test_path_strip(self):
+ scheme = 'https'
+ server = '13.37.73.31'
+ path = 'images/ubuntu-14.04.vmdk'
+ dc_path = 'datacenter-1'
+ ds_name = 'datastore-1'
+ params = {'dcPath': dc_path, 'dsName': ds_name}
+ query = urlparse.urlencode(params)
+ url = datastore.DatastoreURL(scheme, server, path, dc_path, ds_name)
+ expected_url = '%s://%s/folder/%s?%s' % (
+ scheme, server, path, query)
+ self.assertEqual(expected_url, str(url))
+
+ def test_path_lstrip(self):
+ scheme = 'https'
+ server = '13.37.73.31'
+ path = '/images/ubuntu-14.04.vmdk'
+ dc_path = 'datacenter-1'
+ ds_name = 'datastore-1'
+ params = {'dcPath': dc_path, 'dsName': ds_name}
+ query = urlparse.urlencode(params)
+ url = datastore.DatastoreURL(scheme, server, path, dc_path, ds_name)
+ expected_url = '%s://%s/folder/%s?%s' % (
+ scheme, server, path.lstrip('/'), query)
+ self.assertEqual(expected_url, str(url))
+
+ def test_path_rstrip(self):
+ scheme = 'https'
+ server = '13.37.73.31'
+ path = 'images/ubuntu-14.04.vmdk/'
+ dc_path = 'datacenter-1'
+ ds_name = 'datastore-1'
+ params = {'dcPath': dc_path, 'dsName': ds_name}
+ query = urlparse.urlencode(params)
+ url = datastore.DatastoreURL(scheme, server, path, dc_path, ds_name)
+ expected_url = '%s://%s/folder/%s?%s' % (
+ scheme, server, path.rstrip('/'), query)
+ self.assertEqual(expected_url, str(url))
+
+ def test_urlparse(self):
+ dc_path = 'datacenter-1'
+ ds_name = 'datastore-1'
+ params = {'dcPath': dc_path, 'dsName': ds_name}
+ query = urlparse.urlencode(params)
+ url = 'https://13.37.73.31/folder/images/aa.vmdk?%s' % query
+ ds_url = datastore.DatastoreURL.urlparse(url)
+ self.assertEqual(url, str(ds_url))
+
+ def test_datastore_name(self):
+ dc_path = 'datacenter-1'
+ ds_name = 'datastore-1'
+ params = {'dcPath': dc_path, 'dsName': ds_name}
+ query = urlparse.urlencode(params)
+ url = 'https://13.37.73.31/folder/images/aa.vmdk?%s' % query
+ ds_url = datastore.DatastoreURL.urlparse(url)
+ self.assertEqual(ds_name, ds_url.datastore_name)
+
+ def test_datacenter_path(self):
+ dc_path = 'datacenter-1'
+ ds_name = 'datastore-1'
+ params = {'dcPath': dc_path, 'dsName': ds_name}
+ query = urlparse.urlencode(params)
+ url = 'https://13.37.73.31/folder/images/aa.vmdk?%s' % query
+ ds_url = datastore.DatastoreURL.urlparse(url)
+ self.assertEqual(dc_path, ds_url.datacenter_path)
+
+ def test_path(self):
+ dc_path = 'datacenter-1'
+ ds_name = 'datastore-1'
+ params = {'dcPath': dc_path, 'dsName': ds_name}
+ path = 'images/aa.vmdk'
+ query = urlparse.urlencode(params)
+ url = 'https://13.37.73.31/folder/%s?%s' % (path, query)
+ ds_url = datastore.DatastoreURL.urlparse(url)
+ self.assertEqual(path, ds_url.path)