Pass role ids to trust if possible
currently Heat fails to create a stack requiring deferred auth with trusts when user happens to have a role assigned for which a different but similar named role exist in another Keystone domain. This patch makes Heat to attempt extract role IDs from the auth_token_info first and pass those to Keystone trust if found. Change-Id: Ic9207e3f027f9c56c14d548d404ecc0c2427f326 Story: 2002613 Task: 22237
This commit is contained in:
parent
0b83b05115
commit
66442554d2
@ -212,22 +212,28 @@ class KsClientWrapper(object):
|
|||||||
trustor_user_id = self.context.auth_plugin.get_user_id(self.session)
|
trustor_user_id = self.context.auth_plugin.get_user_id(self.session)
|
||||||
trustor_proj_id = self.context.auth_plugin.get_project_id(self.session)
|
trustor_proj_id = self.context.auth_plugin.get_project_id(self.session)
|
||||||
|
|
||||||
|
role_kw = {}
|
||||||
# inherit the roles of the trustor, unless set trusts_delegated_roles
|
# inherit the roles of the trustor, unless set trusts_delegated_roles
|
||||||
if cfg.CONF.trusts_delegated_roles:
|
if cfg.CONF.trusts_delegated_roles:
|
||||||
roles = cfg.CONF.trusts_delegated_roles
|
role_kw['role_names'] = cfg.CONF.trusts_delegated_roles
|
||||||
else:
|
else:
|
||||||
roles = self.context.roles
|
token_info = self.context.auth_token_info
|
||||||
|
if token_info and token_info.get('token', {}).get('roles'):
|
||||||
|
role_kw['role_ids'] = [r['id'] for r in
|
||||||
|
token_info['token']['roles']]
|
||||||
|
else:
|
||||||
|
role_kw['role_names'] = self.context.roles
|
||||||
try:
|
try:
|
||||||
trust = self.client.trusts.create(trustor_user=trustor_user_id,
|
trust = self.client.trusts.create(trustor_user=trustor_user_id,
|
||||||
trustee_user=trustee_user_id,
|
trustee_user=trustee_user_id,
|
||||||
project=trustor_proj_id,
|
project=trustor_proj_id,
|
||||||
impersonation=True,
|
impersonation=True,
|
||||||
role_names=roles)
|
**role_kw)
|
||||||
except ks_exception.NotFound:
|
except ks_exception.NotFound:
|
||||||
LOG.debug("Failed to find roles %s for user %s"
|
LOG.debug("Failed to find roles %s for user %s"
|
||||||
% (roles, trustor_user_id))
|
% (role_kw, trustor_user_id))
|
||||||
raise exception.MissingCredentialError(
|
raise exception.MissingCredentialError(
|
||||||
required=_("roles %s") % roles)
|
required=_("roles %s") % role_kw)
|
||||||
|
|
||||||
context_data = self.context.to_dict()
|
context_data = self.context.to_dict()
|
||||||
context_data['overwrite'] = False
|
context_data['overwrite'] = False
|
||||||
|
@ -577,6 +577,33 @@ class KeystoneClientTest(common.HeatTestCase):
|
|||||||
impersonation=True,
|
impersonation=True,
|
||||||
role_names=trustee_roles)
|
role_names=trustee_roles)
|
||||||
|
|
||||||
|
def test_create_trust_context_trust_create_delegate_all_roleids(self):
|
||||||
|
"""Test create_trust_context when creating a trust using role IDs."""
|
||||||
|
|
||||||
|
class MockTrust(object):
|
||||||
|
id = 'atrust123'
|
||||||
|
|
||||||
|
self._stubs_auth(user_id='5678', project_id='42',
|
||||||
|
stub_trust_context=True,
|
||||||
|
stub_admin_auth=True)
|
||||||
|
|
||||||
|
cfg.CONF.set_override('deferred_auth_method', 'trusts')
|
||||||
|
|
||||||
|
self.mock_ks_v3_client.trusts.create.return_value = MockTrust()
|
||||||
|
|
||||||
|
trustor_roles = [{'name': 'spam', 'id': 'ham'}]
|
||||||
|
ctx = utils.dummy_context(roles=trustor_roles)
|
||||||
|
ctx.trust_id = None
|
||||||
|
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
|
||||||
|
# doing that late monkeypatching to not mock extra keystone stuff
|
||||||
|
ctx.auth_token_info = {'token': {'roles': trustor_roles}}
|
||||||
|
trust_context = heat_ks_client.create_trust_context()
|
||||||
|
self.assertEqual('atrust123', trust_context.trust_id)
|
||||||
|
self.assertEqual('5678', trust_context.trustor_user_id)
|
||||||
|
|
||||||
|
args, kwargs = self.mock_ks_v3_client.trusts.create.call_args
|
||||||
|
self.assertEqual(["ham"], kwargs["role_ids"])
|
||||||
|
|
||||||
def test_create_trust_context_trust_create_norole(self):
|
def test_create_trust_context_trust_create_norole(self):
|
||||||
|
|
||||||
"""Test create_trust_context when creating a trust."""
|
"""Test create_trust_context when creating a trust."""
|
||||||
@ -597,7 +624,8 @@ class KeystoneClientTest(common.HeatTestCase):
|
|||||||
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
|
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
|
||||||
exc = self.assertRaises(exception.MissingCredentialError,
|
exc = self.assertRaises(exception.MissingCredentialError,
|
||||||
heat_ks_client.create_trust_context)
|
heat_ks_client.create_trust_context)
|
||||||
expected = "Missing required credential: roles ['heat_stack_owner']"
|
expected = "Missing required credential: roles "
|
||||||
|
"{'role_names': ['heat_stack_owner']}"
|
||||||
self.assertIn(expected, six.text_type(exc))
|
self.assertIn(expected, six.text_type(exc))
|
||||||
self.m_load_auth.assert_called_with(
|
self.m_load_auth.assert_called_with(
|
||||||
cfg.CONF, 'trustee', trust_id=None)
|
cfg.CONF, 'trustee', trust_id=None)
|
||||||
|
Loading…
Reference in New Issue
Block a user