def relation_get(attribute=None, unit=None, rid=None): """Attempt to use leader-get if supported in the current version of Juju, otherwise falls back on relation-get. Note that we only attempt to use leader-get if the provided rid is a peer relation id or no relation id is provided (in which case we assume we are within the peer relation context). """ try: if rid in relation_ids('cluster'): return leader_get(attribute, rid) else: raise NotImplementedError except NotImplementedError: return _relation_get(attribute=attribute, rid=rid, unit=unit)
def leader_get(attribute=None, rid=None): """Wrapper to ensure that settings are migrated from the peer relation. This is to support upgrading an environment that does not support Juju leadership election to one that does. If a setting is not extant in the leader-get but is on the relation-get peer rel, it is migrated and marked as such so that it is not re-migrated. """ migration_key = '__leader_get_migrated_settings__' if not is_leader(): return _leader_get(attribute=attribute) settings_migrated = False leader_settings = _leader_get(attribute=attribute) previously_migrated = _leader_get(attribute=migration_key) if previously_migrated: migrated = set(json.loads(previously_migrated)) else: migrated = set([]) try: if migration_key in leader_settings: del leader_settings[migration_key] except TypeError: pass if attribute: if attribute in migrated: return leader_settings # If attribute not present in leader db, check if this unit has set # the attribute in the peer relation if not leader_settings: peer_setting = _relation_get(attribute=attribute, unit=local_unit(), rid=rid) if peer_setting: leader_set(settings={attribute: peer_setting}) leader_settings = peer_setting if leader_settings: settings_migrated = True migrated.add(attribute) else: r_settings = _relation_get(unit=local_unit(), rid=rid) if r_settings: for key in set(r_settings.keys()).difference(migrated): # Leader setting wins if not leader_settings.get(key): leader_settings[key] = r_settings[key] settings_migrated = True migrated.add(key) if settings_migrated: leader_set(**leader_settings) if migrated and settings_migrated: migrated = json.dumps(list(migrated)) leader_set(settings={migration_key: migrated}) return leader_settings