Add --immutable-roles flag to bootstrap command

This implements Step 2 of the Proposed Change for Immutable
Resources[1].

[1] http://specs.openstack.org/openstack/keystone-specs/specs/keystone/train/immutable-resources.html#proposed-change

Change-Id: I4d99f630cb16e1d58261012e59d3a92c7035734c
Partial-bug: #1823258
This commit is contained in:
Colleen Murphy 2019-08-07 16:22:05 -07:00
parent a38d4a650f
commit a80d83e76d
3 changed files with 40 additions and 0 deletions

View File

@ -56,6 +56,8 @@ class Bootstrapper(object):
self.default_domain_id = None
self.admin_user_id = None
self.immutable_roles = False
def bootstrap(self):
# NOTE(morganfainberg): Ensure the default domain is in-fact created
self._bootstrap_default_domain()
@ -114,8 +116,18 @@ class Bootstrapper(object):
try:
role_id = uuid.uuid4().hex
role = {'name': role_name, 'id': role_id}
if self.immutable_roles:
role['options'] = {'immutable': True}
role = PROVIDERS.role_api.create_role(role_id, role)
LOG.info('Created role %s', role_name)
if not self.immutable_roles:
LOG.warning("Role %(role)s was created as a mutable role. It "
"is recommended to make this role immutable, "
"which will become the default behavior of the "
"bootstrap command in the future.You can opt into "
"this behavior by using the --immutable-role "
"flag, or update role %(role)s with the "
"'immutable' resource option.", {'role': role_name})
return role
except exception.Conflict:
LOG.info('Role %s exists, skipping creation.', role_name)

View File

@ -111,6 +111,14 @@ class BootStrap(BaseApp):
help=('The initial region_id endpoints will be '
'placed in during the keystone bootstrap '
'process.'))
parser.add_argument('--immutable-roles',
default=False,
action='store_true',
help=('Whether default roles (admin, member, and '
'reader) should be immutable. Immutable '
'default roles is currently an opt-in '
'behavior, but will become the default in '
'future releases.'))
return parser
def do_bootstrap(self):
@ -166,6 +174,7 @@ class BootStrap(BaseApp):
self.bootstrapper.public_url = self.public_url
self.bootstrapper.internal_url = self.internal_url
self.bootstrapper.region_id = self.region_id
self.bootstrapper.immutable_roles = CONF.command.immutable_roles
self.bootstrapper.bootstrap()
self.reader_role_id = self.bootstrapper.reader_role_id

View File

@ -219,6 +219,12 @@ class CliBootStrapTestCase(unit.SQLDriverOverrides, unit.TestCase):
c.get('/v3/auth/tokens',
headers={'X-Auth-Token': r.headers['X-Subject-Token'],
'X-Subject-Token': token})
admin_role = PROVIDERS.role_api.get_role(self.bootstrap.role_id)
reader_role = PROVIDERS.role_api.get_role(self.bootstrap.reader_role_id)
member_role = PROVIDERS.role_api.get_role(self.bootstrap.member_role_id)
self.assertEqual(admin_role['options'], {})
self.assertEqual(member_role['options'], {})
self.assertEqual(reader_role['options'], {})
def test_bootstrap_is_not_idempotent_when_password_does_change(self):
# NOTE(lbragstad): Ensure bootstrap isn't idempotent when run with
@ -292,6 +298,19 @@ class CliBootStrapTestCase(unit.SQLDriverOverrides, unit.TestCase):
user_id,
self.bootstrap.password)
def test_bootstrap_with_immutable_roles(self):
CONF(args=['bootstrap',
'--bootstrap-password', uuid.uuid4().hex,
'--immutable-roles'],
project='keystone')
self._do_test_bootstrap(self.bootstrap)
admin_role = PROVIDERS.role_api.get_role(self.bootstrap.role_id)
reader_role = PROVIDERS.role_api.get_role(self.bootstrap.reader_role_id)
member_role = PROVIDERS.role_api.get_role(self.bootstrap.member_role_id)
self.assertTrue(admin_role['options']['immutable'])
self.assertTrue(member_role['options']['immutable'])
self.assertTrue(reader_role['options']['immutable'])
class CliBootStrapTestCaseWithEnvironment(CliBootStrapTestCase):