Migrate from keystoneclient to keystoneauth

keystoneauth was split out last cycle as a library specifically to deal
with doing auth functions so that people who do not need to do keystone
CRUD operations can just consume only the auth session parts. As part
of modernizing keystone interactions, use keystoneauth instead of
keystoneclient.

A change to tests was made to stop checking how often the keystone auth
session is called. This could be broken in the future depending on how
the keystoneauth1 loader works. It is incorrect to mock out and check
how often Session is called when nova has no direct control over this.
The number of times barbican client is called is correctly in the
control of Nova and will continue to be tested.

bp: keystoneclient-to-keystoneauth

Co-Authored-By: Morgan Fainberg <morgan.fainberg@gmail.com>
Depends-On: I1f754a9a949ef92f4e427a91bbd1b1e73e86c8c4
Change-Id: I09a5da761bdc02c83b087f3cec40b7fa022a7a63
This commit is contained in:
Monty Taylor 2015-12-05 00:38:09 -05:00 committed by Morgan Fainberg
parent df0fca62cf
commit f19ddc4c50
8 changed files with 44 additions and 60 deletions

View File

@ -40,7 +40,7 @@ import eventlet.event
from eventlet import greenthread
import eventlet.semaphore
import eventlet.timeout
from keystoneclient import exceptions as keystone_exception
from keystoneauth1 import exceptions as keystone_exception
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging as messaging

View File

@ -19,8 +19,8 @@
import copy
from keystoneclient import auth
from keystoneclient import service_catalog
from keystoneauth1.access import service_catalog as ksa_service_catalog
from keystoneauth1 import plugin
from oslo_context import context
from oslo_db.sqlalchemy import enginefacade
from oslo_log import log as logging
@ -35,8 +35,8 @@ from nova import utils
LOG = logging.getLogger(__name__)
class _ContextAuthPlugin(auth.BaseAuthPlugin):
"""A keystoneclient auth plugin that uses the values from the Context.
class _ContextAuthPlugin(plugin.BaseAuthPlugin):
"""A keystoneauth auth plugin that uses the values from the Context.
Ideally we would use the plugin provided by auth_token middleware however
this plugin isn't serialized yet so we construct one from the serialized
@ -47,8 +47,7 @@ class _ContextAuthPlugin(auth.BaseAuthPlugin):
super(_ContextAuthPlugin, self).__init__()
self.auth_token = auth_token
sc = {'serviceCatalog': sc}
self.service_catalog = service_catalog.ServiceCatalogV2(sc)
self.service_catalog = ksa_service_catalog.ServiceCatalogV2(sc)
def get_token(self, *args, **kwargs):
return self.auth_token
@ -57,7 +56,7 @@ class _ContextAuthPlugin(auth.BaseAuthPlugin):
region_name=None, service_name=None, **kwargs):
return self.service_catalog.url_for(service_type=service_type,
service_name=service_name,
endpoint_type=interface,
interface=interface,
region_name=region_name)

View File

