From 70b3246a1983700736b7ce4c83e9381d987cc598 Mon Sep 17 00:00:00 2001
From: Dean Troyer <dtroyer@gmail.com>
Date: Fri, 4 May 2012 12:28:35 -0500
Subject: [PATCH] Add Identity to ClientManager

* Make the Identity client in identity.client.make_client()
* Auth via ClientManager.identity
* Skip extra auth roundtrip in compute client

Change-Id: I0190639e38f83997c233195f6cc27ff3afdfba10
---
 openstackclient/common/clientmanager.py | 24 +++++++++++-------------
 openstackclient/compute/client.py       |  9 ++++++---
 openstackclient/identity/client.py      | 20 ++++++++++++++++++++
 tools/pip-requires                      |  3 ++-
 4 files changed, 39 insertions(+), 17 deletions(-)
 create mode 100644 openstackclient/identity/client.py

diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index 66d3ce7685..ab47cc5d54 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -5,8 +5,7 @@ import logging
 
 from openstackclient.common import exceptions as exc
 from openstackclient.compute import client as compute_client
-
-from keystoneclient.v2_0 import client as keystone_client
+from openstackclient.identity import client as identity_client
 
 LOG = logging.getLogger(__name__)
 
@@ -31,6 +30,9 @@ class ClientManager(object):
     """Manages access to API clients, including authentication.
     """
 
+    # Identity client is instantiated in init_token()
+    # otherwise we have a recursion problem
+    identity = None
     compute = ClientCache(compute_client.make_client)
 
     def __init__(self, token=None, url=None,
@@ -82,15 +84,11 @@ class ClientManager(object):
                 "You must provide an auth url via"
                 " either --os-auth-url or via env[OS_AUTH_URL]")
 
-        kwargs = {
-            'username': self._username,
-            'password': self._password,
-            'tenant_id': self._tenant_id,
-            'tenant_name': self._tenant_name,
-            'auth_url': self._auth_url
-        }
-        self._auth_client = keystone_client.Client(**kwargs)
-        self._token = self._auth_client.auth_token
+        # Get an Identity client and keep a token and catalog
+        if not self.identity:
+            self.identity = identity_client.make_client(self)
+        self._token = self.identity.auth_token
+        self._service_catalog = self.identity.service_catalog
         return
 
     def get_endpoint_for_service_type(self, service_type):
@@ -98,8 +96,8 @@ class ClientManager(object):
         """
         # See if we are using password flow auth, i.e. we have a
         # service catalog to select endpoints from
-        if self._auth_client and self._auth_client.service_catalog:
-            endpoint = self._auth_client.service_catalog.url_for(
+        if self._service_catalog:
+            endpoint = self._service_catalog.url_for(
                 service_type=service_type)
         else:
             # Hope we were given the correct URL.
diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py
index ef0ceb3816..07f69aa103 100644
--- a/openstackclient/compute/client.py
+++ b/openstackclient/compute/client.py
@@ -9,8 +9,6 @@ def make_client(instance):
     """Returns a compute service client.
     """
     LOG.debug('instantiating compute client')
-    # FIXME(dhellmann): Where is the endpoint value used?
-    # url = instance.get_endpoint_for_service_type('compute')
     client = nova_client.Client(
         version=instance._compute_api_version,
         username=instance._username,
@@ -28,5 +26,10 @@ def make_client(instance):
         # FIXME(dhellmann): what is service_name?
         service_name='',
         )
-    client.authenticate()
+
+    # Populate the Nova client to skip another auth query to Identity
+    client.client.management_url = instance.get_endpoint_for_service_type(
+        'compute')
+    client.client.service_catalog = instance._service_catalog
+    client.client.auth_token = instance._token
     return client
diff --git a/openstackclient/identity/client.py b/openstackclient/identity/client.py
new file mode 100644
index 0000000000..be44098eb1
--- /dev/null
+++ b/openstackclient/identity/client.py
@@ -0,0 +1,20 @@
+import logging
+
+from keystoneclient.v2_0 import client as identity_client
+
+LOG = logging.getLogger(__name__)
+
+
+def make_client(instance):
+    """Returns an identity service client.
+    """
+    LOG.debug('instantiating identity client')
+    client = identity_client.Client(
+        username=instance._username,
+        password=instance._password,
+        tenant_name=instance._tenant_name,
+        tenant_id=instance._tenant_id,
+        auth_url=instance._auth_url,
+        region_name=instance._region_name,
+    )
+    return client
diff --git a/tools/pip-requires b/tools/pip-requires
index 738b5f5348..8d07fd36be 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -6,4 +6,5 @@ mock
 prettytable
 simplejson
 -e git://github.com/openstack/python-keystoneclient.git#egg=python-keystoneclient
--e git+https://github.com/openstack/python-novaclient.git#egg=python_novaclient
\ No newline at end of file
+-e git+https://github.com/openstack/python-novaclient.git#egg=python_novaclient
+