Ensure bootstrap handles multiple roles with the same name

The bootstrap logic doesn't take into consideration multiple roles
with the same name. If bootstrap is unable to determine which role to
use and accidentally uses a domain-specific role with the same name
as a default role, bootstrap will fail in unexpected ways.

Closes-Bug: 1856881
Change-Id: Iddc364d8c934b6e54d1e8c75b8b159faadbf865d
(cherry picked from commit 25cf359e5f)
This commit is contained in:
Lance Bragstad 2019-12-18 11:59:53 -06:00
parent 1b967e0aad
commit 51ff7be731
3 changed files with 39 additions and 0 deletions

View File

@ -136,6 +136,14 @@ class Bootstrapper(object):
# name instead. # name instead.
hints = driver_hints.Hints() hints = driver_hints.Hints()
hints.add_filter('name', role_name) hints.add_filter('name', role_name)
# Only return global roles, domain-specific roles can't be used in
# system assignments and bootstrap isn't designed to work with
# domain-specific roles.
hints.add_filter('domain_id', None)
# NOTE(lbragstad): Global roles are unique based on name. At this
# point we should be safe to return the first, and only, element in
# the list.
return PROVIDERS.role_api.list_roles(hints)[0] return PROVIDERS.role_api.list_roles(hints)[0]
def _ensure_implied_role(self, prior_role_id, implied_role_id): def _ensure_implied_role(self, prior_role_id, implied_role_id):

View File

@ -311,6 +311,30 @@ class CliBootStrapTestCase(unit.SQLDriverOverrides, unit.TestCase):
self.assertTrue(member_role['options']['immutable']) self.assertTrue(member_role['options']['immutable'])
self.assertTrue(reader_role['options']['immutable']) self.assertTrue(reader_role['options']['immutable'])
def test_bootstrap_with_ambiguous_role_names(self):
# bootstrap system to create the default admin role
self._do_test_bootstrap(self.bootstrap)
# create a domain-specific roles that share the same names as the
# default roles created by keystone-manage bootstrap
domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
domain = PROVIDERS.resource_api.create_domain(domain['id'], domain)
domain_roles = {}
for name in ['admin', 'member', 'reader']:
domain_role = {
'domain_id': domain['id'],
'id': uuid.uuid4().hex,
'name': name
}
domain_roles[name] = PROVIDERS.role_api.create_role(
domain_role['id'], domain_role
)
# ensure subsequent bootstrap attempts don't fail because of
# ambiguity
self._do_test_bootstrap(self.bootstrap)
class CliBootStrapTestCaseWithEnvironment(CliBootStrapTestCase): class CliBootStrapTestCaseWithEnvironment(CliBootStrapTestCase):

View File

@ -0,0 +1,7 @@
---
fixes:
- |
[`bug 1856881 <https://bugs.launchpad.net/keystone/+bug/1856881>`_]
``keystone-manage bootstrap`` can be run in upgrade scenarios where
pre-existing domain-specific roles exist named ``admin``, ``member``, and
``reader``.