Create identity-credentials relation
Charms use this relation to obtain keystone credentials without creating a service catalog entry. Set 'username' only on the relation and keystone will set defaults and return authentication details. Possible relation settings: username: Username to be created. project: Project (tenant) name to be created. Defaults to services project. requested_roles: Comma delimited list of roles to be created requested_grants: Comma delimited list of roles to be granted. Defaults to Admin role. domain: Keystone v3 domain the user will be created in. Defaults to the Default domain. Change-Id: I465d2273560d86752d1bfc7497a9139a9604f814
This commit is contained in:
parent
6370c98e55
commit
30a5fe0999
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,5 +5,6 @@ bin
|
|||||||
tags
|
tags
|
||||||
*.sw[nop]
|
*.sw[nop]
|
||||||
*.pyc
|
*.pyc
|
||||||
|
joined-string
|
||||||
.unit-state.db
|
.unit-state.db
|
||||||
trusty/**
|
trusty/**
|
||||||
|
13
README.md
13
README.md
@ -37,6 +37,19 @@ The following interfaces are provided:
|
|||||||
- identity-notifications: Used to broadcast messages to any services
|
- identity-notifications: Used to broadcast messages to any services
|
||||||
listening on the interface.
|
listening on the interface.
|
||||||
|
|
||||||
|
- identity-credentials: Charms use this relation to obtain keystone
|
||||||
|
credentials without creating a service catalog entry. Set 'username'
|
||||||
|
only on the relation and keystone will set defaults and return
|
||||||
|
authentication details. Possible relation settings:
|
||||||
|
username: Username to be created.
|
||||||
|
project: Project (tenant) name to be created. Defaults to services
|
||||||
|
project.
|
||||||
|
requested_roles: Comma delimited list of roles to be created
|
||||||
|
requested_grants: Comma delimited list of roles to be granted.
|
||||||
|
Defaults to Admin role.
|
||||||
|
domain: Keystone v3 domain the user will be created in. Defaults
|
||||||
|
to the Default domain.
|
||||||
|
|
||||||
Database
|
Database
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
1
hooks/identity-credentials-relation-changed
Symbolic link
1
hooks/identity-credentials-relation-changed
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
keystone_hooks.py
|
1
hooks/identity-credentials-relation-joined
Symbolic link
1
hooks/identity-credentials-relation-joined
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
keystone_hooks.py
|
@ -54,6 +54,7 @@ from charmhelpers.contrib.openstack.utils import (
|
|||||||
|
|
||||||
from keystone_utils import (
|
from keystone_utils import (
|
||||||
add_service_to_keystone,
|
add_service_to_keystone,
|
||||||
|
add_credentials_to_keystone,
|
||||||
determine_packages,
|
determine_packages,
|
||||||
do_openstack_upgrade_reexec,
|
do_openstack_upgrade_reexec,
|
||||||
ensure_initial_admin,
|
ensure_initial_admin,
|
||||||
@ -205,9 +206,6 @@ def config_changed_postupgrade():
|
|||||||
|
|
||||||
update_all_identity_relation_units()
|
update_all_identity_relation_units()
|
||||||
|
|
||||||
for rid in relation_ids('identity-admin'):
|
|
||||||
admin_relation_changed(rid)
|
|
||||||
|
|
||||||
# Ensure sync request is sent out (needed for any/all ssl change)
|
# Ensure sync request is sent out (needed for any/all ssl change)
|
||||||
send_ssl_sync_request()
|
send_ssl_sync_request()
|
||||||
|
|
||||||
@ -298,6 +296,13 @@ def update_all_identity_relation_units(check_db_ready=True):
|
|||||||
for rid in relation_ids('identity-service'):
|
for rid in relation_ids('identity-service'):
|
||||||
for unit in related_units(rid):
|
for unit in related_units(rid):
|
||||||
identity_changed(relation_id=rid, remote_unit=unit)
|
identity_changed(relation_id=rid, remote_unit=unit)
|
||||||
|
log('Firing admin_relation_changed hook for all related services.')
|
||||||
|
for rid in relation_ids('identity-admin'):
|
||||||
|
admin_relation_changed(rid)
|
||||||
|
log('Firing identity_credentials_changed hook for all related services.')
|
||||||
|
for rid in relation_ids('identity-credentials'):
|
||||||
|
for unit in related_units(rid):
|
||||||
|
identity_credentials_changed(relation_id=rid, remote_unit=unit)
|
||||||
|
|
||||||
|
|
||||||
@synchronize_ca_if_changed(force=True)
|
@synchronize_ca_if_changed(force=True)
|
||||||
@ -408,6 +413,33 @@ def identity_changed(relation_id=None, remote_unit=None):
|
|||||||
send_notifications(notifications)
|
send_notifications(notifications)
|
||||||
|
|
||||||
|
|
||||||
|
@hooks.hook('identity-credentials-relation-joined',
|
||||||
|
'identity-credentials-relation-changed')
|
||||||
|
def identity_credentials_changed(relation_id=None, remote_unit=None):
|
||||||
|
"""Update the identity credentials relation on change
|
||||||
|
|
||||||
|
Calls add_credentials_to_keystone
|
||||||
|
|
||||||
|
:param relation_id: Relation id of the relation
|
||||||
|
:param remote_unit: Related unit on the relation
|
||||||
|
"""
|
||||||
|
if is_elected_leader(CLUSTER_RES):
|
||||||
|
if not is_db_ready():
|
||||||
|
log("identity-credentials-relation-changed hook fired before db "
|
||||||
|
"ready - deferring until db ready", level=WARNING)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not is_db_initialised():
|
||||||
|
log("Database not yet initialised - deferring "
|
||||||
|
"identity-credentials-relation updates", level=INFO)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create the tenant user
|
||||||
|
add_credentials_to_keystone(relation_id, remote_unit)
|
||||||
|
else:
|
||||||
|
log('Deferring identity_credentials_changed() to service leader.')
|
||||||
|
|
||||||
|
|
||||||
def send_ssl_sync_request():
|
def send_ssl_sync_request():
|
||||||
"""Set sync request on cluster relation.
|
"""Set sync request on cluster relation.
|
||||||
|
|
||||||
@ -511,9 +543,6 @@ def cluster_changed():
|
|||||||
else:
|
else:
|
||||||
update_all_identity_relation_units()
|
update_all_identity_relation_units()
|
||||||
|
|
||||||
for rid in relation_ids('identity-admin'):
|
|
||||||
admin_relation_changed(rid)
|
|
||||||
|
|
||||||
if not is_elected_leader(CLUSTER_RES) and is_ssl_cert_master():
|
if not is_elected_leader(CLUSTER_RES) and is_ssl_cert_master():
|
||||||
# Force and sync and trigger a sync master re-election since we are not
|
# Force and sync and trigger a sync master re-election since we are not
|
||||||
# leader anymore.
|
# leader anymore.
|
||||||
@ -537,10 +566,7 @@ def leader_settings_changed():
|
|||||||
# sure only the leader is running the cron job.
|
# sure only the leader is running the cron job.
|
||||||
CONFIGS.write(TOKEN_FLUSH_CRON_FILE)
|
CONFIGS.write(TOKEN_FLUSH_CRON_FILE)
|
||||||
|
|
||||||
log('Firing identity_changed hook for all related services.')
|
update_all_identity_relation_units()
|
||||||
for rid in relation_ids('identity-service'):
|
|
||||||
for unit in related_units(rid):
|
|
||||||
identity_changed(relation_id=rid, remote_unit=unit)
|
|
||||||
|
|
||||||
|
|
||||||
@hooks.hook('ha-relation-joined')
|
@hooks.hook('ha-relation-joined')
|
||||||
|
@ -1610,10 +1610,8 @@ def add_service_to_keystone(relation_id=None, remote_unit=None):
|
|||||||
'internal_url'])
|
'internal_url'])
|
||||||
https_cns = []
|
https_cns = []
|
||||||
|
|
||||||
if https():
|
protocol = get_protocol()
|
||||||
protocol = 'https'
|
|
||||||
else:
|
|
||||||
protocol = 'http'
|
|
||||||
if single.issubset(settings):
|
if single.issubset(settings):
|
||||||
# other end of relation advertised only one endpoint
|
# other end of relation advertised only one endpoint
|
||||||
if 'None' in settings.itervalues():
|
if 'None' in settings.itervalues():
|
||||||
@ -1630,15 +1628,8 @@ def add_service_to_keystone(relation_id=None, remote_unit=None):
|
|||||||
relation_data["service_port"] = config('service-port')
|
relation_data["service_port"] = config('service-port')
|
||||||
relation_data["region"] = config('region')
|
relation_data["region"] = config('region')
|
||||||
|
|
||||||
https_service_endpoints = config('https-service-endpoints')
|
# Get and pass CA bundle settings
|
||||||
if (https_service_endpoints and
|
relation_data.update(get_ssl_ca_settings())
|
||||||
bool_from_string(https_service_endpoints)):
|
|
||||||
# Pass CA cert as client will need it to
|
|
||||||
# verify https connections
|
|
||||||
ca = get_ca(user=SSH_USER)
|
|
||||||
ca_bundle = ca.get_ca_bundle()
|
|
||||||
relation_data['https_keystone'] = 'True'
|
|
||||||
relation_data['ca_cert'] = b64encode(ca_bundle)
|
|
||||||
|
|
||||||
# Allow the remote service to request creation of any additional
|
# Allow the remote service to request creation of any additional
|
||||||
# roles. Currently used by Horizon
|
# roles. Currently used by Horizon
|
||||||
@ -1779,9 +1770,9 @@ def add_service_to_keystone(relation_id=None, remote_unit=None):
|
|||||||
cert, key = ca.get_cert_and_key(common_name=internal_cn)
|
cert, key = ca.get_cert_and_key(common_name=internal_cn)
|
||||||
relation_data['ssl_cert'] = b64encode(cert)
|
relation_data['ssl_cert'] = b64encode(cert)
|
||||||
relation_data['ssl_key'] = b64encode(key)
|
relation_data['ssl_key'] = b64encode(key)
|
||||||
ca_bundle = ca.get_ca_bundle()
|
|
||||||
relation_data['ca_cert'] = b64encode(ca_bundle)
|
# Get and pass CA bundle settings
|
||||||
relation_data['https_keystone'] = 'True'
|
relation_data.update(get_ssl_ca_settings())
|
||||||
|
|
||||||
peer_store_and_set(relation_id=relation_id, **relation_data)
|
peer_store_and_set(relation_id=relation_id, **relation_data)
|
||||||
# NOTE(dosaboy): '__null__' settings are for peer relation only so that
|
# NOTE(dosaboy): '__null__' settings are for peer relation only so that
|
||||||
@ -1790,6 +1781,97 @@ def add_service_to_keystone(relation_id=None, remote_unit=None):
|
|||||||
relation_set(relation_id=relation_id, **filtered)
|
relation_set(relation_id=relation_id, **filtered)
|
||||||
|
|
||||||
|
|
||||||
|
def add_credentials_to_keystone(relation_id=None, remote_unit=None):
|
||||||
|
"""Add authentication credentials without a service endpoint
|
||||||
|
|
||||||
|
Creates credentials and then peer stores and relation sets them
|
||||||
|
|
||||||
|
:param relation_id: Relation id of the relation
|
||||||
|
:param remote_unit: Related unit on the relation
|
||||||
|
"""
|
||||||
|
manager = get_manager()
|
||||||
|
settings = relation_get(rid=relation_id, unit=remote_unit)
|
||||||
|
|
||||||
|
credentials_username = settings.get('username')
|
||||||
|
if not credentials_username:
|
||||||
|
log("identity-credentials peer has not yet set username")
|
||||||
|
return
|
||||||
|
|
||||||
|
if get_api_version() == 2:
|
||||||
|
domain = None
|
||||||
|
else:
|
||||||
|
domain = settings.get('domain') or DEFAULT_DOMAIN
|
||||||
|
|
||||||
|
# Use passed project or the service project
|
||||||
|
credentials_project = settings.get('project') or config('service-tenant')
|
||||||
|
create_tenant(credentials_project)
|
||||||
|
|
||||||
|
# Use passed grants or default to granting the Admin role
|
||||||
|
credentials_grants = (get_requested_grants(settings) or
|
||||||
|
[config('admin-role')])
|
||||||
|
|
||||||
|
# Create the user
|
||||||
|
credentials_password = create_user_credentials(
|
||||||
|
credentials_username,
|
||||||
|
get_service_password(credentials_username),
|
||||||
|
project=credentials_project,
|
||||||
|
new_roles=get_requested_roles(settings),
|
||||||
|
grants=credentials_grants,
|
||||||
|
domain=domain)
|
||||||
|
|
||||||
|
protocol = get_protocol()
|
||||||
|
|
||||||
|
relation_data = {
|
||||||
|
"auth_host": resolve_address(ADMIN),
|
||||||
|
"credentials_host": resolve_address(PUBLIC),
|
||||||
|
"credentials_port": config("service-port"),
|
||||||
|
"auth_port": config("admin-port"),
|
||||||
|
"credentials_username": credentials_username,
|
||||||
|
"credentials_password": credentials_password,
|
||||||
|
"credentials_project": credentials_project,
|
||||||
|
"credentials_project_id":
|
||||||
|
manager.resolve_tenant_id(credentials_project),
|
||||||
|
"auth_protocol": protocol,
|
||||||
|
"credentials_protocol": protocol,
|
||||||
|
"api_version": get_api_version(),
|
||||||
|
"region": config('region')
|
||||||
|
}
|
||||||
|
# Get and pass CA bundle settings
|
||||||
|
relation_data.update(get_ssl_ca_settings())
|
||||||
|
|
||||||
|
peer_store_and_set(relation_id=relation_id, **relation_data)
|
||||||
|
|
||||||
|
|
||||||
|
def get_ssl_ca_settings():
|
||||||
|
""" Get the Certificate Authority settings required to use the CA
|
||||||
|
|
||||||
|
:returns: Dictionary with https_keystone and ca_cert set
|
||||||
|
"""
|
||||||
|
ca_data = {}
|
||||||
|
https_service_endpoints = config('https-service-endpoints')
|
||||||
|
if (https_service_endpoints and
|
||||||
|
bool_from_string(https_service_endpoints)):
|
||||||
|
# Pass CA cert as client will need it to
|
||||||
|
# verify https connections
|
||||||
|
ca = get_ca(user=SSH_USER)
|
||||||
|
ca_bundle = ca.get_ca_bundle()
|
||||||
|
ca_data['https_keystone'] = 'True'
|
||||||
|
ca_data['ca_cert'] = b64encode(ca_bundle)
|
||||||
|
return ca_data
|
||||||
|
|
||||||
|
|
||||||
|
def get_protocol():
|
||||||
|
"""Determine the http protocol
|
||||||
|
|
||||||
|
:returns: http or https
|
||||||
|
"""
|
||||||
|
if https():
|
||||||
|
protocol = 'https'
|
||||||
|
else:
|
||||||
|
protocol = 'http'
|
||||||
|
return protocol
|
||||||
|
|
||||||
|
|
||||||
def ensure_valid_service(service):
|
def ensure_valid_service(service):
|
||||||
if service not in valid_services.keys():
|
if service not in valid_services.keys():
|
||||||
log("Invalid service requested: '%s'" % service)
|
log("Invalid service requested: '%s'" % service)
|
||||||
@ -1816,6 +1898,20 @@ def get_requested_roles(settings):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def get_requested_grants(settings):
|
||||||
|
"""Retrieve any valid requested_grants from dict settings
|
||||||
|
|
||||||
|
:param settings: dictionary which may contain key, requested_grants,
|
||||||
|
with comma delimited list of roles to grant.
|
||||||
|
:returns: list of roles to grant
|
||||||
|
"""
|
||||||
|
if ('requested_grants' in settings and
|
||||||
|
settings['requested_grants'] not in ['None', None]):
|
||||||
|
return settings['requested_grants'].split(',')
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
def setup_ipv6():
|
def setup_ipv6():
|
||||||
"""Check ipv6-mode validity and setup dependencies"""
|
"""Check ipv6-mode validity and setup dependencies"""
|
||||||
ubuntu_rel = lsb_release()['DISTRIB_CODENAME'].lower()
|
ubuntu_rel = lsb_release()['DISTRIB_CODENAME'].lower()
|
||||||
@ -1967,10 +2063,10 @@ def git_pre_install():
|
|||||||
add_user_to_group('keystone', 'keystone')
|
add_user_to_group('keystone', 'keystone')
|
||||||
|
|
||||||
for d in dirs:
|
for d in dirs:
|
||||||
mkdir(d, owner='keystone', group='keystone', perms=0755, force=False)
|
mkdir(d, owner='keystone', group='keystone', perms=0o755, force=False)
|
||||||
|
|
||||||
for l in logs:
|
for l in logs:
|
||||||
write_file(l, '', owner='keystone', group='keystone', perms=0600)
|
write_file(l, '', owner='keystone', group='keystone', perms=0o600)
|
||||||
|
|
||||||
|
|
||||||
def git_post_install(projects_yaml):
|
def git_post_install(projects_yaml):
|
||||||
|
@ -23,6 +23,8 @@ provides:
|
|||||||
interface: keystone-notifications
|
interface: keystone-notifications
|
||||||
identity-admin:
|
identity-admin:
|
||||||
interface: keystone-admin
|
interface: keystone-admin
|
||||||
|
identity-credentials:
|
||||||
|
interface: keystone-credentials
|
||||||
requires:
|
requires:
|
||||||
shared-db:
|
shared-db:
|
||||||
interface: mysql-shared
|
interface: mysql-shared
|
||||||
|
@ -273,105 +273,31 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
configs.write = MagicMock()
|
configs.write = MagicMock()
|
||||||
hooks.pgsql_db_changed()
|
hooks.pgsql_db_changed()
|
||||||
|
|
||||||
@patch('keystone_utils.relation_ids')
|
@patch.object(hooks, 'leader_init_db_if_ready')
|
||||||
@patch('keystone_utils.peer_retrieve')
|
|
||||||
@patch('keystone_utils.peer_store')
|
|
||||||
@patch('keystone_utils.log')
|
|
||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
@patch.object(hooks, 'CONFIGS')
|
@patch.object(hooks, 'CONFIGS')
|
||||||
@patch.object(hooks, 'identity_changed')
|
def test_db_changed(self, configs,
|
||||||
def test_db_changed_allowed(self, identity_changed, configs,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_ensure_ssl_cert_master, mock_log,
|
leader_init):
|
||||||
mock_peer_store,
|
|
||||||
mock_peer_retrieve, mock_relation_ids):
|
|
||||||
mock_relation_ids.return_value = ['peer/0']
|
|
||||||
peer_settings = {}
|
|
||||||
|
|
||||||
def fake_peer_store(key, val):
|
|
||||||
peer_settings[key] = val
|
|
||||||
|
|
||||||
def fake_migrate():
|
|
||||||
fake_peer_store('db-initialised', 'True')
|
|
||||||
|
|
||||||
self.migrate_database.side_effect = fake_migrate
|
|
||||||
mock_peer_store.side_effect = fake_peer_store
|
|
||||||
mock_peer_retrieve.side_effect = lambda key: peer_settings.get(key)
|
|
||||||
|
|
||||||
self.is_db_ready.return_value = True
|
|
||||||
mock_ensure_ssl_cert_master.return_value = False
|
mock_ensure_ssl_cert_master.return_value = False
|
||||||
self.relation_ids.return_value = ['identity-service:0']
|
|
||||||
self.related_units.return_value = ['unit/0']
|
|
||||||
|
|
||||||
self._shared_db_test(configs, 'keystone/3')
|
self._shared_db_test(configs, 'keystone/3')
|
||||||
self.assertEquals([call('/etc/keystone/keystone.conf')],
|
self.assertEquals([call('/etc/keystone/keystone.conf')],
|
||||||
configs.write.call_args_list)
|
configs.write.call_args_list)
|
||||||
self.migrate_database.assert_called_with()
|
self.assertTrue(leader_init.called)
|
||||||
self.assertTrue(self.ensure_initial_admin.called)
|
|
||||||
identity_changed.assert_called_with(
|
|
||||||
relation_id='identity-service:0',
|
|
||||||
remote_unit='unit/0')
|
|
||||||
|
|
||||||
@patch('keystone_utils.relation_ids')
|
@patch.object(hooks, 'leader_init_db_if_ready')
|
||||||
@patch('keystone_utils.log')
|
|
||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
@patch.object(hooks, 'CONFIGS')
|
@patch.object(hooks, 'CONFIGS')
|
||||||
@patch.object(hooks, 'identity_changed')
|
def test_postgresql_db_changed(self, configs,
|
||||||
def test_db_changed_not_allowed(self, identity_changed, configs,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_ensure_ssl_cert_master, mock_log,
|
leader_init):
|
||||||
mock_relation_ids):
|
|
||||||
mock_relation_ids.return_value = []
|
|
||||||
self.is_db_ready.return_value = False
|
|
||||||
mock_ensure_ssl_cert_master.return_value = False
|
mock_ensure_ssl_cert_master.return_value = False
|
||||||
self.relation_ids.return_value = ['identity-service:0']
|
|
||||||
self.related_units.return_value = ['unit/0']
|
|
||||||
|
|
||||||
self._shared_db_test(configs, 'keystone/2')
|
|
||||||
self.assertEquals([call('/etc/keystone/keystone.conf')],
|
|
||||||
configs.write.call_args_list)
|
|
||||||
self.assertFalse(self.migrate_database.called)
|
|
||||||
self.assertFalse(self.ensure_initial_admin.called)
|
|
||||||
self.assertFalse(identity_changed.called)
|
|
||||||
|
|
||||||
@patch('keystone_utils.relation_ids')
|
|
||||||
@patch('keystone_utils.peer_retrieve')
|
|
||||||
@patch('keystone_utils.peer_store')
|
|
||||||
@patch('keystone_utils.log')
|
|
||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
|
||||||
@patch.object(hooks, 'CONFIGS')
|
|
||||||
@patch.object(hooks, 'identity_changed')
|
|
||||||
def test_postgresql_db_changed(self, identity_changed, configs,
|
|
||||||
mock_ensure_ssl_cert_master, mock_log,
|
|
||||||
mock_peer_store, mock_peer_retrieve,
|
|
||||||
mock_relation_ids):
|
|
||||||
self.os_release.return_value = 'kilo'
|
|
||||||
mock_relation_ids.return_value = ['peer/0']
|
|
||||||
|
|
||||||
peer_settings = {}
|
|
||||||
|
|
||||||
def fake_peer_store(key, val):
|
|
||||||
peer_settings[key] = val
|
|
||||||
|
|
||||||
def fake_migrate():
|
|
||||||
fake_peer_store('db-initialised', 'True')
|
|
||||||
|
|
||||||
self.migrate_database.side_effect = fake_migrate
|
|
||||||
mock_peer_store.side_effect = fake_peer_store
|
|
||||||
mock_peer_retrieve.side_effect = lambda key: peer_settings.get(key)
|
|
||||||
|
|
||||||
self.is_db_ready.return_value = True
|
|
||||||
mock_ensure_ssl_cert_master.return_value = False
|
|
||||||
self.relation_ids.return_value = ['identity-service:0']
|
|
||||||
self.related_units.return_value = ['unit/0']
|
|
||||||
|
|
||||||
self._postgresql_db_test(configs)
|
self._postgresql_db_test(configs)
|
||||||
self.assertEquals([call('/etc/keystone/keystone.conf')],
|
self.assertEquals([call('/etc/keystone/keystone.conf')],
|
||||||
configs.write.call_args_list)
|
configs.write.call_args_list)
|
||||||
self.migrate_database.assert_called_with()
|
self.assertTrue(leader_init.called)
|
||||||
self.assertTrue(self.ensure_initial_admin.called)
|
|
||||||
identity_changed.assert_called_with(
|
|
||||||
relation_id='identity-service:0',
|
|
||||||
remote_unit='unit/0')
|
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(hooks, 'run_in_apache')
|
@patch.object(hooks, 'run_in_apache')
|
||||||
@patch.object(hooks, 'is_db_initialised')
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
@patch.object(hooks, 'git_install_requested')
|
@patch.object(hooks, 'git_install_requested')
|
||||||
@ -409,7 +335,8 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_ensure_ssl_cert_master,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_log, git_requested,
|
mock_log, git_requested,
|
||||||
mock_is_db_initialised,
|
mock_is_db_initialised,
|
||||||
mock_run_in_apache):
|
mock_run_in_apache,
|
||||||
|
update):
|
||||||
mock_run_in_apache.return_value = False
|
mock_run_in_apache.return_value = False
|
||||||
git_requested.return_value = False
|
git_requested.return_value = False
|
||||||
mock_is_ssl_cert_master.return_value = True
|
mock_is_ssl_cert_master.return_value = True
|
||||||
@ -431,20 +358,14 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
configure_https.assert_called_with()
|
configure_https.assert_called_with()
|
||||||
self.assertTrue(configs.write_all.called)
|
self.assertTrue(configs.write_all.called)
|
||||||
|
|
||||||
self.assertTrue(self.ensure_initial_admin.called)
|
self.assertTrue(update.called)
|
||||||
self.log.assert_called_with(
|
|
||||||
'Firing identity_changed hook for all related services.')
|
|
||||||
identity_changed.assert_called_with(
|
|
||||||
relation_id='identity-service:0',
|
|
||||||
remote_unit='unit/0')
|
|
||||||
admin_relation_changed.assert_called_with('identity-service:0')
|
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(hooks, 'run_in_apache')
|
@patch.object(hooks, 'run_in_apache')
|
||||||
@patch.object(hooks, 'git_install_requested')
|
@patch.object(hooks, 'git_install_requested')
|
||||||
@patch('keystone_utils.log')
|
@patch('keystone_utils.log')
|
||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
@patch('keystone_utils.ensure_ssl_dirs')
|
@patch('keystone_utils.ensure_ssl_dirs')
|
||||||
@patch.object(hooks, 'update_all_identity_relation_units')
|
|
||||||
@patch.object(hooks, 'ensure_permissions')
|
@patch.object(hooks, 'ensure_permissions')
|
||||||
@patch.object(hooks, 'ensure_pki_cert_paths')
|
@patch.object(hooks, 'ensure_pki_cert_paths')
|
||||||
@patch.object(hooks, 'ensure_pki_dir_permissions')
|
@patch.object(hooks, 'ensure_pki_dir_permissions')
|
||||||
@ -467,11 +388,10 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_ensure_permissions,
|
mock_ensure_permissions,
|
||||||
mock_ensure_pki_cert_paths,
|
mock_ensure_pki_cert_paths,
|
||||||
mock_ensure_pki_permissions,
|
mock_ensure_pki_permissions,
|
||||||
mock_update_all_id_rel_units,
|
|
||||||
ensure_ssl_dirs,
|
ensure_ssl_dirs,
|
||||||
mock_ensure_ssl_cert_master,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_log, git_requested,
|
mock_log, git_requested,
|
||||||
mock_run_in_apache):
|
mock_run_in_apache, update):
|
||||||
mock_run_in_apache.return_value = False
|
mock_run_in_apache.return_value = False
|
||||||
git_requested.return_value = False
|
git_requested.return_value = False
|
||||||
mock_is_ssl_cert_master.return_value = True
|
mock_is_ssl_cert_master.return_value = True
|
||||||
@ -489,9 +409,9 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
self.assertTrue(configs.write_all.called)
|
self.assertTrue(configs.write_all.called)
|
||||||
|
|
||||||
self.assertFalse(self.migrate_database.called)
|
self.assertFalse(self.migrate_database.called)
|
||||||
self.assertFalse(self.ensure_initial_admin.called)
|
self.assertTrue(update.called)
|
||||||
self.assertFalse(identity_changed.called)
|
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(hooks, 'run_in_apache')
|
@patch.object(hooks, 'run_in_apache')
|
||||||
@patch.object(hooks, 'is_db_initialised')
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
@patch.object(hooks, 'git_install_requested')
|
@patch.object(hooks, 'git_install_requested')
|
||||||
@ -528,7 +448,8 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_ensure_ssl_cert_master,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_log, git_requested,
|
mock_log, git_requested,
|
||||||
mock_is_db_initialised,
|
mock_is_db_initialised,
|
||||||
mock_run_in_apache):
|
mock_run_in_apache,
|
||||||
|
update):
|
||||||
mock_run_in_apache.return_value = False
|
mock_run_in_apache.return_value = False
|
||||||
git_requested.return_value = False
|
git_requested.return_value = False
|
||||||
mock_is_ssl_cert_master.return_value = True
|
mock_is_ssl_cert_master.return_value = True
|
||||||
@ -552,14 +473,9 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
configure_https.assert_called_with()
|
configure_https.assert_called_with()
|
||||||
self.assertTrue(configs.write_all.called)
|
self.assertTrue(configs.write_all.called)
|
||||||
|
|
||||||
self.assertTrue(self.ensure_initial_admin.called)
|
self.assertTrue(update.called)
|
||||||
self.log.assert_called_with(
|
|
||||||
'Firing identity_changed hook for all related services.')
|
|
||||||
identity_changed.assert_called_with(
|
|
||||||
relation_id='identity-service:0',
|
|
||||||
remote_unit='unit/0')
|
|
||||||
admin_relation_changed.assert_called_with('identity-service:0')
|
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(hooks, 'run_in_apache')
|
@patch.object(hooks, 'run_in_apache')
|
||||||
@patch.object(hooks, 'initialise_pki')
|
@patch.object(hooks, 'initialise_pki')
|
||||||
@patch.object(hooks, 'git_install_requested')
|
@patch.object(hooks, 'git_install_requested')
|
||||||
@ -591,7 +507,8 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_log, config_val_changed,
|
mock_log, config_val_changed,
|
||||||
git_requested,
|
git_requested,
|
||||||
mock_initialise_pki,
|
mock_initialise_pki,
|
||||||
mock_run_in_apache):
|
mock_run_in_apache,
|
||||||
|
update):
|
||||||
mock_run_in_apache.return_value = False
|
mock_run_in_apache.return_value = False
|
||||||
git_requested.return_value = True
|
git_requested.return_value = True
|
||||||
mock_ensure_ssl_cert_master.return_value = False
|
mock_ensure_ssl_cert_master.return_value = False
|
||||||
@ -620,6 +537,7 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
self.git_install.assert_called_with(projects_yaml)
|
self.git_install.assert_called_with(projects_yaml)
|
||||||
self.assertFalse(self.openstack_upgrade_available.called)
|
self.assertFalse(self.openstack_upgrade_available.called)
|
||||||
self.assertFalse(self.do_openstack_upgrade_reexec.called)
|
self.assertFalse(self.do_openstack_upgrade_reexec.called)
|
||||||
|
self.assertTrue(update.called)
|
||||||
|
|
||||||
@patch.object(hooks, 'run_in_apache')
|
@patch.object(hooks, 'run_in_apache')
|
||||||
@patch.object(hooks, 'initialise_pki')
|
@patch.object(hooks, 'initialise_pki')
|
||||||
@ -782,16 +700,14 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
hooks.leader_elected()
|
hooks.leader_elected()
|
||||||
mock_write.assert_has_calls([call(utils.TOKEN_FLUSH_CRON_FILE)])
|
mock_write.assert_has_calls([call(utils.TOKEN_FLUSH_CRON_FILE)])
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(hooks.CONFIGS, 'write')
|
@patch.object(hooks.CONFIGS, 'write')
|
||||||
@patch.object(hooks, 'identity_changed')
|
def test_leader_settings_changed(self, mock_write, update):
|
||||||
def test_leader_settings_changed(self, mock_identity_changed,
|
|
||||||
mock_write):
|
|
||||||
self.relation_ids.return_value = ['identity:1']
|
self.relation_ids.return_value = ['identity:1']
|
||||||
self.related_units.return_value = ['keystone/1']
|
self.related_units.return_value = ['keystone/1']
|
||||||
hooks.leader_settings_changed()
|
hooks.leader_settings_changed()
|
||||||
mock_write.assert_has_calls([call(utils.TOKEN_FLUSH_CRON_FILE)])
|
mock_write.assert_has_calls([call(utils.TOKEN_FLUSH_CRON_FILE)])
|
||||||
exp = [call(relation_id='identity:1', remote_unit='keystone/1')]
|
self.assertTrue(update.called)
|
||||||
mock_identity_changed.assert_has_calls(exp)
|
|
||||||
|
|
||||||
def test_ha_joined(self):
|
def test_ha_joined(self):
|
||||||
self.get_hacluster_config.return_value = {
|
self.get_hacluster_config.return_value = {
|
||||||
@ -908,6 +824,7 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
self.assertTrue(configs.write_all.called)
|
self.assertTrue(configs.write_all.called)
|
||||||
self.assertFalse(mock_synchronize_ca.called)
|
self.assertFalse(mock_synchronize_ca.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(hooks, 'is_db_initialised')
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
@patch('keystone_utils.log')
|
@patch('keystone_utils.log')
|
||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
@ -917,7 +834,8 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
identity_changed,
|
identity_changed,
|
||||||
mock_ensure_ssl_cert_master,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_log,
|
mock_log,
|
||||||
mock_is_db_initialised):
|
mock_is_db_initialised,
|
||||||
|
update):
|
||||||
mock_is_db_initialised.return_value = True
|
mock_is_db_initialised.return_value = True
|
||||||
self.is_db_ready.return_value = True
|
self.is_db_ready.return_value = True
|
||||||
mock_ensure_ssl_cert_master.return_value = False
|
mock_ensure_ssl_cert_master.return_value = False
|
||||||
@ -928,11 +846,7 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
|
|
||||||
hooks.ha_changed()
|
hooks.ha_changed()
|
||||||
self.assertTrue(configs.write_all.called)
|
self.assertTrue(configs.write_all.called)
|
||||||
self.log.assert_called_with(
|
self.assertTrue(update.called)
|
||||||
'Firing identity_changed hook for all related services.')
|
|
||||||
identity_changed.assert_called_with(
|
|
||||||
relation_id='identity-service:0',
|
|
||||||
remote_unit='unit/0')
|
|
||||||
|
|
||||||
@patch('keystone_utils.log')
|
@patch('keystone_utils.log')
|
||||||
@patch('keystone_utils.ensure_ssl_cert_master')
|
@patch('keystone_utils.ensure_ssl_cert_master')
|
||||||
@ -965,6 +879,7 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
cmd = ['a2dissite', 'openstack_https_frontend']
|
cmd = ['a2dissite', 'openstack_https_frontend']
|
||||||
self.check_call.assert_called_with(cmd)
|
self.check_call.assert_called_with(cmd)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(utils, 'os_release')
|
@patch.object(utils, 'os_release')
|
||||||
@patch.object(utils, 'git_install_requested')
|
@patch.object(utils, 'git_install_requested')
|
||||||
@patch.object(hooks, 'is_db_ready')
|
@patch.object(hooks, 'is_db_ready')
|
||||||
@ -986,7 +901,8 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_is_db_initialised,
|
mock_is_db_initialised,
|
||||||
mock_is_db_ready,
|
mock_is_db_ready,
|
||||||
git_requested,
|
git_requested,
|
||||||
os_release):
|
os_release,
|
||||||
|
update):
|
||||||
mock_is_db_initialised.return_value = True
|
mock_is_db_initialised.return_value = True
|
||||||
mock_is_db_ready.return_value = True
|
mock_is_db_ready.return_value = True
|
||||||
mock_is_elected_leader.return_value = False
|
mock_is_elected_leader.return_value = False
|
||||||
@ -1005,10 +921,138 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
user=self.ssh_user, group='juju_keystone',
|
user=self.ssh_user, group='juju_keystone',
|
||||||
peer_interface='cluster', ensure_local_user=True)
|
peer_interface='cluster', ensure_local_user=True)
|
||||||
self.assertTrue(mock_synchronize_ca.called)
|
self.assertTrue(mock_synchronize_ca.called)
|
||||||
self.log.assert_called_with(
|
self.assertTrue(update.called)
|
||||||
'Firing identity_changed hook for all related services.')
|
|
||||||
self.assertTrue(self.ensure_initial_admin.called)
|
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
|
def test_leader_init_db_if_ready(self, is_db_initialized,
|
||||||
|
update):
|
||||||
|
""" Verify leader initilaizes db """
|
||||||
|
self.is_elected_leader.return_value = True
|
||||||
|
is_db_initialized.return_value = False
|
||||||
|
self.is_db_ready.return_value = True
|
||||||
|
hooks.leader_init_db_if_ready()
|
||||||
|
self.is_db_ready.assert_called_with(use_current_context=False)
|
||||||
|
self.migrate_database.assert_called_with()
|
||||||
|
update.assert_called_with(check_db_ready=False)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
|
def test_leader_init_db_not_leader(self, update):
|
||||||
|
""" Verify non-leader does not initilaize db """
|
||||||
|
self.is_elected_leader.return_value = False
|
||||||
|
hooks.leader_init_db_if_ready()
|
||||||
|
self.is_elected_leader.assert_called_with('grp_ks_vips')
|
||||||
|
self.log.assert_called_with("Not leader - skipping db init",
|
||||||
|
level='DEBUG')
|
||||||
|
self.assertFalse(self.migrate_database.called)
|
||||||
|
self.assertFalse(update.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
|
def test_leader_init_db_not_initilaized(self, is_db_initialized, update):
|
||||||
|
""" Verify leader does not initilaize db when already initialized """
|
||||||
|
self.is_elected_leader.return_value = True
|
||||||
|
is_db_initialized.return_value = True
|
||||||
|
hooks.leader_init_db_if_ready()
|
||||||
|
self.log.assert_called_with('Database already initialised - skipping '
|
||||||
|
'db init', level='DEBUG')
|
||||||
|
self.assertFalse(self.migrate_database.called)
|
||||||
|
self.assertFalse(update.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
|
def test_leader_init_db_not_ready(self, is_db_initialized, update):
|
||||||
|
""" Verify leader does not initilaize db when db not ready """
|
||||||
|
self.is_elected_leader.return_value = True
|
||||||
|
is_db_initialized.return_value = False
|
||||||
|
self.is_db_ready.return_value = False
|
||||||
|
hooks.leader_init_db_if_ready()
|
||||||
|
self.is_db_ready.assert_called_with(use_current_context=False)
|
||||||
|
self.log.assert_called_with('Allowed_units list provided and this '
|
||||||
|
'unit not present', level='INFO')
|
||||||
|
self.assertFalse(self.migrate_database.called)
|
||||||
|
self.assertFalse(update.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'admin_relation_changed')
|
||||||
|
@patch.object(hooks, 'identity_credentials_changed')
|
||||||
|
@patch.object(hooks, 'identity_changed')
|
||||||
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
|
@patch.object(hooks, 'CONFIGS')
|
||||||
|
def test_update_all_identity_relation_units(self, configs,
|
||||||
|
is_db_initialized,
|
||||||
|
identity_changed,
|
||||||
|
identity_credentials_changed,
|
||||||
|
admin_relation_changed):
|
||||||
|
""" Verify all identity relations are updated """
|
||||||
|
is_db_initialized.return_value = True
|
||||||
|
self.relation_ids.return_value = ['identity-relation:0']
|
||||||
|
self.related_units.return_value = ['unit/0']
|
||||||
|
log_calls = [call('Firing identity_changed hook for all related '
|
||||||
|
'services.'),
|
||||||
|
call('Firing admin_relation_changed hook for all related '
|
||||||
|
'services.'),
|
||||||
|
call('Firing identity_credentials_changed hook for all '
|
||||||
|
'related services.')]
|
||||||
|
hooks.update_all_identity_relation_units(check_db_ready=False)
|
||||||
|
self.assertTrue(configs.write_all.called)
|
||||||
|
identity_changed.assert_called_with(
|
||||||
|
relation_id='identity-relation:0',
|
||||||
|
remote_unit='unit/0')
|
||||||
|
identity_credentials_changed.assert_called_with(
|
||||||
|
relation_id='identity-relation:0',
|
||||||
|
remote_unit='unit/0')
|
||||||
|
admin_relation_changed.assert_called_with('identity-relation:0')
|
||||||
|
self.log.assert_has_calls(log_calls, any_order=True)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'CONFIGS')
|
||||||
|
def test_update_all_db_not_ready(self, configs):
|
||||||
|
""" Verify update identity relations when DB is not ready """
|
||||||
|
self.is_db_ready.return_value = False
|
||||||
|
hooks.update_all_identity_relation_units(check_db_ready=True)
|
||||||
|
self.assertTrue(configs.write_all.called)
|
||||||
|
self.assertTrue(self.is_db_ready.called)
|
||||||
|
self.log.assert_called_with('Allowed_units list provided and this '
|
||||||
|
'unit not present', level='INFO')
|
||||||
|
self.assertFalse(self.relation_ids.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
|
@patch.object(hooks, 'CONFIGS')
|
||||||
|
def test_update_all_db_not_initializd(self, configs, is_db_initialized):
|
||||||
|
""" Verify update identity relations when DB is not initialized """
|
||||||
|
is_db_initialized.return_value = False
|
||||||
|
hooks.update_all_identity_relation_units(check_db_ready=False)
|
||||||
|
self.assertTrue(configs.write_all.called)
|
||||||
|
self.assertFalse(self.is_db_ready.called)
|
||||||
|
self.log.assert_called_with('Database not yet initialised - '
|
||||||
|
'deferring identity-relation updates',
|
||||||
|
level='INFO')
|
||||||
|
self.assertFalse(self.relation_ids.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
|
@patch.object(hooks, 'CONFIGS')
|
||||||
|
def test_update_all_leader(self, configs, is_db_initialized):
|
||||||
|
""" Verify update identity relations when the leader"""
|
||||||
|
self.is_elected_leader.return_value = True
|
||||||
|
is_db_initialized.return_value = True
|
||||||
|
hooks.update_all_identity_relation_units(check_db_ready=False)
|
||||||
|
self.assertTrue(configs.write_all.called)
|
||||||
|
self.assertTrue(self.ensure_initial_admin.called)
|
||||||
|
# Still updates relations
|
||||||
|
self.assertTrue(self.relation_ids.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'is_db_initialised')
|
||||||
|
@patch.object(hooks, 'CONFIGS')
|
||||||
|
def test_update_all_not_leader(self, configs, is_db_initialized):
|
||||||
|
""" Verify update identity relations when not the leader"""
|
||||||
|
self.is_elected_leader.return_value = False
|
||||||
|
is_db_initialized.return_value = True
|
||||||
|
hooks.update_all_identity_relation_units(check_db_ready=False)
|
||||||
|
self.assertTrue(configs.write_all.called)
|
||||||
|
self.assertFalse(self.ensure_initial_admin.called)
|
||||||
|
# Still updates relations
|
||||||
|
self.assertTrue(self.relation_ids.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'update_all_identity_relation_units')
|
||||||
@patch.object(utils, 'os_release')
|
@patch.object(utils, 'os_release')
|
||||||
@patch.object(utils, 'git_install_requested')
|
@patch.object(utils, 'git_install_requested')
|
||||||
@patch('keystone_utils.log')
|
@patch('keystone_utils.log')
|
||||||
@ -1021,7 +1065,7 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
mock_ensure_ssl_cert_master,
|
mock_ensure_ssl_cert_master,
|
||||||
mock_relation_ids,
|
mock_relation_ids,
|
||||||
mock_log, git_requested,
|
mock_log, git_requested,
|
||||||
os_release):
|
os_release, update):
|
||||||
mock_relation_ids.return_value = []
|
mock_relation_ids.return_value = []
|
||||||
mock_ensure_ssl_cert_master.return_value = False
|
mock_ensure_ssl_cert_master.return_value = False
|
||||||
# Ensure always returns diff
|
# Ensure always returns diff
|
||||||
@ -1037,4 +1081,4 @@ class KeystoneRelationTests(CharmTestCase):
|
|||||||
user=self.ssh_user, group='juju_keystone',
|
user=self.ssh_user, group='juju_keystone',
|
||||||
peer_interface='cluster', ensure_local_user=True)
|
peer_interface='cluster', ensure_local_user=True)
|
||||||
self.assertTrue(self.log.called)
|
self.assertTrue(self.log.called)
|
||||||
self.assertFalse(self.ensure_initial_admin.called)
|
self.assertFalse(update.called)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from mock import patch, call, MagicMock, Mock
|
from mock import patch, call, MagicMock, Mock
|
||||||
from test_utils import CharmTestCase
|
from test_utils import CharmTestCase
|
||||||
import os
|
import os
|
||||||
|
from base64 import b64encode
|
||||||
|
|
||||||
os.environ['JUJU_UNIT_NAME'] = 'keystone'
|
os.environ['JUJU_UNIT_NAME'] = 'keystone'
|
||||||
with patch('charmhelpers.core.hookenv.config') as config:
|
with patch('charmhelpers.core.hookenv.config') as config:
|
||||||
@ -859,7 +860,9 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
self.service_start.assert_called_once_with('apache2')
|
self.service_start.assert_called_once_with('apache2')
|
||||||
self.subprocess.call.assert_called_once_with(['pgrep', 'httpd'])
|
self.subprocess.call.assert_called_once_with(['pgrep', 'httpd'])
|
||||||
|
|
||||||
def test_restart_pid_check_ptable_string_retry(self):
|
# Do not sleep() to speed up manual runs.
|
||||||
|
@patch('charmhelpers.core.decorators.time')
|
||||||
|
def test_restart_pid_check_ptable_string_retry(self, mock_time):
|
||||||
call_returns = [1, 0, 0]
|
call_returns = [1, 0, 0]
|
||||||
self.subprocess.call.side_effect = lambda x: call_returns.pop()
|
self.subprocess.call.side_effect = lambda x: call_returns.pop()
|
||||||
utils.restart_pid_check('apache2', ptable_string='httpd')
|
utils.restart_pid_check('apache2', ptable_string='httpd')
|
||||||
@ -872,3 +875,258 @@ class TestKeystoneUtils(CharmTestCase):
|
|||||||
call(['pgrep', 'httpd']),
|
call(['pgrep', 'httpd']),
|
||||||
]
|
]
|
||||||
self.assertEquals(self.subprocess.call.call_args_list, expected)
|
self.assertEquals(self.subprocess.call.call_args_list, expected)
|
||||||
|
|
||||||
|
def test_get_requested_grants(self):
|
||||||
|
settings = {'requested_grants': 'Admin,Member'}
|
||||||
|
expected_results = ['Admin', 'Member']
|
||||||
|
self.assertEqual(utils.get_requested_grants(settings),
|
||||||
|
expected_results)
|
||||||
|
settings = {'not_requsted_grants': 'something else'}
|
||||||
|
expected_results = []
|
||||||
|
self.assertEqual(utils.get_requested_grants(settings),
|
||||||
|
expected_results)
|
||||||
|
|
||||||
|
@patch.object(utils, 'https')
|
||||||
|
def test_get_protocol(self, https):
|
||||||
|
# http
|
||||||
|
https.return_value = False
|
||||||
|
protocol = utils.get_protocol()
|
||||||
|
self.assertEqual(protocol, 'http')
|
||||||
|
# https
|
||||||
|
https.return_value = True
|
||||||
|
protocol = utils.get_protocol()
|
||||||
|
self.assertEqual(protocol, 'https')
|
||||||
|
|
||||||
|
def test_get_ssl_ca_settings(self):
|
||||||
|
CA = MagicMock()
|
||||||
|
CA.get_ca_bundle.return_value = 'certstring'
|
||||||
|
self.test_config.set('https-service-endpoints', 'True')
|
||||||
|
self.get_ca.return_value = CA
|
||||||
|
expected_settings = {'https_keystone': 'True',
|
||||||
|
'ca_cert': b64encode('certstring')}
|
||||||
|
settings = utils.get_ssl_ca_settings()
|
||||||
|
self.assertEqual(settings, expected_settings)
|
||||||
|
|
||||||
|
@patch.object(utils, 'get_manager')
|
||||||
|
def test_add_credentials_keystone_not_ready(self, get_manager):
|
||||||
|
""" Verify add_credentials_to_keystone when the relation
|
||||||
|
data is incomplete """
|
||||||
|
relation_id = 'identity-credentials:0'
|
||||||
|
remote_unit = 'unit/0'
|
||||||
|
self.relation_get.return_value = {}
|
||||||
|
utils.add_credentials_to_keystone(
|
||||||
|
relation_id=relation_id,
|
||||||
|
remote_unit=remote_unit)
|
||||||
|
self.log.assert_called_with('identity-credentials peer has not yet '
|
||||||
|
'set username')
|
||||||
|
|
||||||
|
@patch.object(utils, 'create_user_credentials')
|
||||||
|
@patch.object(utils, 'get_protocol')
|
||||||
|
@patch.object(utils, 'resolve_address')
|
||||||
|
@patch.object(utils, 'get_api_version')
|
||||||
|
@patch.object(utils, 'get_manager')
|
||||||
|
def test_add_credentials_keystone_username_only(self, get_manager,
|
||||||
|
get_api_version,
|
||||||
|
resolve_address,
|
||||||
|
get_protocol,
|
||||||
|
create_user_credentials):
|
||||||
|
""" Verify add_credentials with only username """
|
||||||
|
manager = MagicMock()
|
||||||
|
manager.resolve_tenant_id.return_value = 'abcdef0123456789'
|
||||||
|
get_manager.return_value = manager
|
||||||
|
remote_unit = 'unit/0'
|
||||||
|
relation_id = 'identity-credentials:0'
|
||||||
|
get_api_version.return_value = 2
|
||||||
|
get_protocol.return_value = 'http'
|
||||||
|
resolve_address.return_value = '10.10.10.10'
|
||||||
|
create_user_credentials.return_value = 'password'
|
||||||
|
self.relation_get.return_value = {'username': 'requester'}
|
||||||
|
self.get_service_password.return_value = 'password'
|
||||||
|
self.get_requested_roles.return_value = []
|
||||||
|
self.test_config.set('admin-port', 80)
|
||||||
|
self.test_config.set('service-port', 81)
|
||||||
|
self.test_config.set('service-tenant', 'services')
|
||||||
|
relation_data = {'auth_host': '10.10.10.10',
|
||||||
|
'credentials_host': '10.10.10.10',
|
||||||
|
'credentials_port': 81,
|
||||||
|
'auth_port': 80,
|
||||||
|
'auth_protocol': 'http',
|
||||||
|
'credentials_username': 'requester',
|
||||||
|
'credentials_protocol': 'http',
|
||||||
|
'credentials_password': 'password',
|
||||||
|
'credentials_project': 'services',
|
||||||
|
'credentials_project_id': 'abcdef0123456789',
|
||||||
|
'region': 'RegionOne',
|
||||||
|
'api_version': 2}
|
||||||
|
|
||||||
|
utils.add_credentials_to_keystone(
|
||||||
|
relation_id=relation_id,
|
||||||
|
remote_unit=remote_unit)
|
||||||
|
create_user_credentials.assert_called_with('requester', 'password',
|
||||||
|
domain=None,
|
||||||
|
new_roles=[],
|
||||||
|
grants=['Admin'],
|
||||||
|
project='services')
|
||||||
|
self.peer_store_and_set.assert_called_with(relation_id=relation_id,
|
||||||
|
**relation_data)
|
||||||
|
|
||||||
|
@patch.object(utils, 'create_user_credentials')
|
||||||
|
@patch.object(utils, 'get_protocol')
|
||||||
|
@patch.object(utils, 'resolve_address')
|
||||||
|
@patch.object(utils, 'get_api_version')
|
||||||
|
@patch.object(utils, 'get_manager')
|
||||||
|
def test_add_credentials_keystone_kv3(self, get_manager,
|
||||||
|
get_api_version,
|
||||||
|
resolve_address,
|
||||||
|
get_protocol,
|
||||||
|
create_user_credentials):
|
||||||
|
""" Verify add_credentials with Keystone V3 """
|
||||||
|
manager = MagicMock()
|
||||||
|
manager.resolve_tenant_id.return_value = 'abcdef0123456789'
|
||||||
|
get_manager.return_value = manager
|
||||||
|
remote_unit = 'unit/0'
|
||||||
|
relation_id = 'identity-credentials:0'
|
||||||
|
get_api_version.return_value = 3
|
||||||
|
get_protocol.return_value = 'http'
|
||||||
|
resolve_address.return_value = '10.10.10.10'
|
||||||
|
create_user_credentials.return_value = 'password'
|
||||||
|
self.relation_get.return_value = {'username': 'requester',
|
||||||
|
'domain': 'Non-Default'}
|
||||||
|
self.get_service_password.return_value = 'password'
|
||||||
|
self.get_requested_roles.return_value = []
|
||||||
|
self.test_config.set('admin-port', 80)
|
||||||
|
self.test_config.set('service-port', 81)
|
||||||
|
relation_data = {'auth_host': '10.10.10.10',
|
||||||
|
'credentials_host': '10.10.10.10',
|
||||||
|
'credentials_port': 81,
|
||||||
|
'auth_port': 80,
|
||||||
|
'auth_protocol': 'http',
|
||||||
|
'credentials_username': 'requester',
|
||||||
|
'credentials_protocol': 'http',
|
||||||
|
'credentials_password': 'password',
|
||||||
|
'credentials_project': 'services',
|
||||||
|
'credentials_project_id': 'abcdef0123456789',
|
||||||
|
'region': 'RegionOne',
|
||||||
|
'api_version': 3}
|
||||||
|
|
||||||
|
utils.add_credentials_to_keystone(
|
||||||
|
relation_id=relation_id,
|
||||||
|
remote_unit=remote_unit)
|
||||||
|
create_user_credentials.assert_called_with('requester', 'password',
|
||||||
|
domain='Non-Default',
|
||||||
|
new_roles=[],
|
||||||
|
grants=['Admin'],
|
||||||
|
project='services')
|
||||||
|
self.peer_store_and_set.assert_called_with(relation_id=relation_id,
|
||||||
|
**relation_data)
|
||||||
|
|
||||||
|
@patch.object(utils, 'create_tenant')
|
||||||
|
@patch.object(utils, 'create_user_credentials')
|
||||||
|
@patch.object(utils, 'get_protocol')
|
||||||
|
@patch.object(utils, 'resolve_address')
|
||||||
|
@patch.object(utils, 'get_api_version')
|
||||||
|
@patch.object(utils, 'get_manager')
|
||||||
|
def test_add_credentials_keystone_roles_grants(self, get_manager,
|
||||||
|
get_api_version,
|
||||||
|
resolve_address,
|
||||||
|
get_protocol,
|
||||||
|
create_user_credentials,
|
||||||
|
create_tenant):
|
||||||
|
""" Verify add_credentials with all relation settings """
|
||||||
|
manager = MagicMock()
|
||||||
|
manager.resolve_tenant_id.return_value = 'abcdef0123456789'
|
||||||
|
get_manager.return_value = manager
|
||||||
|
remote_unit = 'unit/0'
|
||||||
|
relation_id = 'identity-credentials:0'
|
||||||
|
get_api_version.return_value = 2
|
||||||
|
get_protocol.return_value = 'http'
|
||||||
|
resolve_address.return_value = '10.10.10.10'
|
||||||
|
create_user_credentials.return_value = 'password'
|
||||||
|
self.relation_get.return_value = {'username': 'requester',
|
||||||
|
'project': 'myproject',
|
||||||
|
'requested_roles': 'New,Member',
|
||||||
|
'requested_grants': 'New,Member'}
|
||||||
|
self.get_service_password.return_value = 'password'
|
||||||
|
self.get_requested_roles.return_value = ['New', 'Member']
|
||||||
|
self.test_config.set('admin-port', 80)
|
||||||
|
self.test_config.set('service-port', 81)
|
||||||
|
relation_data = {'auth_host': '10.10.10.10',
|
||||||
|
'credentials_host': '10.10.10.10',
|
||||||
|
'credentials_port': 81,
|
||||||
|
'auth_port': 80,
|
||||||
|
'auth_protocol': 'http',
|
||||||
|
'credentials_username': 'requester',
|
||||||
|
'credentials_protocol': 'http',
|
||||||
|
'credentials_password': 'password',
|
||||||
|
'credentials_project': 'myproject',
|
||||||
|
'credentials_project_id': 'abcdef0123456789',
|
||||||
|
'region': 'RegionOne',
|
||||||
|
'api_version': 2}
|
||||||
|
|
||||||
|
utils.add_credentials_to_keystone(
|
||||||
|
relation_id=relation_id,
|
||||||
|
remote_unit=remote_unit)
|
||||||
|
create_tenant.assert_called_with('myproject')
|
||||||
|
create_user_credentials.assert_called_with('requester', 'password',
|
||||||
|
domain=None,
|
||||||
|
new_roles=['New', 'Member'],
|
||||||
|
grants=['New', 'Member'],
|
||||||
|
project='myproject')
|
||||||
|
self.peer_store_and_set.assert_called_with(relation_id=relation_id,
|
||||||
|
**relation_data)
|
||||||
|
|
||||||
|
@patch.object(utils, 'get_ssl_ca_settings')
|
||||||
|
@patch.object(utils, 'create_user_credentials')
|
||||||
|
@patch.object(utils, 'get_protocol')
|
||||||
|
@patch.object(utils, 'resolve_address')
|
||||||
|
@patch.object(utils, 'get_api_version')
|
||||||
|
@patch.object(utils, 'get_manager')
|
||||||
|
def test_add_credentials_keystone_ssl(self, get_manager,
|
||||||
|
get_api_version,
|
||||||
|
resolve_address,
|
||||||
|
get_protocol,
|
||||||
|
create_user_credentials,
|
||||||
|
get_ssl_ca_settings):
|
||||||
|
""" Verify add_credentials with SSL """
|
||||||
|
manager = MagicMock()
|
||||||
|
manager.resolve_tenant_id.return_value = 'abcdef0123456789'
|
||||||
|
get_manager.return_value = manager
|
||||||
|
remote_unit = 'unit/0'
|
||||||
|
relation_id = 'identity-credentials:0'
|
||||||
|
get_api_version.return_value = 2
|
||||||
|
get_protocol.return_value = 'https'
|
||||||
|
resolve_address.return_value = '10.10.10.10'
|
||||||
|
create_user_credentials.return_value = 'password'
|
||||||
|
get_ssl_ca_settings.return_value = {'https_keystone': 'True',
|
||||||
|
'ca_cert': 'base64certstring'}
|
||||||
|
self.relation_get.return_value = {'username': 'requester'}
|
||||||
|
self.get_service_password.return_value = 'password'
|
||||||
|
self.get_requested_roles.return_value = []
|
||||||
|
self.test_config.set('admin-port', 80)
|
||||||
|
self.test_config.set('service-port', 81)
|
||||||
|
self.test_config.set('https-service-endpoints', 'True')
|
||||||
|
relation_data = {'auth_host': '10.10.10.10',
|
||||||
|
'credentials_host': '10.10.10.10',
|
||||||
|
'credentials_port': 81,
|
||||||
|
'auth_port': 80,
|
||||||
|
'auth_protocol': 'https',
|
||||||
|
'credentials_username': 'requester',
|
||||||
|
'credentials_protocol': 'https',
|
||||||
|
'credentials_password': 'password',
|
||||||
|
'credentials_project': 'services',
|
||||||
|
'credentials_project_id': 'abcdef0123456789',
|
||||||
|
'region': 'RegionOne',
|
||||||
|
'api_version': 2,
|
||||||
|
'https_keystone': 'True',
|
||||||
|
'ca_cert': 'base64certstring'}
|
||||||
|
|
||||||
|
utils.add_credentials_to_keystone(
|
||||||
|
relation_id=relation_id,
|
||||||
|
remote_unit=remote_unit)
|
||||||
|
create_user_credentials.assert_called_with('requester', 'password',
|
||||||
|
domain=None,
|
||||||
|
new_roles=[],
|
||||||
|
grants=['Admin'],
|
||||||
|
project='services')
|
||||||
|
self.peer_store_and_set.assert_called_with(relation_id=relation_id,
|
||||||
|
**relation_data)
|
||||||
|
Loading…
Reference in New Issue
Block a user