def domain_backend_changed(relation_id=None, unit=None): if get_api_version() < 3: log('Domain specific backend identity configuration only supported ' 'with Keystone v3 API, skipping domain creation and ' 'restart.') return domain_name = relation_get(attribute='domain-name', unit=unit, rid=relation_id) if domain_name: # NOTE(jamespage): Only create domain data from lead # unit when clustered and database # is configured and created. if is_leader() and is_db_ready() and is_db_initialised(): create_or_show_domain(domain_name) # NOTE(jamespage): Deployment may have multiple domains, # with different identity backends so # ensure that a domain specific nonce # is checked for restarts of keystone restart_nonce = relation_get(attribute='restart-nonce', unit=unit, rid=relation_id) domain_nonce_key = 'domain-restart-nonce-{}'.format(domain_name) db = unitdata.kv() if restart_nonce != db.get(domain_nonce_key): restart_keystone() db.set(domain_nonce_key, restart_nonce) db.flush()
def leader_init_db_if_ready(use_current_context=False): """ Initialise the keystone db if it is ready and mark it as initialised. NOTE: this must be idempotent. """ if not is_elected_leader(CLUSTER_RES): log("Not leader - skipping db init", level=DEBUG) return if is_db_initialised(): log("Database already initialised - skipping db init", level=DEBUG) update_all_identity_relation_units() return # Bugs 1353135 & 1187508. Dbs can appear to be ready before the # units acl entry has been added. So, if the db supports passing # a list of permitted units then check if we're in the list. if not is_db_ready(use_current_context=use_current_context): log('Allowed_units list provided and this unit not present', level=INFO) return migrate_database() bootstrap_keystone(configs=CONFIGS) ensure_initial_admin(config) if CompareOpenStackReleases(os_release('keystone')) >= 'liberty': CONFIGS.write(POLICY_JSON) # Ensure any existing service entries are updated in the # new database backend. update_all_identity_relation_units() update_all_domain_backends()
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 expect_ha() and not is_clustered(): log("Expected to be HA but no hacluster relation yet", level=INFO) return 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 identity_changed(relation_id=None, remote_unit=None): notifications_checksums = {} notifications_endpoints = {} if is_elected_leader(CLUSTER_RES): if not is_db_ready(): log( "identity-service-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-relation " "updates", level=INFO) return if expect_ha() and not is_clustered(): log("Expected to be HA but no hacluster relation yet", level=INFO) return add_service_to_keystone(relation_id, remote_unit) if is_service_present('neutron', 'network'): delete_service_entry('quantum', 'network') settings = relation_get(rid=relation_id, unit=remote_unit) # If endpoint has changed, notify to units related over the # identity-notifications interface. We base the decision to notify on # whether admin_url, public_url or internal_url have changed from # previous notify. service = settings.get('service') if service: key = '%s-endpoint-changed' % service notifications_endpoints[key] = endpoints_dict(settings) notifications_checksums[key] = endpoints_checksum(settings) else: # Some services don't set their name in the 'service' key in the # relation, for those their name is calculated from the prefix of # keys. See `assemble_endpoints()` for details. single = { 'service', 'region', 'public_url', 'admin_url', 'internal_url' } endpoints = assemble_endpoints(settings) for ep in endpoints.keys(): if single.issubset(endpoints[ep]): key = '%s-endpoint-changed' % ep log('endpoint: %s' % ep) notifications_endpoints[key] = (endpoints_dict( endpoints[ep])) notifications_checksums[key] = (endpoints_checksum( endpoints[ep])) else: log('Deferring identity_changed() to service leader.') if notifications_endpoints or notifications_checksums: send_notifications(notifications_checksums, notifications_endpoints)