Merge branch 'trunk' into openstack-identity-fix
diff --git a/libcloud/common/openstack_identity.py b/libcloud/common/openstack_identity.py
index ecc0efd..6a26988 100644
--- a/libcloud/common/openstack_identity.py
+++ b/libcloud/common/openstack_identity.py
@@ -776,7 +776,7 @@
             # method.
             return action
 
-        return request_path
+        return super(OpenStackIdentityConnection, self).morph_action_hook(action=action)
 
     def add_default_headers(self, headers):
         headers["Accept"] = "application/json"
diff --git a/libcloud/compute/drivers/cloudwatt.py b/libcloud/compute/drivers/cloudwatt.py
index 6039fbe..3032b67 100644
--- a/libcloud/compute/drivers/cloudwatt.py
+++ b/libcloud/compute/drivers/cloudwatt.py
@@ -47,6 +47,16 @@
         self._ex_tenant_id = kwargs.pop("ex_tenant_id")
         super(CloudwattAuthConnection, self).__init__(*args, **kwargs)
 
+    def morph_action_hook(self, action):
+        (_, _, _, request_path) = self._tuple_from_url(self.auth_url)
+
+        if request_path == "":
+            # No path is provided in the auth_url, use action passed to this
+            # method.
+            return action
+
+        return request_path
+
     def authenticate(self, force=False):
         reqbody = json.dumps(
             {
diff --git a/libcloud/compute/drivers/kili.py b/libcloud/compute/drivers/kili.py
index 33ebba2..c846e7f 100644
--- a/libcloud/compute/drivers/kili.py
+++ b/libcloud/compute/drivers/kili.py
@@ -26,7 +26,7 @@
 
 ENDPOINT_ARGS = {"service_type": "compute", "name": "nova", "region": "RegionOne"}
 
-AUTH_URL = "https://api.kili.io/keystone/v2.0/tokens"
+AUTH_URL = "https://api.kili.io/keystone"
 
 
 class KiliCloudConnection(OpenStack_1_1_Connection):
diff --git a/libcloud/test/common/test_openstack_identity.py b/libcloud/test/common/test_openstack_identity.py
index 7e077c9..4b65407 100644
--- a/libcloud/test/common/test_openstack_identity.py
+++ b/libcloud/test/common/test_openstack_identity.py
@@ -78,32 +78,29 @@
             ),
         ]
 
-        APPEND = 0
-        NOTAPPEND = 1
-
         auth_urls = [
-            ("https://auth.api.example.com", APPEND, ""),
-            ("https://auth.api.example.com/", NOTAPPEND, "/"),
-            ("https://auth.api.example.com/foo/bar", NOTAPPEND, "/foo/bar"),
-            ("https://auth.api.example.com/foo/bar/", NOTAPPEND, "/foo/bar/"),
+            ("https://auth.api.example.com", ""),
+            ("https://auth.api.example.com/", "/"),
+            ("https://auth.api.example.com/foo/bar", "/foo/bar"),
+            ("https://auth.api.example.com/foo/bar/", "/foo/bar/"),
         ]
 
         actions = {
-            "1.0": "/v1.0",
-            "1.1": "/v1.1/auth",
-            "2.0": "/v2.0/tokens",
-            "2.0_apikey": "/v2.0/tokens",
-            "2.0_password": "/v2.0/tokens",
-            "3.x_password": "/v3/auth/tokens",
-            "3.x_appcred": "/v3/auth/tokens",
-            "3.x_oidc_access_token": "/v3/OS-FEDERATION/identity_providers/user_name/protocols/tenant-name/auth",
+            "1.0": "{url_path}/v1.0",
+            "1.1": "{url_path}/v1.1/auth",
+            "2.0": "{url_path}/v2.0/tokens",
+            "2.0_apikey": "{url_path}/v2.0/tokens",
+            "2.0_password": "{url_path}/v2.0/tokens",
+            "3.x_password": "{url_path}/v3/auth/tokens",
+            "3.x_appcred": "{url_path}/v3/auth/tokens",
+            "3.x_oidc_access_token": "{url_path}/v3/OS-FEDERATION/identity_providers/user_name/protocols/tenant-name/auth",
         }
 
         user_id = OPENSTACK_PARAMS[0]
         key = OPENSTACK_PARAMS[1]
 
         for (auth_version, mock_http_class, kwargs) in tuples:
-            for (url, should_append_default_path, expected_path) in auth_urls:
+            for (url, url_path) in auth_urls:
                 connection = self._get_mock_connection(
                     mock_http_class=mock_http_class, auth_url=url
                 )
@@ -123,10 +120,14 @@
                 except Exception:
                     pass
 
-                if should_append_default_path == APPEND:
-                    expected_path = actions[auth_version]
+                expected_path = (
+                    actions[auth_version].format(url_path=url_path).replace("//", "/")
+                )
 
-                self.assertEqual(osa.action, expected_path)
+                self.assertEqual(
+                    osa.action,
+                    expected_path,
+                )
 
     def test_basic_authentication(self):
         tuples = [
diff --git a/libcloud/test/compute/test_kili.py b/libcloud/test/compute/test_kili.py
index ee9baa0..7824a1d 100644
--- a/libcloud/test/compute/test_kili.py
+++ b/libcloud/test/compute/test_kili.py
@@ -23,7 +23,7 @@
     kwargs = self.openstack_connection_kwargs()
     kwargs["get_endpoint_args"] = ENDPOINT_ARGS
     # Remove keystone from the URL path so that the openstack base tests work
-    kwargs["ex_force_auth_url"] = "https://api.kili.io/v2.0/tokens"
+    kwargs["ex_force_auth_url"] = "https://api.kili.io/"
     kwargs["ex_tenant_name"] = self.tenant_name
 
     return kwargs