adding neutron to sessions module

this change adds neutron to the sessions module and updates the neutron
client to use sessions and auth plugins. it also adjust the ssh_remote
module to not pass the endpoint url as this will be determined by the
session.

* adding neutron to sessions module
* updating neutron client to use sessions and auth plugin
* removing endpoint url discovery for neutron from ssh_remote
* adding neutron to session tests
* fixing neutron client tests
* fixing ssh_remote tests
* renaming token_auth function in keystone to make it more public

Change-Id: Icaa71a06d36c6828366f8d322ec3bed3e238506b
Partial-Implements: blueprint keystone-sessions
This commit is contained in:
Michael McCune 2015-08-25 11:30:40 -04:00
parent 5466269460
commit 6a2a028c8c
7 changed files with 81 additions and 54 deletions

View File

@ -30,6 +30,7 @@ _SESSION_CACHE = None
SESSION_TYPE_CINDER = 'cinder'
SESSION_TYPE_GENERIC = 'generic'
SESSION_TYPE_KEYSTONE = 'keystone'
SESSION_TYPE_NEUTRON = 'neutron'
SESSION_TYPE_NOVA = 'nova'
@ -59,6 +60,7 @@ class SessionCache(object):
SESSION_TYPE_CINDER: self.get_cinder_session,
SESSION_TYPE_GENERIC: self.get_generic_session,
SESSION_TYPE_KEYSTONE: self.get_keystone_session,
SESSION_TYPE_NEUTRON: self.get_neutron_session,
SESSION_TYPE_NOVA: self.get_nova_session,
}
@ -120,6 +122,17 @@ class SessionCache(object):
self._set_session(SESSION_TYPE_KEYSTONE, session)
return session
def get_neutron_session(self):
session = self._sessions.get(SESSION_TYPE_NEUTRON)
if not session:
if CONF.neutron.ca_file:
session = keystone.Session(cert=CONF.neutron.ca_file,
verify=CONF.neutron.api_insecure)
else:
session = self.get_generic_session()
self._set_session(SESSION_TYPE_NEUTRON, session)
return session
def get_nova_session(self):
session = self._sessions.get(SESSION_TYPE_NOVA)
if not session:

View File

@ -91,3 +91,23 @@ class TestSessionCache(base.SaharaTestCase):
keystone_session.reset_mock()
sc.get_session(sessions.SESSION_TYPE_CINDER)
self.assertFalse(keystone_session.called)
@mock.patch('keystoneclient.session.Session')
def test_get_neutron_session(self, keystone_session):
sc = sessions.SessionCache()
self.override_config('ca_file', '/some/cacert', group='neutron')
self.override_config('api_insecure', True, group='neutron')
sc.get_session(sessions.SESSION_TYPE_NEUTRON)
keystone_session.assert_called_once_with(cert='/some/cacert',
verify=True)
sc = sessions.SessionCache()
keystone_session.reset_mock()
self.override_config('ca_file', None, group='neutron')
self.override_config('api_insecure', None, group='neutron')
sc.get_session(sessions.SESSION_TYPE_NEUTRON)
keystone_session.assert_called_once_with()
keystone_session.reset_mock()
sc.get_session(sessions.SESSION_TYPE_NEUTRON)
self.assertFalse(keystone_session.called)

View File

@ -20,11 +20,12 @@ from sahara.utils.openstack import neutron as neutron_client
class NeutronClientTest(testtools.TestCase):
@mock.patch("sahara.utils.openstack.keystone.token_auth")
@mock.patch("neutronclient.neutron.client.Client")
def test_get_router(self, patched):
def test_get_router(self, patched, token_auth):
patched.side_effect = _test_get_neutron_client
neutron = neutron_client.NeutronClient(
'33b47310-b7a8-4559-bf95-45ba669a448e', None, None, None)
'33b47310-b7a8-4559-bf95-45ba669a448e', None, None)
self.assertEqual('6c4d4e32-3667-4cd4-84ea-4cc1e98d18be',
neutron.get_router())

View File

@ -123,9 +123,10 @@ class TestInstanceInteropHelper(base.SaharaTestCase):
# When use_floating_ips=False and use_namespaces=True, a netcat socket
# created with 'ip netns exec qrouter-...' should be used to access
# instances.
@mock.patch("sahara.utils.openstack.keystone.token_auth")
@mock.patch('sahara.utils.ssh_remote._simple_exec_func')
@mock.patch('sahara.utils.ssh_remote.ProxiedHTTPAdapter')
def test_use_namespaces(self, p_adapter, p_simple_exec_func):
def test_use_namespaces(self, p_adapter, p_simple_exec_func, token_auth):
self.override_config('use_floating_ips', False)
self.override_config('use_namespaces', True)

View File

