Port to use keystone sessions and auth plugins
In order to properly support the input parameters we have, we need to go all they way in to full support for keystone plugins and session objects. Amazingly, this is not terribly hard to do. Change-Id: Ia051f7c42aa3c0793cdadd5585e07c3220d5779d
This commit is contained in:
parent
8f1ca24bb8
commit
d3daf5b896
@ -1,6 +1,6 @@
|
||||
pbr>=0.5.21,<1.0
|
||||
|
||||
os-client-config
|
||||
os-client-config>=0.4.0
|
||||
six
|
||||
|
||||
python-novaclient
|
||||
|
@ -17,21 +17,19 @@ import logging
|
||||
import operator
|
||||
import time
|
||||
|
||||
from cinderclient import exceptions as cinder_exceptions
|
||||
from cinderclient.v1 import client as cinder_client
|
||||
import glanceclient
|
||||
from ironicclient import client as ironic_client
|
||||
from ironicclient import exceptions as ironic_exceptions
|
||||
from keystoneclient import client as keystone_client
|
||||
from novaclient import exceptions as nova_exceptions
|
||||
from novaclient.v1_1 import client as nova_client
|
||||
from keystoneclient import auth as ksc_auth
|
||||
from keystoneclient import session as ksc_session
|
||||
from novaclient import client as nova_client
|
||||
from novaclient.v1_1 import floating_ips
|
||||
import os_client_config
|
||||
import pbr.version
|
||||
import swiftclient.client as swift_client
|
||||
import swiftclient.exceptions as swift_exceptions
|
||||
import troveclient.client as trove_client
|
||||
from troveclient import exceptions as trove_exceptions
|
||||
|
||||
|
||||
from shade import meta
|
||||
@ -98,33 +96,38 @@ def _iterate_timeout(timeout, message):
|
||||
class OpenStackCloud(object):
|
||||
|
||||
def __init__(self, cloud, region='',
|
||||
auth_plugin='password',
|
||||
insecure=False, verify=None, cacert=None, cert=None, key=None,
|
||||
image_cache=None, flavor_cache=None, volume_cache=None,
|
||||
debug=False, **kwargs):
|
||||
|
||||
self.name = cloud
|
||||
self.region = region
|
||||
|
||||
self.username = kwargs['username']
|
||||
self.password = kwargs['password']
|
||||
self.project_name = kwargs['project_name']
|
||||
self.auth_url = kwargs['auth_url']
|
||||
self.auth_plugin = auth_plugin
|
||||
self.auth = kwargs.get('auth')
|
||||
|
||||
self.region_name = kwargs.get('region_name', region)
|
||||
self.auth_token = kwargs.get('auth_token', None)
|
||||
self._auth_token = kwargs.get('auth_token', None)
|
||||
|
||||
self.service_types = _get_service_values(kwargs, 'service_type')
|
||||
self.endpoints = _get_service_values(kwargs, 'endpoint')
|
||||
self.api_versions = _get_service_values(kwargs, 'api_version')
|
||||
|
||||
self.user_domain_name = kwargs.get('user_domain_name', None)
|
||||
self.project_domain_name = kwargs.get('project_domain_name', None)
|
||||
|
||||
self.insecure = kwargs.get('insecure', False)
|
||||
self.endpoint_type = kwargs.get('endpoint_type', 'publicURL')
|
||||
self.cert = kwargs.get('cert', None)
|
||||
self.cacert = kwargs.get('cacert', None)
|
||||
self.private = kwargs.get('private', False)
|
||||
|
||||
if verify is None:
|
||||
if insecure:
|
||||
verify = False
|
||||
else:
|
||||
verify = cacert or True
|
||||
self.verify = verify
|
||||
|
||||
if cert and key:
|
||||
cert = (cert, key)
|
||||
self.cert = cert
|
||||
|
||||
self._image_cache = image_cache
|
||||
self._flavor_cache = flavor_cache
|
||||
self._volume_cache = volume_cache
|
||||
@ -133,11 +136,12 @@ class OpenStackCloud(object):
|
||||
|
||||
self.debug = debug
|
||||
|
||||
self._keystone_session = None
|
||||
|
||||
self._nova_client = None
|
||||
self._glance_client = None
|
||||
self._glance_endpoint = None
|
||||
self._ironic_client = None
|
||||
self._keystone_client = None
|
||||
self._cinder_client = None
|
||||
self._trove_client = None
|
||||
self._swift_client = None
|
||||
@ -152,42 +156,22 @@ class OpenStackCloud(object):
|
||||
def get_service_type(self, service):
|
||||
return self.service_types.get(service, service)
|
||||
|
||||
def _get_nova_api_version(self):
|
||||
return self.api_versions['compute']
|
||||
|
||||
@property
|
||||
def nova_client(self):
|
||||
if self._nova_client is None:
|
||||
kwargs = dict(
|
||||
region_name=self.region_name,
|
||||
service_type=self.get_service_type('compute'),
|
||||
insecure=self.insecure,
|
||||
)
|
||||
# Try to use keystone directly first, for potential token reuse
|
||||
try:
|
||||
kwargs['auth_token'] = self.keystone_client.auth_token
|
||||
kwargs['bypass_url'] = self.get_endpoint(
|
||||
self.get_service_type('compute'))
|
||||
except OpenStackCloudException:
|
||||
pass
|
||||
|
||||
# Make the connection
|
||||
self._nova_client = nova_client.Client(
|
||||
self.username,
|
||||
self.password,
|
||||
self.project_name,
|
||||
self.auth_url,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
self._nova_client.authenticate()
|
||||
try:
|
||||
self._nova_client.authenticate()
|
||||
except nova_exceptions.Unauthorized as e:
|
||||
self.log.debug("nova Unauthorized", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Invalid OpenStack Nova credentials: %s" % e.message)
|
||||
except nova_exceptions.AuthorizationFailure as e:
|
||||
self.log.debug("nova AuthorizationFailure", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Unable to authorize user: %s" % e.message)
|
||||
self._nova_client = nova_client.Client(
|
||||
self._get_nova_api_version(),
|
||||
session=self.keystone_session,
|
||||
region_name=self.region_name)
|
||||
except Exception:
|
||||
self.log.debug("Couldn't construct nova object", exc_info=True)
|
||||
raise
|
||||
|
||||
if self._nova_client is None:
|
||||
raise OpenStackCloudException(
|
||||
@ -197,33 +181,46 @@ class OpenStackCloud(object):
|
||||
return self._nova_client
|
||||
|
||||
@property
|
||||
def keystone_client(self):
|
||||
if self._keystone_client is None:
|
||||
def keystone_session(self):
|
||||
if self._keystone_session is None:
|
||||
# keystoneclient does crazy things with logging that are
|
||||
# none of them interesting
|
||||
keystone_logging = logging.getLogger('keystoneclient')
|
||||
keystone_logging.addHandler(logging.NullHandler())
|
||||
|
||||
try:
|
||||
if self.auth_token:
|
||||
self._keystone_client = keystone_client.Client(
|
||||
endpoint=self.auth_url,
|
||||
token=self.auth_token)
|
||||
else:
|
||||
self._keystone_client = keystone_client.Client(
|
||||
username=self.username,
|
||||
password=self.password,
|
||||
project_name=self.project_name,
|
||||
region_name=self.region_name,
|
||||
auth_url=self.auth_url,
|
||||
user_domain_name=self.user_domain_name,
|
||||
project_domain_name=self.project_domain_name)
|
||||
self._keystone_client.authenticate()
|
||||
auth_plugin = ksc_auth.get_plugin_class(self.auth_plugin)
|
||||
except Exception as e:
|
||||
self.log.debug("keystone auth plugin failure", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Could not find auth plugin: {plugin}".format(
|
||||
plugin=self.auth_plugin))
|
||||
try:
|
||||
keystone_auth = auth_plugin(**self.auth)
|
||||
except Exception as e:
|
||||
self.log.debug(
|
||||
"keystone couldn't construct plugin", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Error constructing auth plugin: {plugin}".format(
|
||||
plugin=self.auth_plugin))
|
||||
|
||||
try:
|
||||
self._keystone_session = ksc_session.Session(
|
||||
auth=keystone_auth,
|
||||
verify=self.verify,
|
||||
cert=self.cert)
|
||||
self._auth_token = self._keystone_session.get_token()
|
||||
except Exception as e:
|
||||
self.log.debug("keystone unknown issue", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Error authenticating to the keystone: %s " % e.message)
|
||||
return self._keystone_client
|
||||
return self._keystone_session
|
||||
|
||||
@property
|
||||
def auth_token(self):
|
||||
if not self._auth_token:
|
||||
self._auth_token = self.keystone_session.get_token()
|
||||
return self._auth_token
|
||||
|
||||
def _get_glance_api_version(self):
|
||||
if 'image' in self.api_versions:
|
||||
@ -247,13 +244,13 @@ class OpenStackCloud(object):
|
||||
@property
|
||||
def glance_client(self):
|
||||
if self._glance_client is None:
|
||||
token = self.keystone_client.auth_token
|
||||
token = self.auth_token
|
||||
endpoint = self._get_glance_endpoint()
|
||||
glance_api_version = self._get_glance_api_version()
|
||||
try:
|
||||
self._glance_client = glanceclient.Client(
|
||||
glance_api_version, endpoint, token=token,
|
||||
session=self.keystone_client.session)
|
||||
session=self.keystone_session)
|
||||
except Exception as e:
|
||||
self.log.debug("glance unknown issue", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
@ -266,7 +263,7 @@ class OpenStackCloud(object):
|
||||
@property
|
||||
def swift_client(self):
|
||||
if self._swift_client is None:
|
||||
token = self.keystone_client.auth_token
|
||||
token = self.auth_token
|
||||
endpoint = self.get_endpoint(
|
||||
service_type=self.get_service_type('object-store'))
|
||||
self._swift_client = swift_client.Connection(
|
||||
@ -282,23 +279,8 @@ class OpenStackCloud(object):
|
||||
if self._cinder_client is None:
|
||||
# Make the connection
|
||||
self._cinder_client = cinder_client.Client(
|
||||
self.username,
|
||||
self.password,
|
||||
self.project_name,
|
||||
self.auth_url,
|
||||
region_name=self.region_name,
|
||||
)
|
||||
|
||||
try:
|
||||
self._cinder_client.authenticate()
|
||||
except cinder_exceptions.Unauthorized as e:
|
||||
self.log.debug("cinder Unauthorized", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Invalid OpenStack Cinder credentials.: %s" % e.message)
|
||||
except cinder_exceptions.AuthorizationFailure as e:
|
||||
self.log.debug("cinder AuthorizationFailure", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Unable to authorize user: %s" % e.message)
|
||||
session=self.keystone_session,
|
||||
region_name=self.region_name)
|
||||
|
||||
if self._cinder_client is None:
|
||||
raise OpenStackCloudException(
|
||||
@ -330,25 +312,11 @@ class OpenStackCloud(object):
|
||||
# is one
|
||||
self._trove_client = trove_client.Client(
|
||||
trove_api_version,
|
||||
self.username,
|
||||
self.password,
|
||||
self.project_name,
|
||||
self.auth_url,
|
||||
session=self.keystone_session,
|
||||
region_name=self.region_name,
|
||||
service_type=self.get_service_type('database'),
|
||||
)
|
||||
|
||||
try:
|
||||
self._trove_client.authenticate()
|
||||
except trove_exceptions.Unauthorized as e:
|
||||
self.log.debug("trove Unauthorized", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Invalid OpenStack Trove credentials.: %s" % e.message)
|
||||
except trove_exceptions.AuthorizationFailure as e:
|
||||
self.log.debug("trove AuthorizationFailure", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
"Unable to authorize user: %s" % e.message)
|
||||
|
||||
if self._trove_client is None:
|
||||
raise OpenStackCloudException(
|
||||
"Failed to instantiate Trove client."
|
||||
@ -391,8 +359,10 @@ class OpenStackCloud(object):
|
||||
if service_type in self.endpoints:
|
||||
return self.endpoints[service_type]
|
||||
try:
|
||||
endpoint = self.keystone_client.service_catalog.url_for(
|
||||
service_type=service_type, endpoint_type=self.endpoint_type)
|
||||
endpoint = self.keystone_session.get_endpoint(
|
||||
service_type=service_type,
|
||||
interface=self.endpoint_type,
|
||||
region_name=self.region_name)
|
||||
except Exception as e:
|
||||
self.log.debug("keystone cannot get endpoint", exc_info=True)
|
||||
raise OpenStackCloudException(
|
||||
@ -892,7 +862,7 @@ class OperatorCloud(OpenStackCloud):
|
||||
if self._ironic_client is None:
|
||||
ironic_logging = logging.getLogger('ironicclient')
|
||||
ironic_logging.addHandler(logging.NullHandler())
|
||||
token = self.keystone_client.auth_token
|
||||
token = self.auth_token
|
||||
endpoint = self.get_endpoint(service_type='baremetal')
|
||||
try:
|
||||
self._ironic_client = ironic_client.Client(
|
||||
|
Loading…
x
Reference in New Issue
Block a user