Add identity endpoint creation to bootstrap
To enable the bootstrapped admin user to perform identity operations we must also bootstrap the identity endpoint. Allow specifying service name, endpoint urls and region information to the bootstrap command. Change-Id: Ie78c61ecf1e5f787dd2528b887c1642fd8d457ff Closes-Bug: #1550057
This commit is contained in:
parent
432f5f2348
commit
64c94e74c9
|
@ -63,10 +63,17 @@ class BootStrap(BaseApp):
|
|||
self.load_backends()
|
||||
self.project_id = uuid.uuid4().hex
|
||||
self.role_id = uuid.uuid4().hex
|
||||
self.service_id = None
|
||||
self.service_name = None
|
||||
self.username = None
|
||||
self.project_name = None
|
||||
self.role_name = None
|
||||
self.password = None
|
||||
self.public_url = None
|
||||
self.internal_url = None
|
||||
self.admin_url = None
|
||||
self.region_id = None
|
||||
self.endpoints = {}
|
||||
|
||||
@classmethod
|
||||
def add_argument_parser(cls, subparsers):
|
||||
|
@ -88,6 +95,31 @@ class BootStrap(BaseApp):
|
|||
metavar='OS_BOOTSTRAP_ROLE_NAME',
|
||||
help=('The initial role-name created during the '
|
||||
'keystone bootstrap process.'))
|
||||
parser.add_argument('--bootstrap-service-name', default='keystone',
|
||||
metavar='OS_BOOTSTRAP_SERVICE_NAME',
|
||||
help=('The initial name for the initial identity '
|
||||
'service created during the keystone '
|
||||
'bootstrap process.'))
|
||||
parser.add_argument('--bootstrap-admin-url',
|
||||
metavar='OS_BOOTSTRAP_ADMIN_URL',
|
||||
help=('The initial identity admin url created '
|
||||
'during the keystone bootstrap process. '
|
||||
'e.g. http://127.0.0.1:35357/v2.0'))
|
||||
parser.add_argument('--bootstrap-public-url',
|
||||
metavar='OS_BOOTSTRAP_PUBLIC_URL',
|
||||
help=('The initial identity public url created '
|
||||
'during the keystone bootstrap process. '
|
||||
'e.g. http://127.0.0.1:5000/v2.0'))
|
||||
parser.add_argument('--bootstrap-internal-url',
|
||||
metavar='OS_BOOTSTRAP_INTERNAL_URL',
|
||||
help=('The initial identity internal url created '
|
||||
'during the keystone bootstrap process. '
|
||||
'e.g. http://127.0.0.1:5000/v2.0'))
|
||||
parser.add_argument('--bootstrap-region-id',
|
||||
metavar='OS_BOOTSTRAP_REGION_ID',
|
||||
help=('The initial region_id endpoints will be '
|
||||
'placed in during the keystone bootstrap '
|
||||
'process.'))
|
||||
return parser
|
||||
|
||||
def load_backends(self):
|
||||
|
@ -95,6 +127,7 @@ class BootStrap(BaseApp):
|
|||
self.resource_manager = drivers['resource_api']
|
||||
self.identity_manager = drivers['identity_api']
|
||||
self.assignment_manager = drivers['assignment_api']
|
||||
self.catalog_manager = drivers['catalog_api']
|
||||
self.role_manager = drivers['role_api']
|
||||
|
||||
def _get_config(self):
|
||||
|
@ -110,6 +143,21 @@ class BootStrap(BaseApp):
|
|||
self.password = (
|
||||
os.environ.get('OS_BOOTSTRAP_PASSWORD') or
|
||||
CONF.command.bootstrap_password)
|
||||
self.service_name = (
|
||||
os.environ.get('OS_BOOTSTRAP_SERVICE_NAME') or
|
||||
CONF.command.bootstrap_service_name)
|
||||
self.admin_url = (
|
||||
os.environ.get('OS_BOOTSTRAP_ADMIN_URL') or
|
||||
CONF.command.bootstrap_admin_url)
|
||||
self.public_url = (
|
||||
os.environ.get('OS_BOOTSTRAP_PUBLIC_URL') or
|
||||
CONF.command.bootstrap_public_url)
|
||||
self.internal_url = (
|
||||
os.environ.get('OS_BOOTSTRAP_INTERNAL_URL') or
|
||||
CONF.command.bootstrap_internal_url)
|
||||
self.region_id = (
|
||||
os.environ.get('OS_BOOTSTRAP_REGION_ID') or
|
||||
CONF.command.bootstrap_region_id)
|
||||
|
||||
def do_bootstrap(self):
|
||||
"""Perform the bootstrap actions.
|
||||
|
@ -215,6 +263,80 @@ class BootStrap(BaseApp):
|
|||
'role': self.role_name,
|
||||
'project': self.project_name})
|
||||
|
||||
if self.region_id:
|
||||
try:
|
||||
self.catalog_manager.create_region(
|
||||
region_ref={'id': self.region_id}
|
||||
)
|
||||
LOG.info(_LI('Created Region %s'), self.region_id)
|
||||
except exception.Conflict:
|
||||
LOG.info(_LI('Region %s exists, skipping creation.'),
|
||||
self.region_id)
|
||||
|
||||
if self.public_url or self.admin_url or self.internal_url:
|
||||
hints = driver_hints.Hints()
|
||||
hints.add_filter('type', 'identity')
|
||||
services = self.catalog_manager.list_services(hints)
|
||||
|
||||
if services:
|
||||
service_ref = services[0]
|
||||
|
||||
hints = driver_hints.Hints()
|
||||
hints.add_filter('service_id', service_ref['id'])
|
||||
if self.region_id:
|
||||
hints.add_filter('region_id', self.region_id)
|
||||
|
||||
endpoints = self.catalog_manager.list_endpoints(hints)
|
||||
else:
|
||||
service_ref = {'id': uuid.uuid4().hex,
|
||||
'name': self.service_name,
|
||||
'type': 'identity',
|
||||
'enabled': True}
|
||||
|
||||
self.catalog_manager.create_service(
|
||||
service_id=service_ref['id'],
|
||||
service_ref=service_ref)
|
||||
|
||||
endpoints = []
|
||||
|
||||
self.service_id = service_ref['id']
|
||||
|
||||
available_interfaces = {e['interface']: e for e in endpoints}
|
||||
expected_endpoints = {'public': self.public_url,
|
||||
'internal': self.internal_url,
|
||||
'admin': self.admin_url}
|
||||
|
||||
for interface, url in expected_endpoints.items():
|
||||
if not url:
|
||||
# not specified to bootstrap command
|
||||
continue
|
||||
|
||||
try:
|
||||
endpoint_ref = available_interfaces[interface]
|
||||
except KeyError:
|
||||
endpoint_ref = {'id': uuid.uuid4().hex,
|
||||
'interface': interface,
|
||||
'url': url,
|
||||
'service_id': self.service_id,
|
||||
'enabled': True}
|
||||
|
||||
if self.region_id:
|
||||
endpoint_ref['region_id'] = self.region_id
|
||||
|
||||
self.catalog_manager.create_endpoint(
|
||||
endpoint_id=endpoint_ref['id'],
|
||||
endpoint_ref=endpoint_ref)
|
||||
|
||||
LOG.info(_LI('Created %(interface)s endpoint %(url)s'),
|
||||
{'interface': interface, 'url': url})
|
||||
else:
|
||||
# NOTE(jamielennox): electing not to update existing
|
||||
# endpoints here. There may be call to do so in future.
|
||||
LOG.info(_LI('Skipping %s endpoint as already created'),
|
||||
interface)
|
||||
|
||||
self.endpoints[interface] = endpoint_ref['id']
|
||||
|
||||
@classmethod
|
||||
def main(cls):
|
||||
klass = cls()
|
||||
|
|
|
@ -87,6 +87,30 @@ class CliBootStrapTestCase(unit.SQLDriverOverrides, unit.TestCase):
|
|||
user['id'],
|
||||
bootstrap.password)
|
||||
|
||||
if bootstrap.region_id:
|
||||
region = bootstrap.catalog_manager.get_region(bootstrap.region_id)
|
||||
self.assertEqual(self.region_id, region['id'])
|
||||
|
||||
if bootstrap.service_id:
|
||||
svc = bootstrap.catalog_manager.get_service(bootstrap.service_id)
|
||||
self.assertEqual(self.service_name, svc['name'])
|
||||
|
||||
self.assertEqual(set(['admin', 'public', 'internal']),
|
||||
set(bootstrap.endpoints))
|
||||
|
||||
urls = {'public': self.public_url,
|
||||
'internal': self.internal_url,
|
||||
'admin': self.admin_url}
|
||||
|
||||
for interface, url in urls.items():
|
||||
endpoint_id = bootstrap.endpoints[interface]
|
||||
endpoint = bootstrap.catalog_manager.get_endpoint(endpoint_id)
|
||||
|
||||
self.assertEqual(self.region_id, endpoint['region_id'])
|
||||
self.assertEqual(url, endpoint['url'])
|
||||
self.assertEqual(svc['id'], endpoint['service_id'])
|
||||
self.assertEqual(interface, endpoint['interface'])
|
||||
|
||||
def test_bootstrap_is_idempotent(self):
|
||||
# NOTE(morganfainberg): Ensure we can run bootstrap multiple times
|
||||
# without erroring.
|
||||
|
@ -107,6 +131,11 @@ class CliBootStrapTestCaseWithEnvironment(CliBootStrapTestCase):
|
|||
self.username = uuid.uuid4().hex
|
||||
self.project_name = uuid.uuid4().hex
|
||||
self.role_name = uuid.uuid4().hex
|
||||
self.service_name = uuid.uuid4().hex
|
||||
self.public_url = uuid.uuid4().hex
|
||||
self.internal_url = uuid.uuid4().hex
|
||||
self.admin_url = uuid.uuid4().hex
|
||||
self.region_id = uuid.uuid4().hex
|
||||
self.default_domain = {
|
||||
'id': CONF.identity.default_domain_id,
|
||||
'name': 'Default',
|
||||
|
@ -123,6 +152,21 @@ class CliBootStrapTestCaseWithEnvironment(CliBootStrapTestCase):
|
|||
self.useFixture(
|
||||
fixtures.EnvironmentVariable('OS_BOOTSTRAP_ROLE_NAME',
|
||||
newvalue=self.role_name))
|
||||
self.useFixture(
|
||||
fixtures.EnvironmentVariable('OS_BOOTSTRAP_SERVICE_NAME',
|
||||
newvalue=self.service_name))
|
||||
self.useFixture(
|
||||
fixtures.EnvironmentVariable('OS_BOOTSTRAP_PUBLIC_URL',
|
||||
newvalue=self.public_url))
|
||||
self.useFixture(
|
||||
fixtures.EnvironmentVariable('OS_BOOTSTRAP_INTERNAL_URL',
|
||||
newvalue=self.internal_url))
|
||||
self.useFixture(
|
||||
fixtures.EnvironmentVariable('OS_BOOTSTRAP_ADMIN_URL',
|
||||
newvalue=self.admin_url))
|
||||
self.useFixture(
|
||||
fixtures.EnvironmentVariable('OS_BOOTSTRAP_REGION_ID',
|
||||
newvalue=self.region_id))
|
||||
|
||||
def test_assignment_created_with_user_exists(self):
|
||||
# test assignment can be created if user already exists.
|
||||
|
@ -155,6 +199,43 @@ class CliBootStrapTestCaseWithEnvironment(CliBootStrapTestCase):
|
|||
bootstrap.role_manager.create_role(role['id'], role)
|
||||
self._do_test_bootstrap(bootstrap)
|
||||
|
||||
def test_assignment_created_with_region_exists(self):
|
||||
# test assignment can be created if role already exists.
|
||||
bootstrap = cli.BootStrap()
|
||||
bootstrap.resource_manager.create_domain(self.default_domain['id'],
|
||||
self.default_domain)
|
||||
region = unit.new_region_ref(id=self.region_id)
|
||||
bootstrap.catalog_manager.create_region(region)
|
||||
self._do_test_bootstrap(bootstrap)
|
||||
|
||||
def test_endpoints_created_with_service_exists(self):
|
||||
# test assignment can be created if role already exists.
|
||||
bootstrap = cli.BootStrap()
|
||||
bootstrap.resource_manager.create_domain(self.default_domain['id'],
|
||||
self.default_domain)
|
||||
service = unit.new_service_ref(name=self.service_name)
|
||||
bootstrap.catalog_manager.create_service(service['id'], service)
|
||||
self._do_test_bootstrap(bootstrap)
|
||||
|
||||
def test_endpoints_created_with_endpoint_exists(self):
|
||||
# test assignment can be created if role already exists.
|
||||
bootstrap = cli.BootStrap()
|
||||
bootstrap.resource_manager.create_domain(self.default_domain['id'],
|
||||
self.default_domain)
|
||||
service = unit.new_service_ref(name=self.service_name)
|
||||
bootstrap.catalog_manager.create_service(service['id'], service)
|
||||
|
||||
region = unit.new_region_ref(id=self.region_id)
|
||||
bootstrap.catalog_manager.create_region(region)
|
||||
|
||||
endpoint = unit.new_endpoint_ref(interface='public',
|
||||
service_id=service['id'],
|
||||
url=self.public_url,
|
||||
region_id=self.region_id)
|
||||
bootstrap.catalog_manager.create_endpoint(endpoint['id'], endpoint)
|
||||
|
||||
self._do_test_bootstrap(bootstrap)
|
||||
|
||||
|
||||
class CliDomainConfigAllTestCase(unit.SQLDriverOverrides, unit.TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue