Updated Branches: refs/heads/trunk 2c0f95aba -> 783de479c
Allow user to pass 'url' argument to the CloudStack driver constructor. Part of LIBCLOUD-440. Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/783de479 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/783de479 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/783de479 Branch: refs/heads/trunk Commit: 783de479ccda32498b72b512f34ffc2b8eca80ec Parents: 2c0f95a Author: Tomaz Muraus <[email protected]> Authored: Wed Nov 20 11:45:44 2013 +0100 Committer: Tomaz Muraus <[email protected]> Committed: Wed Nov 20 11:55:48 2013 +0100 ---------------------------------------------------------------------- libcloud/compute/drivers/cloudstack.py | 34 +++++++++++++++++++----- libcloud/test/compute/test_cloudstack.py | 38 ++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/783de479/libcloud/compute/drivers/cloudstack.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/cloudstack.py b/libcloud/compute/drivers/cloudstack.py index 819fcda..6870bf9 100644 --- a/libcloud/compute/drivers/cloudstack.py +++ b/libcloud/compute/drivers/cloudstack.py @@ -19,6 +19,7 @@ import os import base64 from libcloud.utils.py3 import b +from libcloud.utils.py3 import urlparse from libcloud.compute.providers import Provider from libcloud.common.cloudstack import CloudStackDriverMixIn @@ -207,17 +208,37 @@ class CloudStackNodeDriver(CloudStackDriverMixIn, NodeDriver): } def __init__(self, key, secret=None, secure=True, host=None, - path=None, port=None, *args, **kwargs): + path=None, port=None, url=None, *args, **kwargs): """ - @inherits: :class:`NodeDriver.__init__` + :inherits: :class:`NodeDriver.__init__` :param host: The host where the API can be reached. (required) :type host: ``str`` - :param path: The host where the API can be reached. (required) + :param path: The path where the API can be reached. (required) :type path: ``str`` + + :param url: Full URL to the API endpoint. Mutually exclusive with host + and path argument. + :type url: ``str`` """ - host = host if host else self.host + if url: + parsed = urlparse.urlparse(url) + + path = parsed.path + + scheme = parsed.scheme + split = parsed.netloc.split(':') + + if len(split) == 1: + # No port provided, use the default one + host = parsed.netloc + port = 443 if scheme == 'https' else 80 + else: + host = split[0] + port = int(split[1]) + else: + host = host if host else self.host if path is not None: self.path = path @@ -226,8 +247,9 @@ class CloudStackNodeDriver(CloudStackDriverMixIn, NodeDriver): self.host = host if (self.type == Provider.CLOUDSTACK) and (not host or not path): - raise Exception('When instantiating CloudStack driver directly ' + - 'you also need to provide host and path argument') + raise Exception('When instantiating CloudStack driver directly ' + 'you also need to provide url or host and path ' + 'argument') NodeDriver.__init__(self, key=key, secret=secret, secure=secure, host=host, port=port) http://git-wip-us.apache.org/repos/asf/libcloud/blob/783de479/libcloud/test/compute/test_cloudstack.py ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/test_cloudstack.py b/libcloud/test/compute/test_cloudstack.py index dde40db..c3721dc 100644 --- a/libcloud/test/compute/test_cloudstack.py +++ b/libcloud/test/compute/test_cloudstack.py @@ -48,9 +48,36 @@ class CloudStackNodeDriverTest(unittest.TestCase, TestCaseMixin): CloudStackMockHttp.fixture_tag = 'default' self.driver.connection.poll_interval = 0.0 - def test_user_must_provide_host_and_path(self): - expected_msg = 'When instantiating CloudStack driver directly ' + \ - 'you also need to provide host and path argument' + def test_driver_instantiation(self): + urls = [ + 'http://api.exoscale.ch/compute1', # http, default port + 'https://api.exoscale.ch/compute2', # https, default port + 'http://api.exoscale.ch:8888/compute3', # https, custom port + 'https://api.exoscale.ch:8787/compute4', # https, custom port + 'https://api.test.com/compute/endpoint' # https, default port + ] + + expected_values = [ + {'host': 'api.exoscale.ch', 'port': 80, 'path': '/compute1'}, + {'host': 'api.exoscale.ch', 'port': 443, 'path': '/compute2'}, + {'host': 'api.exoscale.ch', 'port': 8888, 'path': '/compute3'}, + {'host': 'api.exoscale.ch', 'port': 8787, 'path': '/compute4'}, + {'host': 'api.test.com', 'port': 443, 'path': '/compute/endpoint'} + ] + + cls = get_driver(Provider.CLOUDSTACK) + + for url, expected in zip(urls, expected_values): + driver = cls('key', 'secret', url=url) + + self.assertEqual(driver.host, expected['host']) + self.assertEqual(driver.path, expected['path']) + self.assertEqual(driver.connection.port, expected['port']) + + def test_user_must_provide_host_and_path_or_url(self): + expected_msg = ('When instantiating CloudStack driver directly ' + 'you also need to provide url or host and path ' + 'argument') cls = get_driver(Provider.CLOUDSTACK) self.assertRaisesRegexp(Exception, expected_msg, cls, @@ -61,6 +88,11 @@ class CloudStackNodeDriverTest(unittest.TestCase, TestCaseMixin): except Exception: self.fail('host and path provided but driver raised an exception') + try: + cls('key', 'secret', url='https://api.exoscale.ch/compute') + except Exception: + self.fail('url provided but driver raised an exception') + def test_create_node_immediate_failure(self): size = self.driver.list_sizes()[0] image = self.driver.list_images()[0]
