From 6fb1a4e496f6860c800f08e68c05b7e95be36c3b Mon Sep 17 00:00:00 2001 From: Dean Troyer <dtroyer@gmail.com> Date: Wed, 9 May 2012 17:15:43 -0500 Subject: [PATCH] More identity client config * move auth option checking back to OpenStackShell() to keep the shell-level interaction at that level; add checking for token flow options * make identity.client.make_client() configure keystoneclient.v2_0.Client() properly for both password flow and token flow auth * eliminated ClientManager.init_token(), set _service_catalog in __init__() * compute client handles token flow Change-Id: I42481b5424489387798c4ec6d3e2a723ab1e6067 --- openstackclient/common/clientmanager.py | 43 +++++-------------------- openstackclient/compute/client.py | 11 +++++-- openstackclient/identity/client.py | 25 ++++++++------ openstackclient/shell.py | 36 +++++++++++++++++++++ 4 files changed, 68 insertions(+), 47 deletions(-) diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index ab47cc5d54..04aef1dbed 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -21,7 +21,6 @@ class ClientCache(object): def __get__(self, instance, owner): # Tell the ClientManager to login to keystone if self._handle is None: - instance.init_token() self._handle = self.factory(instance) return self._handle @@ -30,9 +29,7 @@ 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 + identity = ClientCache(identity_client.make_client) compute = ClientCache(compute_client.make_client) def __init__(self, token=None, url=None, @@ -55,40 +52,16 @@ class ClientManager(object): self._identity_api_version = identity_api_version self._compute_api_version = compute_api_version self._image_api_version = image_api_version + self._service_catalog = None - def init_token(self): - """Return the auth token and endpoint. - """ - if self._token: - LOG.debug('using existing auth token') - return + # Create the identity client + self.identity - LOG.debug('validating authentication options') - if not self._username: - raise exc.CommandError( - "You must provide a username via" - " either --os-username or env[OS_USERNAME]") + if not self._url: + # Populate other password flow attributes + self._token = self.identity.auth_token + self._service_catalog = self.identity.service_catalog - if not self._password: - raise exc.CommandError( - "You must provide a password via" - " either --os-password or env[OS_PASSWORD]") - - if not (self._tenant_id or self._tenant_name): - raise exc.CommandError( - "You must provide a tenant_id via" - " either --os-tenant-id or via env[OS_TENANT_ID]") - - if not self._auth_url: - raise exc.CommandError( - "You must provide an auth url via" - " either --os-auth-url or via env[OS_AUTH_URL]") - - # 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): diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py index 07f69aa103..30a724e02e 100644 --- a/openstackclient/compute/client.py +++ b/openstackclient/compute/client.py @@ -28,8 +28,13 @@ def make_client(instance): ) # 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 + if instance._url: + # token flow + client.client.management_url = instance._url + else: + # password flow + 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 index be44098eb1..2d823d2bc9 100644 --- a/openstackclient/identity/client.py +++ b/openstackclient/identity/client.py @@ -8,13 +8,20 @@ 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, - ) + if instance._url: + LOG.debug('instantiating identity client: token flow') + client = identity_client.Client( + endpoint=instance._url, + token=instance._token, + ) + else: + LOG.debug('instantiating identity client: password flow') + 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/openstackclient/shell.py b/openstackclient/shell.py index fb5d07272b..83dd1040de 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -27,6 +27,7 @@ from cliff.app import App from cliff.commandmanager import CommandManager from openstackclient.common import clientmanager +from openstackclient.common import exceptions as exc from openstackclient.common import utils @@ -141,6 +142,41 @@ class OpenStackShell(App): 'image': self.options.os_image_api_version, } + self.log.debug('validating authentication options') + if self.options.os_token or self.options.os_url: + # Token flow auth takes priority + if not self.options.os_token: + raise exc.CommandError( + "You must provide a token via" + " either --os-token or env[OS_TOKEN]") + + if not self.options.os_url: + raise exc.CommandError( + "You must provide a service URL via" + " either --os-url or env[OS_URL]") + + else: + # Validate password flow auth + if not self.options.os_username: + raise exc.CommandError( + "You must provide a username via" + " either --os-username or env[OS_USERNAME]") + + if not self.options.os_password: + raise exc.CommandError( + "You must provide a password via" + " either --os-password or env[OS_PASSWORD]") + + if not (self.options.os_tenant_id or self.options.os_tenant_name): + raise exc.CommandError( + "You must provide a tenant_id via" + " either --os-tenant-id or via env[OS_TENANT_ID]") + + if not self.options.os_auth_url: + raise exc.CommandError( + "You must provide an auth url via" + " either --os-auth-url or via env[OS_AUTH_URL]") + self.client_manager = clientmanager.ClientManager( token=self.options.os_token, url=self.options.os_url,