def test_peer_store_and_set_no_relation(self, peer_store): self.is_relation_made.return_value = False peerstorage.peer_store_and_set(relation_id='db', kwarg1='kwarg1_v') self.relation_set.assert_called_with(relation_id='db', relation_settings={}, kwarg1='kwarg1_v') peer_store.assert_not_called()
def test_peer_store_and_set_kwargs(self, peer_store): self.is_relation_made.return_value = True peerstorage.peer_store_and_set(relation_id='db', kwarg1='kwarg1_v') self.relation_set.assert_called_with(relation_id='db', relation_settings={}, kwarg1='kwarg1_v') calls = [call('db_kwarg1', 'kwarg1_v', relation_name='cluster')] peer_store.assert_has_calls(calls, any_order=True)
def test_peer_store_and_rel_settings(self, peer_store): self.is_relation_made.return_value = True rel_setting = {'rel_set1': 'relset1_v'} peerstorage.peer_store_and_set(relation_id='db', relation_settings=rel_setting) self.relation_set.assert_called_with(relation_id='db', relation_settings=rel_setting) calls = [call('db_rel_set1', 'relset1_v', relation_name='cluster')] peer_store.assert_has_calls(calls, any_order=True)
def db_changed(relation_id=None, unit=None, admin=None): # Is this db-admin or db relation if admin not in [True, False]: admin = relation_type() == 'db-admin' if admin: relation_name = 'db-admin' else: relation_name = 'db' if not seeded(): log( "Percona cluster not yet bootstrapped - deferring {} relation " "until bootstrapped.".format(relation_name), DEBUG) return if not is_leader() and client_node_is_ready(): clear_and_populate_client_db_relations(relation_id, relation_name) return # Bail if leader is not ready if not leader_node_is_ready(): return db_name, _ = (unit or remote_unit()).split("/") username = db_name db_helper = get_db_helper() addr = relation_get('private-address', unit=unit, rid=relation_id) password = db_helper.configure_db(addr, db_name, username, admin=admin) db_host = get_db_host(addr, interface=relation_name) peer_store_and_set(relation_id=relation_id, user=username, password=password, host=db_host, database=db_name)
def db_changed(relation_id=None, unit=None, admin=None): # Is this db-admin or db relation if admin not in [True, False]: admin = relation_type() == 'db-admin' if admin: relation_name = 'db-admin' else: relation_name = 'db' if not seeded(): log("Percona cluster not yet bootstrapped - deferring {} relation " "until bootstrapped.".format(relation_name), DEBUG) return if not is_leader() and client_node_is_ready(): clear_and_populate_client_db_relations(relation_id, relation_name) return # Bail if leader is not ready if not leader_node_is_ready(): return db_name, _ = (unit or remote_unit()).split("/") username = db_name db_helper = get_db_helper() addr = relation_get('private-address', unit=unit, rid=relation_id) password = db_helper.configure_db(addr, db_name, username, admin=admin) db_host = get_db_host(addr, interface=relation_name) peer_store_and_set(relation_id=relation_id, user=username, password=password, host=db_host, database=db_name)
def shared_db_changed(relation_id=None, unit=None): if not seeded(): log( "Percona cluster not yet bootstrapped - deferring shared-db rel " "until bootstrapped", DEBUG) return if not is_leader() and client_node_is_ready(): clear_and_populate_client_db_relations(relation_id, 'shared-db') return # Bail if leader is not ready if not leader_node_is_ready(): return settings = relation_get(unit=unit, rid=relation_id) access_network = config('access-network') db_helper = get_db_helper() peer_store_and_set(relation_id=relation_id, relation_settings={'access-network': access_network}) singleset = set(['database', 'username', 'hostname']) if singleset.issubset(settings): # Process a single database configuration hostname = settings['hostname'] database = settings['database'] username = settings['username'] normalized_address = resolve_hostname_to_ip(hostname) if access_network and not is_address_in_network( access_network, normalized_address): # NOTE: for configurations using access-network, only setup # database access if remote unit has presented a # hostname or ip address thats within the configured # network cidr log("Host '%s' not in access-network '%s' - ignoring" % (normalized_address, access_network), level=INFO) return # NOTE: do this before querying access grants password = configure_db_for_hosts(hostname, database, username, db_helper) allowed_units = db_helper.get_allowed_units(database, username, relation_id=relation_id) allowed_units = unit_sorted(allowed_units) allowed_units = ' '.join(allowed_units) relation_set(relation_id=relation_id, allowed_units=allowed_units) db_host = get_db_host(hostname) peer_store_and_set(relation_id=relation_id, db_host=db_host, password=password, allowed_units=allowed_units) else: # Process multiple database setup requests. # from incoming relation data: # nova_database=xxx nova_username=xxx nova_hostname=xxx # quantum_database=xxx quantum_username=xxx quantum_hostname=xxx # create # { # "nova": { # "username": xxx, # "database": xxx, # "hostname": xxx # }, # "quantum": { # "username": xxx, # "database": xxx, # "hostname": xxx # } # } # databases = {} for k, v in settings.iteritems(): db = k.split('_')[0] x = '_'.join(k.split('_')[1:]) if db not in databases: databases[db] = {} databases[db][x] = v allowed_units = {} return_data = {} for db in databases: if singleset.issubset(databases[db]): database = databases[db]['database'] hostname = databases[db]['hostname'] username = databases[db]['username'] normalized_address = resolve_hostname_to_ip(hostname) if (access_network and not is_address_in_network( access_network, normalized_address)): # NOTE: for configurations using access-network, # only setup database access if remote unit # has presented a hostname or ip address # thats within the configured network cidr return # NOTE: do this before querying access grants password = configure_db_for_hosts(hostname, database, username, db_helper) a_units = db_helper.get_allowed_units(database, username, relation_id=relation_id) a_units = ' '.join(unit_sorted(a_units)) allowed_units_key = '%s_allowed_units' % (db) allowed_units[allowed_units_key] = a_units return_data['%s_password' % (db)] = password return_data[allowed_units_key] = a_units db_host = get_db_host(hostname) if allowed_units: relation_set(relation_id=relation_id, **allowed_units) else: log("No allowed_units - not setting relation settings", level=DEBUG) if return_data: peer_store_and_set(relation_id=relation_id, db_host=db_host, **return_data) else: log("No return data - not setting relation settings", level=DEBUG)
def amqp_changed(relation_id=None, remote_unit=None, check_deferred_restarts=True): """Update amqp relations. :param relation_id: Relation id to update :type relation_id: str :param remote_unit: Remote unit on relation_id to update :type remote_unit: str :param check_deferred_events: Whether to check if restarts are permitted before running hook. :type check_deferred_events: bool """ allowed, reason = is_hook_allowed( 'amqp-relation-changed', check_deferred_restarts=check_deferred_restarts) if not allowed: log(reason, "WARN") return singleset = set(['username', 'vhost']) host_addr = ch_ip.get_relation_ip( rabbit_net_utils.AMQP_INTERFACE, cidr_network=config(rabbit_net_utils.AMQP_OVERRIDE_CONFIG)) sent_update = False if rabbit.leader_node_is_ready(): relation_settings = { 'hostname': host_addr, 'private-address': host_addr } # NOTE: active/active case if config('prefer-ipv6'): relation_settings['private-address'] = host_addr current = relation_get(rid=relation_id, unit=remote_unit) if singleset.issubset(current): if not all([current.get('username'), current.get('vhost')]): log('Relation not ready.', DEBUG) return # Provide credentials to relations. If password is already # available on peer relation then use it instead of reconfiguring. username = current['username'] vhost = current['vhost'] admin = current.get('admin', False) ttlname = current.get('ttlname') ttlreg = current.get('ttlreg') ttl = current.get('ttl') amqp_rid = relation_id or get_relation_id() password = configure_amqp(username, vhost, amqp_rid, admin=admin, ttlname=ttlname, ttlreg=ttlreg, ttl=ttl) relation_settings['password'] = password else: # NOTE(hopem): we should look at removing this code since i don't # think it's ever used anymore and stems from the days # when we needed to ensure consistency between # peerstorage (replaced by leader get/set) and amqp # relations. queues = {} for k, v in current.items(): amqp_rid = k.split('_')[0] x = '_'.join(k.split('_')[1:]) if amqp_rid not in queues: queues[amqp_rid] = {} queues[amqp_rid][x] = v for amqp_rid in queues: if singleset.issubset(queues[amqp_rid]): username = queues[amqp_rid]['username'] vhost = queues[amqp_rid]['vhost'] ttlname = queues[amqp_rid].get('ttlname') ttlreg = queues[amqp_rid].get('ttlreg') ttl = queues[amqp_rid].get('ttl') password = configure_amqp(username, vhost, amqp_rid, admin=admin, ttlname=ttlname, ttlreg=ttlreg, ttl=ttl) key = '_'.join([amqp_rid, 'password']) relation_settings[key] = password ssl_utils.configure_client_ssl(relation_settings) if is_clustered(): relation_settings['clustered'] = 'true' # NOTE(dosaboy): this stanza can be removed once we fully remove # deprecated HA support. if is_relation_made('ha'): # active/passive settings relation_settings['vip'] = config('vip') # or ha-vip-only to support active/active, but # accessed via a VIP for older clients. if config('ha-vip-only') is True: relation_settings['ha-vip-only'] = 'true' # set if need HA queues or not if cmp_pkgrevno('rabbitmq-server', '3.0.1') < 0: relation_settings['ha_queues'] = True log( "Updating relation {} keys {}".format( relation_id or get_relation_id(), ','.join(relation_settings.keys())), DEBUG) peer_store_and_set(relation_id=relation_id, relation_settings=relation_settings) sent_update = True elif not is_leader() and rabbit.client_node_is_ready(): if not rabbit.clustered(): log("This node is not clustered yet, defer sending data to client", level=DEBUG) return log("Propagating peer settings to all amqp relations", DEBUG) # NOTE(jamespage) clear relation to deal with data being # removed from peer storage. relation_clear(relation_id) # 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('amqp'): peerdb_settings = peer_retrieve_by_prefix(rel_id) if 'password' in peerdb_settings: peerdb_settings['hostname'] = host_addr peerdb_settings['private-address'] = host_addr relation_set(relation_id=rel_id, **peerdb_settings) sent_update = True kvstore = kv() update_done = kvstore.get(INITIAL_CLIENT_UPDATE_KEY, False) if sent_update and not update_done: kvstore.set(key=INITIAL_CLIENT_UPDATE_KEY, value=True) kvstore.flush()
def amqp_changed(relation_id=None, remote_unit=None): host_addr = rabbit.get_unit_ip() # TODO: Simplify what the non-leader needs to do if not is_leader() and rabbit.client_node_is_ready(): # NOTE(jamespage) clear relation to deal with data being # removed from peer storage relation_clear(relation_id) # Each unit needs to set the db information otherwise if the unit # with the info dies the settings die with it Bug# 1355848 exc_list = ['hostname', 'private-address'] for rel_id in relation_ids('amqp'): peerdb_settings = peer_retrieve_by_prefix(rel_id, exc_list=exc_list) peerdb_settings['hostname'] = host_addr peerdb_settings['private-address'] = host_addr if 'password' in peerdb_settings: relation_set(relation_id=rel_id, **peerdb_settings) log('amqp_changed(): Deferring amqp_changed' ' to the leader.') # NOTE: active/active case if config('prefer-ipv6'): relation_settings = {'private-address': host_addr} relation_set(relation_id=relation_id, relation_settings=relation_settings) return # Bail if not completely ready if not rabbit.leader_node_is_ready(): return relation_settings = {} settings = relation_get(rid=relation_id, unit=remote_unit) singleset = set(['username', 'vhost']) if singleset.issubset(settings): if None in [settings['username'], settings['vhost']]: log('amqp_changed(): Relation not ready.') return relation_settings['password'] = configure_amqp( username=settings['username'], vhost=settings['vhost'], admin=settings.get('admin', False)) else: queues = {} for k, v in settings.iteritems(): amqp = k.split('_')[0] x = '_'.join(k.split('_')[1:]) if amqp not in queues: queues[amqp] = {} queues[amqp][x] = v for amqp in queues: if singleset.issubset(queues[amqp]): relation_settings['_'.join([amqp, 'password'])] = configure_amqp( queues[amqp]['username'], queues[amqp]['vhost']) relation_settings['hostname'] = \ relation_settings['private-address'] = \ rabbit.get_unit_ip() ssl_utils.configure_client_ssl(relation_settings) if is_clustered(): relation_settings['clustered'] = 'true' if is_relation_made('ha'): # active/passive settings relation_settings['vip'] = config('vip') # or ha-vip-only to support active/active, but # accessed via a VIP for older clients. if config('ha-vip-only') is True: relation_settings['ha-vip-only'] = 'true' # set if need HA queues or not if cmp_pkgrevno('rabbitmq-server', '3.0.1') < 0: relation_settings['ha_queues'] = True peer_store_and_set(relation_id=relation_id, relation_settings=relation_settings)
def shared_db_changed(relation_id=None, unit=None): if not seeded(): log("Percona cluster not yet bootstrapped - deferring shared-db rel " "until bootstrapped", DEBUG) return if not is_elected_leader(DC_RESOURCE_NAME): # NOTE(jamespage): relation level data candidate log('Service is peered, clearing shared-db relation ' 'as this service unit is not the leader') relation_clear(relation_id) # Each unit needs to set the db information otherwise if the unit # with the info dies the settings die with it Bug# 1355848 if is_relation_made('cluster'): for rel_id in relation_ids('shared-db'): peerdb_settings = \ peer_retrieve_by_prefix(rel_id, exc_list=['hostname']) passwords = [key for key in peerdb_settings.keys() if 'password' in key.lower()] if len(passwords) > 0: relation_set(relation_id=rel_id, **peerdb_settings) return settings = relation_get(unit=unit, rid=relation_id) access_network = config('access-network') db_helper = get_db_helper() peer_store_and_set(relation_id=relation_id, relation_settings={'access-network': access_network}) singleset = set(['database', 'username', 'hostname']) if singleset.issubset(settings): # Process a single database configuration hostname = settings['hostname'] database = settings['database'] username = settings['username'] normalized_address = get_host_ip(hostname) if access_network and not is_address_in_network(access_network, normalized_address): # NOTE: for configurations using access-network, only setup # database access if remote unit has presented a # hostname or ip address thats within the configured # network cidr log("Host '%s' not in access-network '%s' - ignoring" % (normalized_address, access_network), level=INFO) return # NOTE: do this before querying access grants password = configure_db_for_hosts(hostname, database, username, db_helper) allowed_units = db_helper.get_allowed_units(database, username, relation_id=relation_id) allowed_units = unit_sorted(allowed_units) allowed_units = ' '.join(allowed_units) relation_set(relation_id=relation_id, allowed_units=allowed_units) db_host = get_db_host(hostname) peer_store_and_set(relation_id=relation_id, db_host=db_host, password=password) else: # Process multiple database setup requests. # from incoming relation data: # nova_database=xxx nova_username=xxx nova_hostname=xxx # quantum_database=xxx quantum_username=xxx quantum_hostname=xxx # create # { # "nova": { # "username": xxx, # "database": xxx, # "hostname": xxx # }, # "quantum": { # "username": xxx, # "database": xxx, # "hostname": xxx # } # } # databases = {} for k, v in settings.iteritems(): db = k.split('_')[0] x = '_'.join(k.split('_')[1:]) if db not in databases: databases[db] = {} databases[db][x] = v allowed_units = {} return_data = {} for db in databases: if singleset.issubset(databases[db]): database = databases[db]['database'] hostname = databases[db]['hostname'] username = databases[db]['username'] normalized_address = get_host_ip(hostname) if (access_network and not is_address_in_network(access_network, normalized_address)): # NOTE: for configurations using access-network, # only setup database access if remote unit # has presented a hostname or ip address # thats within the configured network cidr return # NOTE: do this before querying access grants password = configure_db_for_hosts(hostname, database, username, db_helper) a_units = db_helper.get_allowed_units(database, username, relation_id=relation_id) a_units = ' '.join(unit_sorted(a_units)) allowed_units['%s_allowed_units' % (db)] = a_units return_data['%s_password' % (db)] = password db_host = get_db_host(hostname) if allowed_units: relation_set(relation_id=relation_id, **allowed_units) else: log("No allowed_units - not setting relation settings", level=DEBUG) if return_data: peer_store_and_set(relation_id=relation_id, db_host=db_host, **return_data) else: log("No return data - not setting relation settings", level=DEBUG)
def amqp_changed(relation_id=None, remote_unit=None): if config('prefer-ipv6'): host_addr = get_ipv6_addr()[0] else: host_addr = unit_get('private-address') if not is_elected_leader('res_rabbitmq_vip'): # NOTE(jamespage) clear relation to deal with data being # removed from peer storage relation_clear(relation_id) # Each unit needs to set the db information otherwise if the unit # with the info dies the settings die with it Bug# 1355848 exc_list = ['hostname', 'private-address'] for rel_id in relation_ids('amqp'): peerdb_settings = peer_retrieve_by_prefix(rel_id, exc_list=exc_list) peerdb_settings['hostname'] = host_addr peerdb_settings['private-address'] = host_addr if 'password' in peerdb_settings: relation_set(relation_id=rel_id, **peerdb_settings) log('amqp_changed(): Deferring amqp_changed' ' to is_elected_leader.') # NOTE: active/active case if config('prefer-ipv6'): relation_settings = {'private-address': host_addr} relation_set(relation_id=relation_id, relation_settings=relation_settings) return relation_settings = {} settings = relation_get(rid=relation_id, unit=remote_unit) singleset = set(['username', 'vhost']) if singleset.issubset(settings): if None in [settings['username'], settings['vhost']]: log('amqp_changed(): Relation not ready.') return relation_settings['password'] = configure_amqp( username=settings['username'], vhost=settings['vhost'], admin=settings.get('admin', False)) else: queues = {} for k, v in settings.iteritems(): amqp = k.split('_')[0] x = '_'.join(k.split('_')[1:]) if amqp not in queues: queues[amqp] = {} queues[amqp][x] = v for amqp in queues: if singleset.issubset(queues[amqp]): relation_settings[ '_'.join([amqp, 'password'])] = configure_amqp( queues[amqp]['username'], queues[amqp]['vhost']) if config('prefer-ipv6'): relation_settings['private-address'] = host_addr else: # NOTE(jamespage) # override private-address settings if access-network is # configured and an appropriate network interface is configured. relation_settings['hostname'] = \ relation_settings['private-address'] = \ get_address_in_network(config('access-network'), unit_get('private-address')) ssl_utils.configure_client_ssl(relation_settings) if is_clustered(): relation_settings['clustered'] = 'true' if is_relation_made('ha'): # active/passive settings relation_settings['vip'] = config('vip') # or ha-vip-only to support active/active, but # accessed via a VIP for older clients. if config('ha-vip-only') is True: relation_settings['ha-vip-only'] = 'true' # set if need HA queues or not if cmp_pkgrevno('rabbitmq-server', '3.0.1') < 0: relation_settings['ha_queues'] = True peer_store_and_set(relation_id=relation_id, relation_settings=relation_settings)
def amqp_changed(relation_id=None, remote_unit=None): singleset = set(['username', 'vhost']) host_addr = rabbit.get_unit_ip() if rabbit.leader_node_is_ready(): relation_settings = {'hostname': host_addr, 'private-address': host_addr} # NOTE: active/active case if config('prefer-ipv6'): relation_settings['private-address'] = host_addr current = relation_get(rid=relation_id, unit=remote_unit) if singleset.issubset(current): if not all([current.get('username'), current.get('vhost')]): log('Relation not ready.', DEBUG) return # Provide credentials to relations. If password is already # available on peer relation then use it instead of reconfiguring. username = current['username'] vhost = current['vhost'] admin = current.get('admin', False) amqp_rid = relation_id or get_relation_id() password = configure_amqp(username, vhost, amqp_rid, admin=admin) relation_settings['password'] = password else: # NOTE(hopem): we should look at removing this code since i don't # think it's ever used anymore and stems from the days # when we needed to ensure consistency between # peerstorage (replaced by leader get/set) and amqp # relations. queues = {} for k, v in current.iteritems(): amqp_rid = k.split('_')[0] x = '_'.join(k.split('_')[1:]) if amqp_rid not in queues: queues[amqp_rid] = {} queues[amqp_rid][x] = v for amqp_rid in queues: if singleset.issubset(queues[amqp_rid]): username = queues[amqp_rid]['username'] vhost = queues[amqp_rid]['vhost'] password = configure_amqp(username, vhost, amqp_rid, admin=admin) key = '_'.join([amqp_rid, 'password']) relation_settings[key] = password ssl_utils.configure_client_ssl(relation_settings) if is_clustered(): relation_settings['clustered'] = 'true' # NOTE(dosaboy): this stanza can be removed once we fully remove # deprecated HA support. if is_relation_made('ha'): # active/passive settings relation_settings['vip'] = config('vip') # or ha-vip-only to support active/active, but # accessed via a VIP for older clients. if config('ha-vip-only') is True: relation_settings['ha-vip-only'] = 'true' # set if need HA queues or not if cmp_pkgrevno('rabbitmq-server', '3.0.1') < 0: relation_settings['ha_queues'] = True log("Updating relation {} keys {}" .format(relation_id or get_relation_id(), ','.join(relation_settings.keys())), DEBUG) peer_store_and_set(relation_id=relation_id, relation_settings=relation_settings) elif not is_leader() and rabbit.client_node_is_ready(): log("Propagating peer settings to all amqp relations", DEBUG) # NOTE(jamespage) clear relation to deal with data being # removed from peer storage. relation_clear(relation_id) # 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('amqp'): peerdb_settings = peer_retrieve_by_prefix(rel_id) if 'password' in peerdb_settings: peerdb_settings['hostname'] = host_addr peerdb_settings['private-address'] = host_addr relation_set(relation_id=rel_id, **peerdb_settings)
def amqp_changed(relation_id=None, remote_unit=None): singleset = set(['username', 'vhost']) host_addr = ch_ip.get_relation_ip( rabbit_net_utils.AMQP_INTERFACE, cidr_network=config(rabbit_net_utils.AMQP_OVERRIDE_CONFIG)) if rabbit.leader_node_is_ready(): relation_settings = {'hostname': host_addr, 'private-address': host_addr} # NOTE: active/active case if config('prefer-ipv6'): relation_settings['private-address'] = host_addr current = relation_get(rid=relation_id, unit=remote_unit) if singleset.issubset(current): if not all([current.get('username'), current.get('vhost')]): log('Relation not ready.', DEBUG) return # Provide credentials to relations. If password is already # available on peer relation then use it instead of reconfiguring. username = current['username'] vhost = current['vhost'] admin = current.get('admin', False) amqp_rid = relation_id or get_relation_id() password = configure_amqp(username, vhost, amqp_rid, admin=admin) relation_settings['password'] = password else: # NOTE(hopem): we should look at removing this code since i don't # think it's ever used anymore and stems from the days # when we needed to ensure consistency between # peerstorage (replaced by leader get/set) and amqp # relations. queues = {} for k, v in current.items(): amqp_rid = k.split('_')[0] x = '_'.join(k.split('_')[1:]) if amqp_rid not in queues: queues[amqp_rid] = {} queues[amqp_rid][x] = v for amqp_rid in queues: if singleset.issubset(queues[amqp_rid]): username = queues[amqp_rid]['username'] vhost = queues[amqp_rid]['vhost'] password = configure_amqp(username, vhost, amqp_rid, admin=admin) key = '_'.join([amqp_rid, 'password']) relation_settings[key] = password ssl_utils.configure_client_ssl(relation_settings) if is_clustered(): relation_settings['clustered'] = 'true' # NOTE(dosaboy): this stanza can be removed once we fully remove # deprecated HA support. if is_relation_made('ha'): # active/passive settings relation_settings['vip'] = config('vip') # or ha-vip-only to support active/active, but # accessed via a VIP for older clients. if config('ha-vip-only') is True: relation_settings['ha-vip-only'] = 'true' # set if need HA queues or not if cmp_pkgrevno('rabbitmq-server', '3.0.1') < 0: relation_settings['ha_queues'] = True log("Updating relation {} keys {}" .format(relation_id or get_relation_id(), ','.join(relation_settings.keys())), DEBUG) peer_store_and_set(relation_id=relation_id, relation_settings=relation_settings) elif not is_leader() and rabbit.client_node_is_ready(): log("Propagating peer settings to all amqp relations", DEBUG) # NOTE(jamespage) clear relation to deal with data being # removed from peer storage. relation_clear(relation_id) # 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('amqp'): peerdb_settings = peer_retrieve_by_prefix(rel_id) if 'password' in peerdb_settings: peerdb_settings['hostname'] = host_addr peerdb_settings['private-address'] = host_addr relation_set(relation_id=rel_id, **peerdb_settings)
def shared_db_changed(relation_id=None, unit=None): if not seeded(): log("Percona cluster not yet bootstrapped - deferring shared-db rel " "until bootstrapped", DEBUG) return if not is_leader() and client_node_is_ready(): clear_and_populate_client_db_relations(relation_id, 'shared-db') return # Bail if leader is not ready if not leader_node_is_ready(): return settings = relation_get(unit=unit, rid=relation_id) access_network = config('access-network') db_helper = get_db_helper() peer_store_and_set(relation_id=relation_id, relation_settings={'access-network': access_network}) singleset = set(['database', 'username', 'hostname']) if singleset.issubset(settings): # Process a single database configuration hostname = settings['hostname'] database = settings['database'] username = settings['username'] normalized_address = resolve_hostname_to_ip(hostname) if access_network and not is_address_in_network(access_network, normalized_address): # NOTE: for configurations using access-network, only setup # database access if remote unit has presented a # hostname or ip address thats within the configured # network cidr log("Host '%s' not in access-network '%s' - ignoring" % (normalized_address, access_network), level=INFO) return # NOTE: do this before querying access grants password = configure_db_for_hosts(hostname, database, username, db_helper) allowed_units = db_helper.get_allowed_units(database, username, relation_id=relation_id) allowed_units = unit_sorted(allowed_units) allowed_units = ' '.join(allowed_units) relation_set(relation_id=relation_id, allowed_units=allowed_units) db_host = get_db_host(hostname) peer_store_and_set(relation_id=relation_id, db_host=db_host, password=password, allowed_units=allowed_units) else: # Process multiple database setup requests. # from incoming relation data: # nova_database=xxx nova_username=xxx nova_hostname=xxx # quantum_database=xxx quantum_username=xxx quantum_hostname=xxx # create # { # "nova": { # "username": xxx, # "database": xxx, # "hostname": xxx # }, # "quantum": { # "username": xxx, # "database": xxx, # "hostname": xxx # } # } # databases = {} for k, v in settings.iteritems(): db = k.split('_')[0] x = '_'.join(k.split('_')[1:]) if db not in databases: databases[db] = {} databases[db][x] = v allowed_units = {} return_data = {} for db in databases: if singleset.issubset(databases[db]): database = databases[db]['database'] hostname = databases[db]['hostname'] username = databases[db]['username'] normalized_address = resolve_hostname_to_ip(hostname) if (access_network and not is_address_in_network(access_network, normalized_address)): # NOTE: for configurations using access-network, # only setup database access if remote unit # has presented a hostname or ip address # thats within the configured network cidr return # NOTE: do this before querying access grants password = configure_db_for_hosts(hostname, database, username, db_helper) a_units = db_helper.get_allowed_units(database, username, relation_id=relation_id) a_units = ' '.join(unit_sorted(a_units)) allowed_units_key = '%s_allowed_units' % (db) allowed_units[allowed_units_key] = a_units return_data['%s_password' % (db)] = password return_data[allowed_units_key] = a_units db_host = get_db_host(hostname) if allowed_units: relation_set(relation_id=relation_id, **allowed_units) else: log("No allowed_units - not setting relation settings", level=DEBUG) if return_data: peer_store_and_set(relation_id=relation_id, db_host=db_host, **return_data) else: log("No return data - not setting relation settings", level=DEBUG)