Adding sessions module and keystone client upgrade
This change implements the sahara.service.sessions module with the basic session cache object. It also adds the authentication plugin from the keystonemiddleware into the context for rest transactions. It also migrates the keystone client utility functions to use the new session methodology. The trust module has been accordingly fixed to make greater use of authentication objects instead of client objects. * adding auth plugin to context * adding sessions module * adding test for sessions * adding keystonemiddleware base auth plugin object to context on api call * adding keystone session to sessions module * refactoring keystone client to use sessions * adding keystone methods to retrieve auth plugins, tokens, and service catalog * changing sahara.service.trusts to use new keystone methods * fixing trust tests to fit new authentication methodologies Change-Id: I65ed4b4dcee8752bf4e66ef9e47305ff408d8d5d Partial-Implements: bp keystone-sessions
This commit is contained in:
parent
81af38fabe
commit
f240d55ac5
@ -47,6 +47,7 @@ class Context(context.RequestContext):
|
|||||||
resource_uuid=None,
|
resource_uuid=None,
|
||||||
current_instance_info=None,
|
current_instance_info=None,
|
||||||
request_id=None,
|
request_id=None,
|
||||||
|
auth_plugin=None,
|
||||||
overwrite=True,
|
overwrite=True,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
if kwargs:
|
if kwargs:
|
||||||
@ -64,6 +65,7 @@ class Context(context.RequestContext):
|
|||||||
self.tenant_name = tenant_name
|
self.tenant_name = tenant_name
|
||||||
self.remote_semaphore = remote_semaphore or semaphore.Semaphore(
|
self.remote_semaphore = remote_semaphore or semaphore.Semaphore(
|
||||||
CONF.cluster_remote_threshold)
|
CONF.cluster_remote_threshold)
|
||||||
|
self.auth_plugin = auth_plugin
|
||||||
self.roles = roles
|
self.roles = roles
|
||||||
if overwrite or not hasattr(context._request_store, 'context'):
|
if overwrite or not hasattr(context._request_store, 'context'):
|
||||||
self.update_store()
|
self.update_store()
|
||||||
@ -87,6 +89,7 @@ class Context(context.RequestContext):
|
|||||||
self.resource_uuid,
|
self.resource_uuid,
|
||||||
self.current_instance_info,
|
self.current_instance_info,
|
||||||
self.request_id,
|
self.request_id,
|
||||||
|
self.auth_plugin,
|
||||||
overwrite=False)
|
overwrite=False)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
106
sahara/service/sessions.py
Normal file
106
sahara/service/sessions.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# Copyright (c) 2015 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from keystoneclient import session as keystone
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from sahara import exceptions as ex
|
||||||
|
from sahara.i18n import _
|
||||||
|
from sahara.i18n import _LE
|
||||||
|
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
_SESSION_CACHE = None
|
||||||
|
|
||||||
|
SESSION_TYPE_GENERIC = 'generic'
|
||||||
|
SESSION_TYPE_KEYSTONE = 'keystone'
|
||||||
|
|
||||||
|
|
||||||
|
def cache():
|
||||||
|
global _SESSION_CACHE
|
||||||
|
if not _SESSION_CACHE:
|
||||||
|
_SESSION_CACHE = SessionCache()
|
||||||
|
return _SESSION_CACHE
|
||||||
|
|
||||||
|
|
||||||
|
class SessionCache(object):
|
||||||
|
'''A cache of keystone Session objects
|
||||||
|
|
||||||
|
When a requested Session is not currently cached, it will be
|
||||||
|
acquired from specific information in this module. Sessions should
|
||||||
|
be referenced by their OpenStack project name and not the service
|
||||||
|
name, this is to allow for multiple service implementations
|
||||||
|
while retaining the ability to generate Session objects. In all
|
||||||
|
cases, the constant values in this module should be used to
|
||||||
|
communicate the session type.
|
||||||
|
|
||||||
|
'''
|
||||||
|
def __init__(self):
|
||||||
|
'''create a new SessionCache'''
|
||||||
|
self._sessions = {}
|
||||||
|
self._session_funcs = {
|
||||||
|
SESSION_TYPE_GENERIC: self.get_generic_session,
|
||||||
|
SESSION_TYPE_KEYSTONE: self.get_keystone_session,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _set_session(self, session_type, session):
|
||||||
|
'''Set the session for a given type.
|
||||||
|
|
||||||
|
:param session_type: the type of session to set.
|
||||||
|
|
||||||
|
:param session: the session to associate with the type
|
||||||
|
'''
|
||||||
|
self._sessions[session_type] = session
|
||||||
|
|
||||||
|
def get_session(self, session_type=SESSION_TYPE_GENERIC):
|
||||||
|
'''Return a Session for the requested type
|
||||||
|
|
||||||
|
:param session_type: the type of Session to get, if None a generic
|
||||||
|
session will be returned.
|
||||||
|
|
||||||
|
:raises SaharaException: if the requested session type is not
|
||||||
|
found.
|
||||||
|
'''
|
||||||
|
session_function = self._session_funcs.get(session_type)
|
||||||
|
if session_function:
|
||||||
|
return session_function()
|
||||||
|
else:
|
||||||
|
LOG.error(
|
||||||
|
_LE('Requesting an unknown session type (type: {type})').
|
||||||
|
format(type=session_type))
|
||||||
|
raise ex.SaharaException(
|
||||||
|
_('Session type {type} not recognized').
|
||||||
|
format(type=session_type))
|
||||||
|
|
||||||
|
def get_generic_session(self):
|
||||||
|
session = self._sessions.get(SESSION_TYPE_GENERIC)
|
||||||
|
if not session:
|
||||||
|
session = keystone.Session()
|
||||||
|
self._set_session(SESSION_TYPE_GENERIC, session)
|
||||||
|
return session
|
||||||
|
|
||||||
|
def get_keystone_session(self):
|
||||||
|
session = self._sessions.get(SESSION_TYPE_KEYSTONE)
|
||||||
|
if not session:
|
||||||
|
if CONF.keystone.ca_file:
|
||||||
|
session = keystone.Session(cert=CONF.keystone.ca_file,
|
||||||
|
verify=CONF.keystone.api_insecure)
|
||||||
|
else:
|
||||||
|
session = self.get_generic_session()
|
||||||
|
self._set_session(SESSION_TYPE_KEYSTONE, session)
|
||||||
|
return session
|
@ -39,36 +39,42 @@ def _get_expiry():
|
|||||||
hours=CONF.cluster_operation_trust_expiration_hours)
|
hours=CONF.cluster_operation_trust_expiration_hours)
|
||||||
|
|
||||||
|
|
||||||
def create_trust(trustor,
|
def create_trust(trustor, trustee, role_names, impersonation=True,
|
||||||
trustee,
|
project_id=None, expires=True):
|
||||||
role_names,
|
|
||||||
impersonation=True,
|
|
||||||
project_id=None,
|
|
||||||
expires=True):
|
|
||||||
'''Create a trust and return it's identifier
|
'''Create a trust and return it's identifier
|
||||||
|
|
||||||
:param trustor: The Keystone client delegating the trust.
|
:param trustor: The user delegating the trust, this is an auth plugin.
|
||||||
:param trustee: The Keystone client consuming the trust.
|
|
||||||
|
:param trustee: The user consuming the trust, this is an auth plugin.
|
||||||
|
|
||||||
:param role_names: A list of role names to be assigned.
|
:param role_names: A list of role names to be assigned.
|
||||||
|
|
||||||
:param impersonation: Should the trustee impersonate trustor,
|
:param impersonation: Should the trustee impersonate trustor,
|
||||||
default is True.
|
default is True.
|
||||||
|
|
||||||
:param project_id: The project that the trust will be scoped into,
|
:param project_id: The project that the trust will be scoped into,
|
||||||
default is the trustor's project id.
|
default is the trustor's project id.
|
||||||
|
|
||||||
:param expires: The trust will expire if this is set to True.
|
:param expires: The trust will expire if this is set to True.
|
||||||
|
|
||||||
:returns: A valid trust id.
|
:returns: A valid trust id.
|
||||||
|
|
||||||
:raises CreationFailed: If the trust cannot be created.
|
:raises CreationFailed: If the trust cannot be created.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
if project_id is None:
|
if project_id is None:
|
||||||
project_id = trustor.tenant_id
|
project_id = keystone.project_id_from_auth(trustor)
|
||||||
try:
|
try:
|
||||||
expires_at = _get_expiry() if expires else None
|
expires_at = _get_expiry() if expires else None
|
||||||
trust = trustor.trusts.create(trustor_user=trustor.user_id,
|
trustor_user_id = keystone.user_id_from_auth(trustor)
|
||||||
trustee_user=trustee.user_id,
|
trustee_user_id = keystone.user_id_from_auth(trustee)
|
||||||
impersonation=impersonation,
|
client = keystone.client_from_auth(trustor)
|
||||||
role_names=role_names,
|
trust = client.trusts.create(trustor_user=trustor_user_id,
|
||||||
project=project_id,
|
trustee_user=trustee_user_id,
|
||||||
expires_at=expires_at)
|
impersonation=impersonation,
|
||||||
|
role_names=role_names,
|
||||||
|
project=project_id,
|
||||||
|
expires_at=expires_at)
|
||||||
LOG.debug('Created trust {trust_id}'.format(
|
LOG.debug('Created trust {trust_id}'.format(
|
||||||
trust_id=six.text_type(trust.id)))
|
trust_id=six.text_type(trust.id)))
|
||||||
return trust.id
|
return trust.id
|
||||||
@ -87,9 +93,10 @@ def create_trust_for_cluster(cluster, expires=True):
|
|||||||
|
|
||||||
:param expires: The trust will expire if this is set to True.
|
:param expires: The trust will expire if this is set to True.
|
||||||
'''
|
'''
|
||||||
trustor = keystone.client()
|
|
||||||
ctx = context.current()
|
ctx = context.current()
|
||||||
trustee = keystone.client_for_admin()
|
trustor = keystone.auth()
|
||||||
|
trustee = keystone.auth_for_admin(
|
||||||
|
project_name=CONF.keystone_authtoken.admin_tenant_name)
|
||||||
|
|
||||||
trust_id = create_trust(trustor=trustor,
|
trust_id = create_trust(trustor=trustor,
|
||||||
trustee=trustee,
|
trustee=trustee,
|
||||||
@ -104,13 +111,16 @@ def create_trust_for_cluster(cluster, expires=True):
|
|||||||
def delete_trust(trustee, trust_id):
|
def delete_trust(trustee, trust_id):
|
||||||
'''Delete a trust from a trustee
|
'''Delete a trust from a trustee
|
||||||
|
|
||||||
:param trustee: The Keystone client to delete the trust from.
|
:param trustee: The user to delete the trust from, this is an auth plugin.
|
||||||
|
|
||||||
:param trust_id: The identifier of the trust to delete.
|
:param trust_id: The identifier of the trust to delete.
|
||||||
|
|
||||||
:raises DeletionFailed: If the trust cannot be deleted.
|
:raises DeletionFailed: If the trust cannot be deleted.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
try:
|
try:
|
||||||
trustee.trusts.delete(trust_id)
|
client = keystone.client_from_auth(trustee)
|
||||||
|
client.trusts.delete(trust_id)
|
||||||
LOG.debug('Deleted trust {trust_id}'.format(
|
LOG.debug('Deleted trust {trust_id}'.format(
|
||||||
trust_id=six.text_type(trust_id)))
|
trust_id=six.text_type(trust_id)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -130,9 +140,8 @@ def delete_trust_from_cluster(cluster):
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
if cluster.trust_id:
|
if cluster.trust_id:
|
||||||
keystone_client = keystone.client_for_admin_from_trust(
|
keystone_auth = keystone.auth_for_admin(trust_id=cluster.trust_id)
|
||||||
cluster.trust_id)
|
delete_trust(keystone_auth, cluster.trust_id)
|
||||||
delete_trust(keystone_client, cluster.trust_id)
|
|
||||||
ctx = context.current()
|
ctx = context.current()
|
||||||
conductor.cluster_update(ctx,
|
conductor.cluster_update(ctx,
|
||||||
cluster,
|
cluster,
|
||||||
@ -154,6 +163,8 @@ def use_os_admin_auth_token(cluster):
|
|||||||
ctx = context.current()
|
ctx = context.current()
|
||||||
ctx.username = CONF.keystone_authtoken.admin_user
|
ctx.username = CONF.keystone_authtoken.admin_user
|
||||||
ctx.tenant_id = cluster.tenant_id
|
ctx.tenant_id = cluster.tenant_id
|
||||||
client = keystone.client_for_admin_from_trust(cluster.trust_id)
|
ctx.auth_plugin = keystone.auth_for_admin(
|
||||||
ctx.auth_token = client.auth_token
|
trust_id=cluster.trust_id)
|
||||||
ctx.service_catalog = json.dumps(client.service_catalog.get_data())
|
ctx.auth_token = keystone.token_from_auth(ctx.auth_plugin)
|
||||||
|
ctx.service_catalog = json.dumps(
|
||||||
|
keystone.service_catalog_from_auth(ctx.auth_plugin))
|
||||||
|
33
sahara/tests/unit/service/test_sessions.py
Normal file
33
sahara/tests/unit/service/test_sessions.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Copyright (c) 2015 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from keystoneclient import session as keystone
|
||||||
|
|
||||||
|
from sahara import exceptions as ex
|
||||||
|
from sahara.service import sessions
|
||||||
|
from sahara.tests.unit import base
|
||||||
|
|
||||||
|
|
||||||
|
class TestSessionCache(base.SaharaTestCase):
|
||||||
|
|
||||||
|
def test_get_session(self):
|
||||||
|
sc = sessions.cache()
|
||||||
|
|
||||||
|
session = sc.get_session()
|
||||||
|
self.assertTrue(isinstance(session, keystone.Session))
|
||||||
|
|
||||||
|
self.assertRaises(ex.SaharaException,
|
||||||
|
sc.get_session,
|
||||||
|
session_type='bad service')
|
@ -27,20 +27,27 @@ class FakeTrust(object):
|
|||||||
|
|
||||||
class TestTrusts(base.SaharaTestCase):
|
class TestTrusts(base.SaharaTestCase):
|
||||||
|
|
||||||
def _trustor(self):
|
def _client(self):
|
||||||
create = mock.Mock()
|
create = mock.Mock()
|
||||||
create.return_value = FakeTrust("trust_id")
|
create.return_value = FakeTrust("trust_id")
|
||||||
trustor_trusts = mock.Mock(create=create)
|
client_trusts = mock.Mock(create=create)
|
||||||
trustor = mock.Mock(user_id="trustor_id", tenant_id="tenant_id",
|
client = mock.Mock(trusts=client_trusts)
|
||||||
trusts=trustor_trusts)
|
return client
|
||||||
return trustor
|
|
||||||
|
|
||||||
def test_create_trust(self):
|
@mock.patch('sahara.utils.openstack.keystone.client_from_auth')
|
||||||
trustor = self._trustor()
|
@mock.patch('sahara.utils.openstack.keystone.project_id_from_auth')
|
||||||
trustee = mock.Mock(user_id="trustee_id")
|
@mock.patch('sahara.utils.openstack.keystone.user_id_from_auth')
|
||||||
|
def test_create_trust(self, user_id_from_auth, project_id_from_auth,
|
||||||
|
client_from_auth):
|
||||||
|
project_id_from_auth.return_value = 'tenant_id'
|
||||||
|
user_id_from_auth.side_effect = ['trustor_id', 'trustee_id']
|
||||||
|
trustor = 'trustor_id'
|
||||||
|
trustee = 'trustee_id'
|
||||||
|
client = self._client()
|
||||||
|
client_from_auth.return_value = client
|
||||||
trust_id = trusts.create_trust(trustor, trustee,
|
trust_id = trusts.create_trust(trustor, trustee,
|
||||||
"role_names", expires=True)
|
"role_names", expires=True)
|
||||||
trustor.trusts.create.assert_called_with(
|
client.trusts.create.assert_called_with(
|
||||||
trustor_user="trustor_id",
|
trustor_user="trustor_id",
|
||||||
trustee_user="trustee_id",
|
trustee_user="trustee_id",
|
||||||
impersonation=True,
|
impersonation=True,
|
||||||
@ -50,29 +57,42 @@ class TestTrusts(base.SaharaTestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual("trust_id", trust_id)
|
self.assertEqual("trust_id", trust_id)
|
||||||
|
|
||||||
@mock.patch('sahara.utils.openstack.keystone.client_for_admin')
|
user_id_from_auth.side_effect = ['trustor_id', 'trustee_id']
|
||||||
@mock.patch('sahara.utils.openstack.keystone.client')
|
client = self._client()
|
||||||
@mock.patch('sahara.conductor.API.cluster_update')
|
client_from_auth.return_value = client
|
||||||
@mock.patch('sahara.context.current')
|
trust_id = trusts.create_trust(trustor, trustee, "role_names",
|
||||||
def test_create_trust_for_cluster(self, m_current, m_cluster_update,
|
project_id='injected_project',
|
||||||
m_client, m_client_for_admin):
|
expires=False)
|
||||||
ctx = mock.Mock(roles="role_names")
|
client.trusts.create.assert_called_with(trustor_user="trustor_id",
|
||||||
trustee = mock.Mock(user_id="trustee_id")
|
trustee_user="trustee_id",
|
||||||
trustor = self._trustor()
|
impersonation=True,
|
||||||
|
role_names="role_names",
|
||||||
|
project="injected_project",
|
||||||
|
expires_at=None)
|
||||||
|
self.assertEqual("trust_id", trust_id)
|
||||||
|
|
||||||
m_current.return_value = ctx
|
@mock.patch('sahara.conductor.API.cluster_update')
|
||||||
m_client_for_admin.return_value = trustee
|
@mock.patch('sahara.service.trusts.create_trust')
|
||||||
m_client.return_value = trustor
|
@mock.patch('sahara.utils.openstack.keystone.auth_for_admin')
|
||||||
|
@mock.patch('sahara.context.current')
|
||||||
|
def test_create_trust_for_cluster(self, context_current, auth_for_admin,
|
||||||
|
create_trust, cluster_update):
|
||||||
|
self.override_config('admin_tenant_name', 'admin_project',
|
||||||
|
group='keystone_authtoken')
|
||||||
|
trustor_auth = mock.Mock()
|
||||||
|
ctx = mock.Mock(roles="role_names", auth_plugin=trustor_auth)
|
||||||
|
context_current.return_value = ctx
|
||||||
|
trustee_auth = mock.Mock()
|
||||||
|
auth_for_admin.return_value = trustee_auth
|
||||||
|
create_trust.return_value = 'trust_id'
|
||||||
|
|
||||||
trusts.create_trust_for_cluster("cluster")
|
trusts.create_trust_for_cluster("cluster")
|
||||||
|
|
||||||
trustor.trusts.create.assert_called_with(
|
auth_for_admin.assert_called_with(project_name='admin_project')
|
||||||
trustor_user="trustor_id",
|
create_trust.assert_called_with(trustor=trustor_auth,
|
||||||
trustee_user="trustee_id",
|
trustee=trustee_auth,
|
||||||
impersonation=True,
|
role_names='role_names',
|
||||||
role_names="role_names",
|
expires=True)
|
||||||
project="tenant_id",
|
|
||||||
expires_at=mock.ANY
|
cluster_update.assert_called_with(ctx, "cluster",
|
||||||
)
|
{"trust_id": "trust_id"})
|
||||||
m_cluster_update.assert_called_with(ctx, "cluster",
|
|
||||||
{"trust_id": "trust_id"})
|
|
||||||
|
@ -78,6 +78,7 @@ class Rest(flask.Blueprint):
|
|||||||
|
|
||||||
kwargs.pop("tenant_id")
|
kwargs.pop("tenant_id")
|
||||||
req_id = flask.request.environ.get(oslo_req_id.ENV_REQUEST_ID)
|
req_id = flask.request.environ.get(oslo_req_id.ENV_REQUEST_ID)
|
||||||
|
auth_plugin = flask.request.environ.get('keystone.token_auth')
|
||||||
ctx = context.Context(
|
ctx = context.Context(
|
||||||
flask.request.headers['X-User-Id'],
|
flask.request.headers['X-User-Id'],
|
||||||
flask.request.headers['X-Tenant-Id'],
|
flask.request.headers['X-Tenant-Id'],
|
||||||
@ -86,6 +87,7 @@ class Rest(flask.Blueprint):
|
|||||||
flask.request.headers['X-User-Name'],
|
flask.request.headers['X-User-Name'],
|
||||||
flask.request.headers['X-Tenant-Name'],
|
flask.request.headers['X-Tenant-Name'],
|
||||||
flask.request.headers['X-Roles'].split(','),
|
flask.request.headers['X-Roles'].split(','),
|
||||||
|
auth_plugin=auth_plugin,
|
||||||
request_id=req_id)
|
request_id=req_id)
|
||||||
context.set_ctx(ctx)
|
context.set_ctx(ctx)
|
||||||
if flask.request.method in ['POST', 'PUT', 'PATCH']:
|
if flask.request.method in ['POST', 'PUT', 'PATCH']:
|
||||||
|
@ -20,6 +20,7 @@ from keystoneclient.v3 import client as keystone_client_v3
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from sahara import context
|
from sahara import context
|
||||||
|
from sahara.service import sessions
|
||||||
from sahara.utils.openstack import base
|
from sahara.utils.openstack import base
|
||||||
|
|
||||||
|
|
||||||
@ -73,14 +74,142 @@ CONF.register_opts(opts)
|
|||||||
CONF.register_opts(ssl_opts, group=keystone_group)
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def auth_for_admin(project_name=None, trust_id=None):
|
||||||
|
'''Return an auth plugin for the admin.
|
||||||
|
|
||||||
|
:param project_name: a project to scope the auth with (optional).
|
||||||
|
|
||||||
|
:param trust_id: a trust to scope the auth with (optional).
|
||||||
|
|
||||||
|
:returns: an auth plugin object for the admin.
|
||||||
|
'''
|
||||||
|
# TODO(elmiko) revisit the project_domain_name if we start getting
|
||||||
|
# into federated authentication. it will need to match the domain that
|
||||||
|
# the project_name exists in.
|
||||||
|
auth = _password_auth(
|
||||||
|
username=CONF.keystone_authtoken.admin_user,
|
||||||
|
password=CONF.keystone_authtoken.admin_password,
|
||||||
|
project_name=project_name,
|
||||||
|
user_domain_name=CONF.admin_user_domain_name,
|
||||||
|
project_domain_name=CONF.admin_project_domain_name,
|
||||||
|
trust_id=trust_id)
|
||||||
|
return auth
|
||||||
|
|
||||||
|
|
||||||
|
def auth_for_proxy(username, password, trust_id=None):
|
||||||
|
'''Return an auth plugin for the proxy user.
|
||||||
|
|
||||||
|
:param username: the name of the proxy user.
|
||||||
|
|
||||||
|
:param password: the proxy user's password.
|
||||||
|
|
||||||
|
:param trust_id: a trust to scope the auth with (optional).
|
||||||
|
|
||||||
|
:returns: an auth plugin object for the proxy user.
|
||||||
|
'''
|
||||||
|
auth = _password_auth(
|
||||||
|
username=username,
|
||||||
|
password=password,
|
||||||
|
user_domain_name=CONF.proxy_user_domain_name,
|
||||||
|
trust_id=trust_id)
|
||||||
|
return auth
|
||||||
|
|
||||||
|
|
||||||
def client():
|
def client():
|
||||||
'''Return the current context client.'''
|
'''Return the current context client.'''
|
||||||
ctx = context.current()
|
return client_from_auth(auth())
|
||||||
|
|
||||||
return _client(username=ctx.username, token=ctx.auth_token,
|
|
||||||
tenant_id=ctx.tenant_id)
|
|
||||||
|
|
||||||
|
|
||||||
|
def client_for_admin():
|
||||||
|
'''Return the Sahara admin user client.'''
|
||||||
|
auth = auth_for_admin(
|
||||||
|
project_name=CONF.keystone_authtoken.admin_tenant_name)
|
||||||
|
return client_from_auth(auth)
|
||||||
|
|
||||||
|
|
||||||
|
def client_from_auth(auth):
|
||||||
|
'''Return a session based client from the auth plugin provided.
|
||||||
|
|
||||||
|
A session is obtained from the global session cache.
|
||||||
|
|
||||||
|
:param auth: the auth plugin object to use in client creation.
|
||||||
|
|
||||||
|
:returns: a keystone client
|
||||||
|
'''
|
||||||
|
session = sessions.cache().get_session(sessions.SESSION_TYPE_KEYSTONE)
|
||||||
|
if CONF.use_identity_api_v3:
|
||||||
|
client_class = keystone_client_v3.Client
|
||||||
|
else:
|
||||||
|
client_class = keystone_client.Client
|
||||||
|
return client_class(session=session, auth=auth)
|
||||||
|
|
||||||
|
|
||||||
|
def project_id_from_auth(auth):
|
||||||
|
'''Return the project id associated with an auth plugin.
|
||||||
|
|
||||||
|
:param auth: the auth plugin to inspect.
|
||||||
|
|
||||||
|
:returns: the project id associated with the auth plugin.
|
||||||
|
'''
|
||||||
|
return auth.get_project_id(
|
||||||
|
sessions.cache().get_session(sessions.SESSION_TYPE_KEYSTONE))
|
||||||
|
|
||||||
|
|
||||||
|
def service_catalog_from_auth(auth):
|
||||||
|
'''Return the service catalog associated with an auth plugin.
|
||||||
|
|
||||||
|
:param auth: the auth plugin to inspect.
|
||||||
|
|
||||||
|
:returns: a list containing the service catalog.
|
||||||
|
'''
|
||||||
|
if CONF.use_identity_api_v3:
|
||||||
|
return auth.get_access(
|
||||||
|
sessions.cache().get_session()).get('catalog', [])
|
||||||
|
else:
|
||||||
|
return auth.get_access(
|
||||||
|
sessions.cache().get_session()).get('serviceCatalog', [])
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(elmiko) factor this out when redoing the barbicanclient
|
||||||
|
def session_for_admin():
|
||||||
|
'''Return a Keystone session for the admin user.'''
|
||||||
|
auth = _password_auth(
|
||||||
|
username=CONF.keystone_authtoken.admin_user,
|
||||||
|
password=CONF.keystone_authtoken.admin_password,
|
||||||
|
project_name=CONF.keystone_authtoken.admin_tenant_name,
|
||||||
|
user_domain_name=CONF.admin_user_domain_name,
|
||||||
|
project_domain_name=CONF.admin_project_domain_name)
|
||||||
|
return keystone_session.Session(auth=auth)
|
||||||
|
|
||||||
|
|
||||||
|
def token_from_auth(auth):
|
||||||
|
'''Return an authentication token from an auth plugin.
|
||||||
|
|
||||||
|
:param auth: the auth plugin to acquire a token from.
|
||||||
|
|
||||||
|
:returns: an auth token in string format.
|
||||||
|
'''
|
||||||
|
return keystone_session.Session(auth=auth).get_token()
|
||||||
|
|
||||||
|
|
||||||
|
def user_id_from_auth(auth):
|
||||||
|
'''Return a user id associated with an auth plugin.
|
||||||
|
|
||||||
|
:param auth: the auth plugin to inspect.
|
||||||
|
|
||||||
|
:returns: a token associated with the auth.
|
||||||
|
'''
|
||||||
|
return auth.get_user_id(sessions.cache().get_session(
|
||||||
|
sessions.SESSION_TYPE_KEYSTONE))
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(elmiko) deprecate this when all client have been migrated to sessions
|
||||||
def _client(username, password=None, token=None, tenant_name=None,
|
def _client(username, password=None, token=None, tenant_name=None,
|
||||||
tenant_id=None, trust_id=None, domain_name=None):
|
tenant_id=None, trust_id=None, domain_name=None):
|
||||||
|
|
||||||
@ -111,64 +240,68 @@ def _client(username, password=None, token=None, tenant_name=None,
|
|||||||
return keystone
|
return keystone
|
||||||
|
|
||||||
|
|
||||||
def _admin_client(project_name=None, trust_id=None):
|
def _password_auth(username, password, project_name, user_domain_name=None,
|
||||||
username = CONF.keystone_authtoken.admin_user
|
project_domain_name=None, trust_id=None):
|
||||||
password = CONF.keystone_authtoken.admin_password
|
'''Return a password auth plugin object.
|
||||||
keystone = _client(username=username,
|
|
||||||
password=password,
|
|
||||||
tenant_name=project_name,
|
|
||||||
trust_id=trust_id)
|
|
||||||
return keystone
|
|
||||||
|
|
||||||
|
:param username: the user to authenticate as.
|
||||||
|
|
||||||
def client_for_admin():
|
:param password: the user's password.
|
||||||
'''Return the Sahara admin user client.'''
|
|
||||||
return _admin_client(
|
|
||||||
project_name=CONF.keystone_authtoken.admin_tenant_name)
|
|
||||||
|
|
||||||
|
:param project_name: the project(ex. tenant) name to scope the auth.
|
||||||
|
|
||||||
def client_for_admin_from_trust(trust_id):
|
:param user_domain_name: the domain the user belongs to.
|
||||||
'''Return the Sahara admin user client scoped to a trust.'''
|
|
||||||
return _admin_client(trust_id=trust_id)
|
|
||||||
|
|
||||||
|
:param project_domain_name: the domain the project belongs to.
|
||||||
|
|
||||||
def client_for_proxy_user(username, password, trust_id=None):
|
:param trust_id: a trust id to scope the auth.
|
||||||
'''Return a client for the proxy user specified.'''
|
|
||||||
return _client(username=username,
|
|
||||||
password=password,
|
|
||||||
domain_name=CONF.proxy_user_domain_name,
|
|
||||||
trust_id=trust_id)
|
|
||||||
|
|
||||||
|
:returns: a password auth plugin object.
|
||||||
def _session(username, password, project_name, user_domain_name=None,
|
'''
|
||||||
project_domain_name=None):
|
|
||||||
passwd_kwargs = dict(
|
passwd_kwargs = dict(
|
||||||
auth_url=base.retrieve_auth_url(),
|
auth_url=base.retrieve_auth_url(),
|
||||||
username=CONF.keystone_authtoken.admin_user,
|
username=username,
|
||||||
password=CONF.keystone_authtoken.admin_password
|
password=password
|
||||||
)
|
)
|
||||||
|
|
||||||
if CONF.use_identity_api_v3:
|
if CONF.use_identity_api_v3:
|
||||||
passwd_kwargs.update(dict(
|
passwd_kwargs.update(dict(
|
||||||
project_name=project_name,
|
project_name=project_name,
|
||||||
user_domain_name=user_domain_name,
|
user_domain_name=user_domain_name,
|
||||||
project_domain_name=project_domain_name
|
project_domain_name=project_domain_name,
|
||||||
|
trust_id=trust_id
|
||||||
))
|
))
|
||||||
auth = keystone_identity.v3.Password(**passwd_kwargs)
|
auth = keystone_identity.v3.Password(**passwd_kwargs)
|
||||||
else:
|
else:
|
||||||
passwd_kwargs.update(dict(
|
passwd_kwargs.update(dict(
|
||||||
tenant_name=project_name
|
tenant_name=project_name,
|
||||||
|
trust_id=trust_id
|
||||||
))
|
))
|
||||||
auth = keystone_identity.v2.Password(**passwd_kwargs)
|
auth = keystone_identity.v2.Password(**passwd_kwargs)
|
||||||
|
return auth
|
||||||
return keystone_session.Session(auth=auth)
|
|
||||||
|
|
||||||
|
|
||||||
def session_for_admin():
|
def _token_auth(token, project_id, project_domain_name='Default'):
|
||||||
'''Return a Keystone session for the admin user.'''
|
'''Return a token auth plugin object.
|
||||||
return _session(
|
|
||||||
username=CONF.keystone_authtoken.admin_user,
|
:param token: the token to use for authentication.
|
||||||
password=CONF.keystone_authtoken.admin_password,
|
|
||||||
project_name=CONF.keystone_authtoken.admin_tenant_name,
|
:param project_id: the project(ex. tenant) id to scope the auth.
|
||||||
user_domain_name=CONF.admin_user_domain_name,
|
|
||||||
project_domain_name=CONF.admin_project_domain_name)
|
: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
|
||||||
|
@ -55,8 +55,8 @@ def client(username, password, trust_id=None):
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
if trust_id:
|
if trust_id:
|
||||||
proxyclient = k.client_for_proxy_user(username, password, trust_id)
|
proxyauth = k.auth_for_proxy_user(username, password, trust_id)
|
||||||
return client_from_token(proxyclient.auth_token)
|
return client_from_token(k.token_from_auth(proxyauth))
|
||||||
else:
|
else:
|
||||||
return swiftclient.Connection(
|
return swiftclient.Connection(
|
||||||
auth_version='2.0',
|
auth_version='2.0',
|
||||||
|
@ -61,8 +61,8 @@ def create_proxy_user_for_job_execution(job_execution):
|
|||||||
'''
|
'''
|
||||||
username = 'job_{0}'.format(job_execution.id)
|
username = 'job_{0}'.format(job_execution.id)
|
||||||
password = proxy_user_create(username)
|
password = proxy_user_create(username)
|
||||||
current_user = k.client()
|
current_user = k.auth()
|
||||||
proxy_user = k.client_for_proxy_user(username, password)
|
proxy_user = k.auth_for_proxy(username, password)
|
||||||
trust_id = t.create_trust(trustor=current_user,
|
trust_id = t.create_trust(trustor=current_user,
|
||||||
trustee=proxy_user,
|
trustee=proxy_user,
|
||||||
role_names=CONF.proxy_user_role_names)
|
role_names=CONF.proxy_user_role_names)
|
||||||
@ -87,9 +87,9 @@ def delete_proxy_user_for_job_execution(job_execution):
|
|||||||
proxy_username = proxy_configs.get('proxy_username')
|
proxy_username = proxy_configs.get('proxy_username')
|
||||||
proxy_password = proxy_configs.get('proxy_password')
|
proxy_password = proxy_configs.get('proxy_password')
|
||||||
proxy_trust_id = proxy_configs.get('proxy_trust_id')
|
proxy_trust_id = proxy_configs.get('proxy_trust_id')
|
||||||
proxy_user = k.client_for_proxy_user(proxy_username,
|
proxy_user = k.auth_for_proxy(proxy_username,
|
||||||
proxy_password,
|
proxy_password,
|
||||||
proxy_trust_id)
|
proxy_trust_id)
|
||||||
t.delete_trust(proxy_user, proxy_trust_id)
|
t.delete_trust(proxy_user, proxy_trust_id)
|
||||||
proxy_user_delete(proxy_username)
|
proxy_user_delete(proxy_username)
|
||||||
update = job_execution.job_configs.to_dict()
|
update = job_execution.job_configs.to_dict()
|
||||||
@ -108,8 +108,8 @@ def create_proxy_user_for_cluster(cluster):
|
|||||||
return cluster
|
return cluster
|
||||||
username = 'cluster_{0}'.format(cluster.id)
|
username = 'cluster_{0}'.format(cluster.id)
|
||||||
password = proxy_user_create(username)
|
password = proxy_user_create(username)
|
||||||
current_user = k.client()
|
current_user = k.auth()
|
||||||
proxy_user = k.client_for_proxy_user(username, password)
|
proxy_user = k.auth_for_proxy(username, password)
|
||||||
trust_id = t.create_trust(trustor=current_user,
|
trust_id = t.create_trust(trustor=current_user,
|
||||||
trustee=proxy_user,
|
trustee=proxy_user,
|
||||||
role_names=CONF.proxy_user_role_names)
|
role_names=CONF.proxy_user_role_names)
|
||||||
@ -133,9 +133,9 @@ def delete_proxy_user_for_cluster(cluster):
|
|||||||
proxy_username = proxy_configs.get('proxy_username')
|
proxy_username = proxy_configs.get('proxy_username')
|
||||||
proxy_password = proxy_configs.get('proxy_password')
|
proxy_password = proxy_configs.get('proxy_password')
|
||||||
proxy_trust_id = proxy_configs.get('proxy_trust_id')
|
proxy_trust_id = proxy_configs.get('proxy_trust_id')
|
||||||
proxy_user = k.client_for_proxy_user(proxy_username,
|
proxy_user = k.auth_for_proxy(proxy_username,
|
||||||
proxy_password,
|
proxy_password,
|
||||||
proxy_trust_id)
|
proxy_trust_id)
|
||||||
t.delete_trust(proxy_user, proxy_trust_id)
|
t.delete_trust(proxy_user, proxy_trust_id)
|
||||||
proxy_user_delete(proxy_username)
|
proxy_user_delete(proxy_username)
|
||||||
update = {'cluster_configs': cluster.cluster_configs.to_dict()}
|
update = {'cluster_configs': cluster.cluster_configs.to_dict()}
|
||||||
|
Loading…
Reference in New Issue
Block a user