@ -22,7 +22,8 @@ import base64
import binascii
from barbicanclient import client as barbican_client
from keystoneclient import session
from keystoneauth1 import loading as ks_loading
from keystoneauth1 import session
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
@ -52,7 +53,7 @@ BARBICAN_OPT_GROUP = 'barbican'
CONF.register_opts(barbican_opts, group=BARBICAN_OPT_GROUP)
session.Session.register_conf_options(CONF, BARBICAN_OPT_GROUP)
ks_loading.register_session_conf_options(CONF, BARBICAN_OPT_GROUP)
LOG = logging.getLogger(__name__)
@ -89,7 +90,7 @@ class BarbicanKeyManager(key_mgr.KeyManager):
return self._barbican_client
try:
_SESSION = session.Session.load_from_conf_options(
_SESSION = ks_loading.load_session_from_conf_options(
CONF,
BARBICAN_OPT_GROUP)

View File

@ -19,12 +19,9 @@ import copy
import time
import uuid
from keystoneclient import auth
from keystoneclient.auth import token_endpoint
from keystoneclient import session
from keystoneauth1 import loading as ks_loading
from neutronclient.common import exceptions as neutron_client_exc
from neutronclient.v2_0 import client as clientv20
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
@ -72,9 +69,9 @@ deprecations = {'cafile': [cfg.DeprecatedOpt('ca_certificates_file',
'timeout': [cfg.DeprecatedOpt('url_timeout',
group=NEUTRON_GROUP)]}
_neutron_options = session.Session.register_conf_options(
_neutron_options = ks_loading.register_session_conf_options(
CONF, NEUTRON_GROUP, deprecated_opts=deprecations)
auth.register_conf_options(CONF, NEUTRON_GROUP)
ks_loading.register_auth_conf_options(CONF, NEUTRON_GROUP)
CONF.import_opt('default_floating_pool', 'nova.network.floating_ips')
@ -90,12 +87,12 @@ _ADMIN_AUTH = None
def list_opts():
list = copy.deepcopy(_neutron_options)
list.insert(0, auth.get_common_conf_options()[0])
list.insert(0, ks_loading.get_auth_common_conf_options()[0])
# NOTE(dims): There are a lot of auth plugins, we just generate
# the config options for a few common ones
plugins = ['password', 'v2password', 'v3password']
for name in plugins:
for plugin_option in auth.get_plugin_class(name).get_options():
for plugin_option in ks_loading.get_plugin_loader(name).get_options():
found = False
for option in list:
if option.name == plugin_option.name:
@ -116,7 +113,7 @@ def reset_state():
def _load_auth_plugin(conf):
auth_plugin = auth.load_from_conf_options(conf, NEUTRON_GROUP)
auth_plugin = ks_loading.load_auth_from_conf_options(conf, NEUTRON_GROUP)
if auth_plugin:
return auth_plugin
@ -136,25 +133,13 @@ def get_client(context, admin=False):
auth_plugin = None
if not _SESSION:
_SESSION = session.Session.load_from_conf_options(CONF, NEUTRON_GROUP)
_SESSION = ks_loading.load_session_from_conf_options(
CONF, NEUTRON_GROUP)
if admin or (context.is_admin and not context.auth_token):
# NOTE(jamielennox): The theory here is that we maintain one
# authenticated admin auth globally. The plugin will authenticate
# internally (not thread safe) and on demand so we extract a current
# auth plugin from it (whilst locked). This may or may not require
# reauthentication. We then use the static token plugin to issue the
# actual request with that current token in a thread safe way.
if not _ADMIN_AUTH:
_ADMIN_AUTH = _load_auth_plugin(CONF)
with lockutils.lock('neutron_admin_auth_token_lock'):
# FIXME(jamielennox): We should also retrieve the endpoint from the
# catalog here rather than relying on setting it in CONF.
auth_token = _ADMIN_AUTH.get_token(_SESSION)
# FIXME(jamielennox): why aren't we using the service catalog?
auth_plugin = token_endpoint.Token(CONF.neutron.url, auth_token)
auth_plugin = _ADMIN_AUTH
elif context.auth_token:
auth_plugin = context.get_auth_plugin()

View File

@ -224,38 +224,33 @@ class BarbicanKeyManagerTestCase(test_key_mgr.KeyManagerTestCase):
self.assertRaises(exception.Forbidden,
self.key_mgr.store_key, None, None)
@mock.patch('keystoneclient.session.Session')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('barbicanclient.client.Client')
def test_get_barbican_client_new(self, mock_barbican, mock_keystone):
manager = self._create_key_manager()
manager._get_barbican_client(self.ctxt)
self.assertEqual(mock_keystone.call_count, 1)
self.assertEqual(mock_barbican.call_count, 1)
@mock.patch('keystoneclient.session.Session')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('barbicanclient.client.Client')
def test_get_barbican_client_reused(self, mock_barbican, mock_keystone):
manager = self._create_key_manager()
manager._get_barbican_client(self.ctxt)
self.assertEqual(mock_keystone.call_count, 1)
self.assertEqual(mock_barbican.call_count, 1)
manager._get_barbican_client(self.ctxt)
self.assertEqual(mock_keystone.call_count, 1)
self.assertEqual(mock_barbican.call_count, 1)
@mock.patch('keystoneclient.session.Session')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('barbicanclient.client.Client')
def test_get_barbican_client_not_reused(self, mock_barbican,
mock_keystone):
manager = self._create_key_manager()
manager._get_barbican_client(self.ctxt)
self.assertEqual(mock_keystone.call_count, 1)
self.assertEqual(mock_barbican.call_count, 1)
ctxt2 = mock.MagicMock()
ctxt2.auth_token = "fake_token2"
ctxt2.project = "fake_project2"
manager._get_barbican_client(ctxt2)
self.assertEqual(mock_keystone.call_count, 2)
self.assertEqual(mock_barbican.call_count, 2)
def test_get_barbican_client_null_context(self):

View File

@ -18,8 +18,8 @@ import collections
import copy
import uuid
from keystoneclient.auth import base as ksc_auth_base
from keystoneclient.fixture import V2Token
from keystoneauth1.fixture import V2Token
from keystoneauth1 import loading as ks_loading
import mock
from mox3 import mox
from neutronclient.common import exceptions
@ -3937,8 +3937,8 @@ class TestNeutronClientForAdminScenarios(test.NoDBTestCase):
# these are run (due to glonal conf object) and not be fully
# representative of a "clean" slate at the start of a test.
self.config_fixture = self.useFixture(config_fixture.Config())
plugin_class = ksc_auth_base.get_plugin_class('v2password')
plugin_class.register_conf_options(self.config_fixture, 'neutron')
oslo_opts = ks_loading.get_auth_plugin_conf_options('v2password')
self.config_fixture.register_opts(oslo_opts, 'neutron')
@requests_mock.mock()
def _test_get_client_for_admin(self, req_mock,
@ -3949,7 +3949,7 @@ class TestNeutronClientForAdminScenarios(test.NoDBTestCase):
req_mock.post(auth_url + '/tokens', json=token_resp)
self.flags(url='http://anyhost/', group='neutron')
self.flags(auth_plugin='v2password', group='neutron')
self.flags(auth_type='v2password', group='neutron')
self.flags(auth_url=auth_url, group='neutron')
self.flags(timeout=30, group='neutron')
if use_id:
@ -3994,11 +3994,15 @@ class TestNeutronClientForAdminScenarios(test.NoDBTestCase):
self.assertIsNone(admin_auth.tenant_id)
self.assertIsNone(admin_auth.user_id)
self.assertEqual(CONF.neutron.timeout, neutronapi._SESSION.timeout)
self.assertEqual(CONF.neutron.timeout,
neutronapi._SESSION.timeout)
self.assertEqual(token_value, context_client.httpclient.auth.token)
self.assertEqual(CONF.neutron.url,
context_client.httpclient.auth.endpoint)
self.assertEqual(
token_value,
context_client.httpclient.auth.get_token(neutronapi._SESSION))
self.assertEqual(
CONF.neutron.url,
context_client.httpclient.get_endpoint())
def test_get_client_for_admin(self):
self._test_get_client_for_admin()

View File

@ -25,8 +25,8 @@ import sys
from cinderclient import client as cinder_client
from cinderclient import exceptions as cinder_exception
from cinderclient.v1 import client as v1_client
from keystoneclient import exceptions as keystone_exception
from keystoneclient import session
from keystoneauth1 import exceptions as keystone_exception
from keystoneauth1 import loading as ks_loading
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
@ -83,9 +83,9 @@ deprecated = {'timeout': [cfg.DeprecatedOpt('http_timeout',
'insecure': [cfg.DeprecatedOpt('api_insecure',
group=CINDER_OPT_GROUP)]}
session.Session.register_conf_options(CONF,
CINDER_OPT_GROUP,
deprecated_opts=deprecated)
ks_loading.register_session_conf_options(CONF,
CINDER_OPT_GROUP,
deprecated_opts=deprecated)
LOG = logging.getLogger(__name__)
@ -105,8 +105,8 @@ def cinderclient(context):
global _V1_ERROR_RAISED
if not _SESSION:
_SESSION = session.Session.load_from_conf_options(CONF,
CINDER_OPT_GROUP)
_SESSION = ks_loading.load_session_from_conf_options(CONF,
CINDER_OPT_GROUP)
url = None
endpoint_override = None

View File

@ -26,7 +26,7 @@ Babel>=1.3 # BSD
iso8601>=0.1.9 # MIT
jsonschema!=2.5.0,<3.0.0,>=2.0.0 # MIT
python-cinderclient>=1.3.1 # Apache-2.0
python-keystoneclient!=1.8.0,!=2.1.0,>=1.6.0 # Apache-2.0
keystoneauth1>=2.1.0 # Apache-2.0
python-neutronclient>=2.6.0 # Apache-2.0
python-glanceclient>=1.2.0 # Apache-2.0
requests!=2.9.0,>=2.8.1 # Apache-2.0