Add default_domain_id for Keystone v3 deploys

The default_domain_id is used to specify a domain when the client
hasn't explicitly set one. It defaults to 'default' which is fine
for liberty and previous because the id of the default domain is,
 oddly, 'default' rather than a uuid. On Mitaka and higher it is
a uuid so when keystone assumes the default domains id is 'default'
it fails.

Change-Id: Iaa5e6a07a229815cf2281858cb68a4e120aa2af3
Closes-Bug: 1626889
This commit is contained in:
Liam Young 2016-09-23 09:05:46 +00:00
parent 5b6d669116
commit ccf153981f
4 changed files with 50 additions and 15 deletions

View File

@ -207,7 +207,7 @@ class KeystoneContext(context.OSContextGenerator):
from keystone_utils import (
api_port, set_admin_token, endpoint_url, resolve_address,
PUBLIC, ADMIN, PKI_CERTS_DIR, ensure_pki_cert_paths,
get_admin_domain_id
get_admin_domain_id, get_default_domain_id
)
ctxt = {}
ctxt['token'] = set_admin_token(config('admin-token'))
@ -216,6 +216,9 @@ class KeystoneContext(context.OSContextGenerator):
if ctxt['api_version'] > 2:
ctxt['admin_domain_id'] = (
get_admin_domain_id() or 'admin_domain_id')
# default is the default for default_domain_id
ctxt['default_domain_id'] = (
get_default_domain_id() or 'default')
ctxt['admin_port'] = determine_api_port(api_port('keystone-admin'),
singlenode_mode=True)
ctxt['public_port'] = determine_api_port(api_port('keystone-public'),

View File

@ -183,6 +183,7 @@ KEYSTONE_CONF_DIR = os.path.dirname(KEYSTONE_CONF)
STORED_PASSWD = "/var/lib/keystone/keystone.passwd"
STORED_TOKEN = "/var/lib/keystone/keystone.token"
STORED_ADMIN_DOMAIN_ID = "/var/lib/keystone/keystone.admin_domain_id"
STORED_DEFAULT_DOMAIN_ID = "/var/lib/keystone/keystone.default_domain_id"
SERVICE_PASSWD_PATH = '/var/lib/keystone/services.passwd'
HAPROXY_CONF = '/etc/haproxy/haproxy.cfg'
@ -877,14 +878,21 @@ def grant_role(user, role, tenant=None, domain=None, user_domain=None):
(user, role, tenant), level=DEBUG)
def store_data(backing_file, data):
with open(backing_file, 'w+') as fd:
fd.writelines("%s\n" % data)
def store_admin_passwd(passwd):
with open(STORED_PASSWD, 'w+') as fd:
fd.writelines("%s\n" % passwd)
store_data(STORED_PASSWD, passwd)
def store_admin_domain_id(domain_id):
with open(STORED_ADMIN_DOMAIN_ID, 'w+') as fd:
fd.writelines("%s\n" % domain_id)
store_data(STORED_ADMIN_DOMAIN_ID, domain_id)
def store_default_domain_id(domain_id):
store_data(STORED_DEFAULT_DOMAIN_ID, domain_id)
def get_admin_passwd():
@ -950,9 +958,10 @@ def ensure_initial_admin(config):
changes?
"""
if get_api_version() > 2:
create_or_show_domain(DEFAULT_DOMAIN)
domain_id = create_or_show_domain(ADMIN_DOMAIN)
store_admin_domain_id(domain_id)
default_domain_id = create_or_show_domain(DEFAULT_DOMAIN)
store_default_domain_id(default_domain_id)
admin_domain_id = create_or_show_domain(ADMIN_DOMAIN)
store_admin_domain_id(admin_domain_id)
create_tenant("admin")
create_tenant(config("service-tenant"))
# User is managed by ldap backend when using ldap identity
@ -2281,16 +2290,24 @@ def assess_status_func(configs):
ports=determine_ports())
def get_admin_domain_id():
def get_file_stored_domain_id(backing_file):
domain_id = None
if os.path.isfile(STORED_ADMIN_DOMAIN_ID):
log("Loading stored domain id from %s" % STORED_ADMIN_DOMAIN_ID,
if os.path.isfile(backing_file):
log("Loading stored domain id from {}".format(backing_file),
level=INFO)
with open(STORED_ADMIN_DOMAIN_ID, 'r') as fd:
with open(backing_file, 'r') as fd:
domain_id = fd.readline().strip('\n')
return domain_id
def get_admin_domain_id():
return get_file_stored_domain_id(STORED_ADMIN_DOMAIN_ID)
def get_default_domain_id():
return get_file_stored_domain_id(STORED_DEFAULT_DOMAIN_ID)
def pause_unit_helper(configs):
"""Helper function to pause a unit, and then call assess_status(...) in
effect, so that the status is correctly updated.

View File

@ -30,6 +30,9 @@ idle_timeout = 200
[identity]
driver = keystone.identity.backends.{{ identity_backend }}.Identity
{% if default_domain_id -%}
default_domain_id = {{ default_domain_id }}
{% endif -%}
[credential]
driver = keystone.credential.backends.sql.Credential

View File

@ -816,9 +816,9 @@ class TestKeystoneUtils(CharmTestCase):
mock_keystone.api.services.delete.assert_called_with('sid1')
@patch('os.path.isfile')
def test_get_admin_domain_id(self, isfile_mock):
def test_get_file_stored_domain_id(self, isfile_mock):
isfile_mock.return_value = False
x = utils.get_admin_domain_id()
x = utils.get_file_stored_domain_id('/a/file')
assert x is None
from sys import version_info
if version_info.major == 2:
@ -829,9 +829,21 @@ class TestKeystoneUtils(CharmTestCase):
with patch.object(builtins, 'open', mock_open(
read_data="some_data\n")):
isfile_mock.return_value = True
x = utils.get_admin_domain_id()
x = utils.get_file_stored_domain_id('/a/file')
self.assertEquals(x, 'some_data')
@patch.object(utils, 'get_file_stored_domain_id')
def test_get_admin_domain_id(self, mock_get_file_stored_domain_id):
utils.get_admin_domain_id()
mock_get_file_stored_domain_id.assert_called_with(
'/var/lib/keystone/keystone.admin_domain_id')
@patch.object(utils, 'get_file_stored_domain_id')
def test_get_default_domain_id(self, mock_get_file_stored_domain_id):
utils.get_default_domain_id()
mock_get_file_stored_domain_id.assert_called_with(
'/var/lib/keystone/keystone.default_domain_id')
def test_assess_status(self):
with patch.object(utils, 'assess_status_func') as asf:
callee = MagicMock()