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 update_all_identity_relation_units(check_db_ready=True): CONFIGS.write_all() if check_db_ready and not is_db_ready(): log('Allowed_units list provided and this unit not present', level=INFO) return if not is_db_initialised(): log( "Database not yet initialised - deferring identity-relation " "updates", level=INFO) return if is_elected_leader(CLUSTER_RES): ensure_initial_admin(config) log('Firing identity_changed hook for all related services.') for rid in relation_ids('identity-service'): for unit in related_units(rid): 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)
def install_hook(): execd_preinstall() utils.configure_source() utils.install(*packages) update_config_block('DEFAULT', public_port=cluster.determine_api_port(config["service-port"])) update_config_block('DEFAULT', admin_port=cluster.determine_api_port(config["admin-port"])) set_admin_token(config['admin-token']) # set all backends to use sql+sqlite, if they are not already by default update_config_block('sql', connection='sqlite:////var/lib/keystone/keystone.db') update_config_block('identity', driver='keystone.identity.backends.sql.Identity') update_config_block('catalog', driver='keystone.catalog.backends.sql.Catalog') update_config_block('token', driver='keystone.token.backends.sql.Token') update_config_block('ec2', driver='keystone.contrib.ec2.backends.sql.Ec2') utils.stop('keystone') execute("keystone-manage db_sync") utils.start('keystone') # ensure user + permissions for peer relations that # may be syncing data there via SSH_USER. unison.ensure_user(user=SSH_USER, group='keystone') execute("chmod -R g+wrx /var/lib/keystone/") time.sleep(5) ensure_initial_admin(config)
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(check_db_ready=False) 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() 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. Also avoid duplicate db ready check. update_all_identity_relation_units(check_db_ready=False) update_all_domain_backends()
def update_all_identity_relation_units(check_db_ready=True): CONFIGS.write_all() if is_unit_paused_set(): return if check_db_ready and not is_db_ready(): log('Allowed_units list provided and this unit not present', level=INFO) return if not is_db_initialised(): log("Database not yet initialised - deferring identity-relation " "updates", level=INFO) return if is_elected_leader(CLUSTER_RES): ensure_initial_admin(config) log('Firing identity_changed hook for all related services.') for rid in relation_ids('identity-service'): for unit in related_units(rid): 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)
def upgrade_charm(): # Ensure all required packages are installed utils.install(*packages) cluster_changed() if cluster.eligible_leader(CLUSTER_RES): utils.juju_log('INFO', 'Cluster leader - ensuring endpoint configuration' ' is up to date') ensure_initial_admin(config)
def ha_changed(): CONFIGS.write_all() clustered = relation_get('clustered') if clustered: log('Cluster configured, notifying other services and updating ' 'keystone endpoint configuration') if (is_db_initialised() and is_elected_leader(CLUSTER_RES) and not is_unit_paused_set()): ensure_initial_admin(config) update_all_identity_relation_units()
def config_changed_postupgrade(): save_script_rc() release = os_release('keystone') if run_in_apache(release=release): # Need to ensure mod_wsgi is installed and apache2 is reloaded # immediatly as charm querys its local keystone before restart # decorator can fire apt_install(filter_installed_packages(determine_packages())) # when deployed from source, init scripts aren't installed service_pause('keystone') disable_unused_apache_sites() if WSGI_KEYSTONE_API_CONF in CONFIGS.templates: CONFIGS.write(WSGI_KEYSTONE_API_CONF) if not is_unit_paused_set(): restart_pid_check('apache2') stop_manager_instance() if enable_memcache(release=release): # If charm or OpenStack have been upgraded then the list of required # packages may have changed so ensure they are installed. apt_install(filter_installed_packages(determine_packages())) if is_leader() and fernet_enabled(): key_setup() key_leader_set() configure_https() open_port(config('service-port')) update_nrpe_config() CONFIGS.write_all() if snap_install_requested() and not is_unit_paused_set(): service_restart('snap.keystone.*') stop_manager_instance() if (is_db_initialised() and is_elected_leader(CLUSTER_RES) and not is_unit_paused_set()): ensure_initial_admin(config) if CompareOpenStackReleases( os_release('keystone')) >= 'liberty': CONFIGS.write(POLICY_JSON) update_all_identity_relation_units() update_all_domain_backends() update_all_fid_backends() for r_id in relation_ids('ha'): ha_joined(relation_id=r_id) notify_middleware_with_release_version() inform_peers_if_ready(check_api_unit_ready)
def config_changed_postupgrade(): save_script_rc() release = os_release('keystone') if run_in_apache(release=release): # Need to ensure mod_wsgi is installed and apache2 is reloaded # immediatly as charm querys its local keystone before restart # decorator can fire apt_install(filter_installed_packages(determine_packages())) # when deployed from source, init scripts aren't installed service_pause('keystone') disable_unused_apache_sites() if WSGI_KEYSTONE_API_CONF in CONFIGS.templates: CONFIGS.write(WSGI_KEYSTONE_API_CONF) if not is_unit_paused_set(): restart_pid_check('apache2') stop_manager_instance() if enable_memcache(release=release): # If charm or OpenStack have been upgraded then the list of required # packages may have changed so ensure they are installed. apt_install(filter_installed_packages(determine_packages())) if is_leader() and fernet_enabled(): key_setup() key_leader_set() configure_https() open_port(config('service-port')) update_nrpe_config() CONFIGS.write_all() if snap_install_requested() and not is_unit_paused_set(): service_restart('snap.keystone.*') stop_manager_instance() if (is_db_initialised() and is_elected_leader(CLUSTER_RES) and not is_unit_paused_set()): ensure_initial_admin(config) if CompareOpenStackReleases( os_release('keystone')) >= 'liberty': CONFIGS.write(POLICY_JSON) update_all_identity_relation_units() update_all_domain_backends() update_all_fid_backends() for r_id in relation_ids('ha'): ha_joined(relation_id=r_id) notify_middleware_with_release_version()
def ha_changed(): CONFIGS.write_all() clustered = relation_get('clustered') if clustered: log('Cluster configured, notifying other services and updating ' 'keystone endpoint configuration') if (is_db_initialised() and is_elected_leader(CLUSTER_RES) and not is_unit_paused_set()): ensure_initial_admin(config) update_all_identity_relation_units() update_all_domain_backends() update_all_fid_backends()
def config_changed(): unison.ensure_user(user=SSH_USER, group='keystone') execute("chmod -R g+wrx /var/lib/keystone/") # Determine whether or not we should do an upgrade, based on the # the version offered in keyston-release. available = get_os_codename_install_source(config['openstack-origin']) installed = get_os_codename_package('keystone') if (available and get_os_version_codename(available) > \ get_os_version_codename(installed)): # TODO: fixup this call to work like utils.install() do_openstack_upgrade(config['openstack-origin'], ' '.join(packages)) # Ensure keystone group permissions execute("chmod -R g+wrx /var/lib/keystone/") env_vars = {'OPENSTACK_SERVICE_KEYSTONE': 'keystone', 'OPENSTACK_PORT_ADMIN': cluster.determine_api_port( config['admin-port']), 'OPENSTACK_PORT_PUBLIC': cluster.determine_api_port( config['service-port'])} save_script_rc(**env_vars) set_admin_token(config['admin-token']) if cluster.eligible_leader(CLUSTER_RES): utils.juju_log('INFO', 'Cluster leader - ensuring endpoint configuration' ' is up to date') ensure_initial_admin(config) update_config_block('logger_root', level=config['log-level'], file='/etc/keystone/logging.conf') if get_os_version_package('keystone') >= '2013.1': # PKI introduced in Grizzly configure_pki_tokens(config) if config_dirty(): utils.restart('keystone') if cluster.eligible_leader(CLUSTER_RES): utils.juju_log('INFO', 'Firing identity_changed hook' ' for all related services.') # HTTPS may have been set - so fire all identity relations # again for r_id in utils.relation_ids('identity-service'): for unit in utils.relation_list(r_id): identity_changed(relation_id=r_id, remote_unit=unit)
def ha_relation_changed(): relation_data = utils.relation_get_dict() if ('clustered' in relation_data and cluster.is_leader(CLUSTER_RES)): utils.juju_log('INFO', 'Cluster configured, notifying other services' ' and updating keystone endpoint configuration') # Update keystone endpoint to point at VIP ensure_initial_admin(config) # Tell all related services to start using # the VIP and haproxy ports instead for r_id in utils.relation_ids('identity-service'): utils.relation_set(rid=r_id, auth_host=config['vip'], service_host=config['vip'])
def certs_changed(relation_id=None, unit=None): # update_all_identity_relation_units calls the keystone API # so configs need to be written and services restarted # before @restart_on_change(restart_map(), stopstart=True) def write_certs_and_config(): process_certificates('keystone', relation_id, unit) configure_https() write_certs_and_config() # If enabling https the identity endpoints need updating. if (is_db_initialised() and is_elected_leader(CLUSTER_RES) and not is_unit_paused_set()): ensure_initial_admin(config) update_all_identity_relation_units() update_all_domain_backends()
def test_ensure_initial_admin_public_name( self, _create_service_entry, _create_user_creds, _create_tenant, _create_keystone_endpoint, _ip_config, _is_clustered, _unit_get): _is_clustered.return_value = False _ip_config.side_effect = self.test_config.get _unit_get.return_value = '10.0.0.1' self.test_config.set('os-public-hostname', 'keystone.example.com') utils.ensure_initial_admin(self.config) _create_keystone_endpoint.assert_called_with( public_ip='keystone.example.com', service_port=5000, internal_ip='10.0.0.1', admin_ip='10.0.0.1', auth_port=35357, region='RegionOne', )
def ha_changed(): CONFIGS.write_all() clustered = relation_get('clustered') if clustered: log('Cluster configured, notifying other services and updating ' 'keystone endpoint configuration') for rid in relation_ids('certificates'): if related_units(rid): for unit in related_units(rid): certs_changed(rid, unit) if (is_db_initialised() and is_elected_leader(CLUSTER_RES) and not is_unit_paused_set()): ensure_initial_admin(config) update_all_identity_relation_units() update_all_domain_backends() update_all_fid_backends() inform_peers_if_ready(check_api_unit_ready)
def certs_changed(relation_id=None, unit=None): # update_all_identity_relation_units calls the keystone API # so configs need to be written and services restarted # before @restart_on_change(restart_map(), stopstart=True) def write_certs_and_config(): if process_certificates('keystone', relation_id, unit): configure_https() return True return False if not write_certs_and_config(): log('no certificates for us on the relation yet, deferring.', level=INFO) return # If enabling https the identity endpoints need updating. if (is_db_initialised() and is_elected_leader(CLUSTER_RES) and not is_unit_paused_set()): ensure_initial_admin(config) update_all_identity_relation_units() update_all_domain_backends()
def test_ensure_initial_admin_public_name(self, _create_service_entry, _create_user_creds, _create_tenant, _create_keystone_endpoint, _ip_config, _is_clustered, _unit_get): _is_clustered.return_value = False _ip_config.side_effect = self.test_config.get _unit_get.return_value = '10.0.0.1' self.test_config.set('os-public-hostname', 'keystone.example.com') utils.ensure_initial_admin(self.config) _create_keystone_endpoint.assert_called_with( public_ip='keystone.example.com', service_port=5000, internal_ip='10.0.0.1', admin_ip='10.0.0.1', auth_port=35357, region='RegionOne' )
def certs_changed(relation_id=None, unit=None): # update_all_identity_relation_units calls the keystone API # so configs need to be written and services restarted # before @restart_on_change(restart_map(), stopstart=True) def write_certs_and_config(): if process_certificates('keystone', relation_id, unit): configure_https() return True return False if not write_certs_and_config(): log('no certificates for us on the relation yet, deferring.', level=INFO) return # If enabling https the identity endpoints need updating. if (is_db_initialised() and is_elected_leader(CLUSTER_RES) and not is_unit_paused_set()): ensure_initial_admin(config) update_all_identity_relation_units() update_all_domain_backends() update_all_fid_backends() inform_peers_if_ready(check_api_unit_ready)
def db_changed(): relation_data = utils.relation_get_dict() if ('password' not in relation_data or 'db_host' not in relation_data): utils.juju_log('INFO', "db_host or password not set. Peer not ready, exit 0") return update_config_block('sql', connection="mysql://%s:%s@%s/%s" % (config["database-user"], relation_data["password"], relation_data["db_host"], config["database"])) if cluster.eligible_leader(CLUSTER_RES): utils.juju_log('INFO', 'Cluster leader, performing db-sync') execute("keystone-manage db_sync", echo=True) if config_dirty(): utils.restart('keystone') time.sleep(5) if cluster.eligible_leader(CLUSTER_RES): ensure_initial_admin(config) # If the backend database has been switched to something new and there # are existing identity-service relations,, service entries need to be # recreated in the new database. Re-executing identity-service-changed # will do this. for rid in utils.relation_ids('identity-service'): for unit in utils.relation_list(rid=rid): utils.juju_log('INFO', "Re-exec'ing identity-service-changed" " for: %s - %s" % (rid, unit)) identity_changed(relation_id=rid, remote_unit=unit)