diff --git a/hooks/charmhelpers/contrib/peerstorage/__init__.py b/hooks/charmhelpers/contrib/peerstorage/__init__.py index e0eeab5b..36ba64ff 100644 --- a/hooks/charmhelpers/contrib/peerstorage/__init__.py +++ b/hooks/charmhelpers/contrib/peerstorage/__init__.py @@ -1,4 +1,6 @@ +from charmhelpers.core.hookenv import relation_id as current_relation_id from charmhelpers.core.hookenv import ( + is_relation_made, relation_ids, relation_get, local_unit, @@ -49,6 +51,22 @@ def peer_retrieve(key, relation_name='cluster'): 'peer relation {}'.format(relation_name)) +def peer_retrieve_by_prefix(prefix, relation_name='cluster', delimiter='_', + inc_list=[], exc_list=[]): + """ Retrieve k/v pairs given a prefix and filter using {inc,exc}_list """ + peerdb_settings = peer_retrieve('-', relation_name=relation_name) + matched = {} + for k, v in peerdb_settings.items(): + full_prefix = prefix + delimiter + if k.startswith(full_prefix): + new_key = k.replace(full_prefix, '') + if new_key in exc_list: + continue + if new_key in inc_list or len(inc_list) == 0: + matched[new_key] = v + return matched + + def peer_store(key, value, relation_name='cluster'): """ Store the key/value pair on the named peer relation relation_name """ cluster_rels = relation_ids(relation_name) @@ -81,3 +99,26 @@ def peer_echo(includes=None): echo_data[attribute] = value if len(echo_data) > 0: relation_set(relation_settings=echo_data) + + +def peer_store_and_set(relation_id=None, peer_relation_name='cluster', + peer_store_fatal=False, relation_settings={}, + delimiter='_', **kwargs): + """ For each pair set them in the relation and store in peer db + + Note that the relation set is done within the provided relation_id and + if none is provided defaults to the current relation""" + relation_set(relation_id=relation_id, + relation_settings=relation_settings, + **kwargs) + if is_relation_made(peer_relation_name): + for key, value in dict(kwargs.items() + + relation_settings.items()).iteritems(): + key_prefix = relation_id or current_relation_id() + peer_store(key_prefix + delimiter + key, + value, + relation_name=peer_relation_name) + else: + if peer_store_fatal: + raise ValueError('Unable to detect ' + 'peer relation {}'.format(peer_relation_name)) diff --git a/hooks/keystone_hooks.py b/hooks/keystone_hooks.py index 1173c566..0e6f9f40 100755 --- a/hooks/keystone_hooks.py +++ b/hooks/keystone_hooks.py @@ -61,7 +61,10 @@ from charmhelpers.contrib.hahelpers.cluster import ( ) from charmhelpers.payload.execd import execd_preinstall -from charmhelpers.contrib.peerstorage import peer_echo +from charmhelpers.contrib.peerstorage import ( + peer_retrieve_by_prefix, + peer_echo, +) from charmhelpers.contrib.network.ip import ( get_iface_for_address, get_netmask_for_address @@ -173,6 +176,12 @@ def identity_changed(relation_id=None, remote_unit=None): add_service_to_keystone(relation_id, remote_unit) synchronize_ca() else: + # Each unit needs to set the db information otherwise if the unit + # with the info dies the settings die with it Bug# 1355848 + for rel_id in relation_ids('identity-service'): + peerdb_settings = peer_retrieve_by_prefix(rel_id) + if 'service_password' in peerdb_settings: + relation_set(relation_id=rel_id, **peerdb_settings) log('Deferring identity_changed() to service leader.') @@ -189,13 +198,17 @@ def cluster_joined(): @restart_on_change(restart_map(), stopstart=True) def cluster_changed(): # NOTE(jamespage) re-echo passwords for peer storage - peer_echo(includes=['_passwd']) + peer_echo(includes=['_passwd', 'identity-service:']) unison.ssh_authorized_peers(user=SSH_USER, group='keystone', peer_interface='cluster', ensure_local_user=True) synchronize_ca() CONFIGS.write_all() + for r_id in relation_ids('identity-service'): + for unit in relation_list(r_id): + identity_changed(relation_id=r_id, + remote_unit=unit) @hooks.hook('ha-relation-joined') diff --git a/hooks/keystone_utils.py b/hooks/keystone_utils.py index ab47f977..8a791958 100644 --- a/hooks/keystone_utils.py +++ b/hooks/keystone_utils.py @@ -57,6 +57,7 @@ from charmhelpers.core.host import ( ) from charmhelpers.contrib.peerstorage import ( + peer_store_and_set, peer_store, peer_retrieve, ) @@ -655,8 +656,8 @@ def add_service_to_keystone(relation_id=None, remote_unit=None): for role in get_requested_roles(settings): log("Creating requested role: %s" % role) create_role(role) - relation_set(relation_id=relation_id, - **relation_data) + peer_store_and_set(relation_id=relation_id, + **relation_data) return else: ensure_valid_service(settings['service']) @@ -771,8 +772,8 @@ def add_service_to_keystone(relation_id=None, remote_unit=None): relation_data['ssl_key'] = b64encode(key) relation_data['ca_cert'] = b64encode(ca_bundle) relation_data['https_keystone'] = 'True' - relation_set(relation_id=relation_id, - **relation_data) + peer_store_and_set(relation_id=relation_id, + **relation_data) def ensure_valid_service(service):