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]

Reply via email to