@ -77,7 +77,8 @@ CONF.register_opts(ssl_opts, group=keystone_group)
def auth():
'''Return a token auth plugin for the current context.'''
ctx = context.current()
return ctx.auth_plugin or _token_auth(ctx.auth_token, ctx.tenant_id)
return ctx.auth_plugin or token_auth(token=ctx.auth_token,
project_id=ctx.tenant_id)
def auth_for_admin(project_name=None, trust_id=None):
@ -188,6 +189,36 @@ def session_for_admin():
return keystone_session.Session(auth=auth)
def token_auth(token, project_id=None, project_name=None,
project_domain_name='Default'):
'''Return a token auth plugin object.
:param token: the token to use for authentication.
:param project_id: the project(ex. tenant) id to scope the auth.
:returns: a token auth plugin object.
'''
token_kwargs = dict(
auth_url=base.retrieve_auth_url(),
token=token
)
if CONF.use_identity_api_v3:
token_kwargs.update(dict(
project_id=project_id,
project_name=project_name,
project_domain_name=project_domain_name,
))
auth = keystone_identity.v3.Token(**token_kwargs)
else:
token_kwargs.update(dict(
tenant_id=project_id,
tenant_name=project_name,
))
auth = keystone_identity.v2.Token(**token_kwargs)
return auth
def token_from_auth(auth):
'''Return an authentication token from an auth plugin.
@ -278,30 +309,3 @@ def _password_auth(username, password, project_name, user_domain_name=None,
))
auth = keystone_identity.v2.Password(**passwd_kwargs)
return auth
def _token_auth(token, project_id, project_domain_name='Default'):
'''Return a token auth plugin object.
:param token: the token to use for authentication.
:param project_id: the project(ex. tenant) id to scope the auth.
:returns: a token auth plugin object.
'''
token_kwargs = dict(
auth_url=base.retrieve_auth_url(),
token=token
)
if CONF.use_identity_api_v3:
token_kwargs.update(dict(
project_id=project_id,
project_domain_name=project_domain_name,
))
auth = keystone_identity.v3.Token(**token_kwargs)
else:
token_kwargs.update(dict(
tenant_id=project_id
))
auth = keystone_identity.v2.Token(**token_kwargs)
return auth

View File

@ -18,10 +18,11 @@ from neutronclient.neutron import client as neutron_cli
from oslo_config import cfg
from oslo_log import log as logging
from sahara import context
from sahara import exceptions as ex
from sahara.i18n import _
from sahara.service import sessions
from sahara.utils.openstack import base
from sahara.utils.openstack import keystone
opts = [
@ -44,30 +45,19 @@ LOG = logging.getLogger(__name__)
def client():
ctx = context.ctx()
args = {
'username': ctx.username,
'tenant_name': ctx.tenant_name,
'tenant_id': ctx.tenant_id,
'token': ctx.auth_token,
'endpoint_url': base.url_for(ctx.service_catalog, 'network'),
'ca_cert': CONF.neutron.ca_file,
'insecure': CONF.neutron.api_insecure
}
return neutron_cli.Client('2.0', **args)
session = sessions.cache().get_session(sessions.SESSION_TYPE_NEUTRON)
neutron = neutron_cli.Client('2.0', session=session, auth=keystone.auth())
return neutron
class NeutronClient(object):
neutron = None
routers = {}
def __init__(self, network, uri, token, tenant_name):
self.neutron = neutron_cli.Client('2.0',
endpoint_url=uri,
token=token,
tenant_name=tenant_name,
ca_cert=CONF.neutron.ca_file,
insecure=CONF.neutron.api_insecure)
def __init__(self, network, token, tenant_name):
session = sessions.cache().get_session(sessions.SESSION_TYPE_NEUTRON)
auth = keystone.token_auth(token=token, project_name=tenant_name)
self.neutron = neutron_cli.Client('2.0', session=session, auth=auth)
self.network = network
def get_router(self):

View File

@ -54,7 +54,6 @@ from sahara import exceptions as ex
from sahara.i18n import _
from sahara.i18n import _LE
from sahara.utils import crypto
from sahara.utils.openstack import base
from sahara.utils.openstack import neutron
from sahara.utils import procutils
from sahara.utils import remote
@ -545,7 +544,6 @@ class InstanceInteropHelper(remote.Remote):
neutron_info = dict()
neutron_info['network'] = instance.cluster.neutron_management_network
ctx = context.current()
neutron_info['uri'] = base.url_for(ctx.service_catalog, 'network')
neutron_info['token'] = ctx.auth_token
neutron_info['tenant'] = ctx.tenant_name
neutron_info['host'] = instance.management_ip
@ -566,8 +564,8 @@ class InstanceInteropHelper(remote.Remote):
# Query Neutron only if needed
if '{router_id}' in command:
client = neutron.NeutronClient(info['network'], info['uri'],
info['token'], info['tenant'])
client = neutron.NeutronClient(info['network'], info['token'],
info['tenant'])
keywords['router_id'] = client.get_router()
keywords['host'] = instance.management_ip