Add support for system and domain scoped tokens

Currently we request to keystone via the project scoped tokens only
even if the context has system scope.
This patch converts the keystone request to system/domain/project
scoped tokens as requested in the context.

Change-Id: Ie2f124d9ef7d4d69d69bc03880644612cd338e01
This commit is contained in:
Rajat Dhasmana 2020-09-17 08:36:00 +00:00
parent fb7edff4d0
commit 568b279a85
2 changed files with 61 additions and 4 deletions

View File

@ -228,10 +228,30 @@ def _keystone_client(context, version=(3, 0)):
:param version: version of Keystone to request
:return: keystoneclient.client.Client object
"""
auth_plugin = identity.Token(
auth_url=CONF.keystone_authtoken.auth_url,
token=context.auth_token,
project_id=context.project_id)
if context.system_scope is not None:
auth_plugin = identity.Token(
auth_url=CONF.keystone_authtoken.auth_url,
token=context.auth_token,
system_scope=context.system_scope
)
elif context.domain_id is not None:
auth_plugin = identity.Token(
auth_url=CONF.keystone_authtoken.auth_url,
token=context.auth_token,
domain_id=context.domain_id
)
elif context.project_id is not None:
auth_plugin = identity.Token(
auth_url=CONF.keystone_authtoken.auth_url,
token=context.auth_token,
project_id=context.project_id
)
else:
# We're dealing with an unscoped token from keystone that doesn't
# carry any authoritative power outside of the user simplify proving
# they know their own password. This token isn't associated with any
# authorization target (e.g., system, domain, or project).
auth_plugin = context.get_auth_plugin()
client_session = ka_loading.session.Session().load_from_options(
auth=auth_plugin,

View File

@ -22,6 +22,7 @@ from oslo_config import fixture as config_fixture
from cinder import context
from cinder import exception
from cinder import quota_utils
from cinder.tests.unit import fake_constants as fake
from cinder.tests.unit import test
@ -54,6 +55,42 @@ class QuotaUtilsTest(test.TestCase):
session=ksclient_session(),
version=(3, 0))
@mock.patch('keystoneclient.client.Client')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('keystoneauth1.identity.Token')
def test_keystone_client_instantiation_system_scope(
self, ks_token, ksclient_session, ksclient_class):
system_context = context.RequestContext(
'fake_user', 'fake_proj_id', system_scope='all')
quota_utils._keystone_client(system_context)
ks_token.assert_called_once_with(
auth_url=self.auth_url, token=system_context.auth_token,
system_scope=system_context.system_scope)
@mock.patch('keystoneclient.client.Client')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('keystoneauth1.identity.Token')
def test_keystone_client_instantiation_domain_scope(
self, ks_token, ksclient_session, ksclient_class):
domain_context = context.RequestContext(
'fake_user', 'fake_proj_id', domain_id='default')
quota_utils._keystone_client(domain_context)
ks_token.assert_called_once_with(
auth_url=self.auth_url, token=domain_context.auth_token,
domain_id=domain_context.domain_id)
@mock.patch('keystoneclient.client.Client')
@mock.patch('keystoneauth1.session.Session')
@mock.patch('keystoneauth1.identity.Token')
def test_keystone_client_instantiation_project_scope(
self, ks_token, ksclient_session, ksclient_class):
project_context = context.RequestContext(
'fake_user', project_id=fake.PROJECT_ID)
quota_utils._keystone_client(project_context)
ks_token.assert_called_once_with(
auth_url=self.auth_url, token=project_context.auth_token,
project_id=project_context.project_id)
@mock.patch('keystoneclient.client.Client')
def test_get_project_keystoneclient_v2(self, ksclient_class):
keystoneclient = ksclient_class.return_value