def install():
    status_set('maintenance', 'Executing pre-install')
    execd_preinstall()
    configure_installation_source(config('openstack-origin'))
    status_set('maintenance', 'Installing apt packages')
    apt_update()
    apt_install(determine_packages(), fatal=True)

    if snap_install_requested():
        status_set('maintenance', 'Installing keystone snap')
        snap_install('keystone', '--edge', '--classic')
        service_pause('snap.keystone.uwsgi')
        service_pause('snap.keystone.nginx')
    else:
        if run_in_apache():
            disable_unused_apache_sites()
            if not git_install_requested():
                service_pause('keystone')

    status_set('maintenance', 'Git install')
    git_install(config('openstack-origin-git'))

    unison.ensure_user(user=SSH_USER, group='juju_keystone')
    # NOTE(coreycb): can just use group='keystone' once snap has drop privs support
    if snap_install_requested():
        unison.ensure_user(user=SSH_USER, group='root')
    else:
        unison.ensure_user(user=SSH_USER, group='keystone')
def config_changed_postupgrade():
    # Ensure ssl dir exists and is unison-accessible
    ensure_ssl_dir()

    if not snap_install_requested():
        check_call(['chmod', '-R', 'g+wrx', '/var/lib/keystone/'])

    ensure_ssl_dirs()

    save_script_rc()
    if run_in_apache():
        # 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
        if not git_install_requested():
            service_pause('keystone')
        if snap_install_requested():
            service_pause('snap.keystone.uwsgi')
            service_pause('snap.keystone.nginx')
        else:
           disable_unused_apache_sites()
           CONFIGS.write(WSGI_KEYSTONE_API_CONF)
           if not is_unit_paused_set():
               restart_pid_check('apache2')
    # NOTE(coreycb): Need to add https support for snap with nginx
    if not snap_install_requested():
        configure_https()
    open_port(config('service-port'))

    if not snap_install_requested():
        update_nrpe_config()
    CONFIGS.write_all()

    # NOTE(coreycb): Can dropp check once snap has alias support and
    # drops privileges.
    if not snap_install_requested():
        initialise_pki()

    update_all_identity_relation_units()
    update_all_domain_backends()

    # Ensure sync request is sent out (needed for any/all ssl change)
    send_ssl_sync_request()

    for r_id in relation_ids('ha'):
        ha_joined(relation_id=r_id)
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):
            if not is_unit_paused_set():
                if snap_install_requested():
                    service_restart('snap.keystone.nginx')
                    service_restart('snap.keystone.uwsgi')
                else:
                    service_restart(keystone_service())
            db.set(domain_nonce_key, restart_nonce)
            db.flush()
def config_changed():
    if config('prefer-ipv6'):
        status_set('maintenance', 'configuring ipv6')
        setup_ipv6()
        sync_db_with_multi_ipv6_addresses(config('database'),
                                          config('database-user'))

    unison.ensure_user(user=SSH_USER, group='juju_keystone')
    # NOTE(coreycb): can just use group='keystone' once snap has drop privs support
    if snap_install_requested():
        unison.ensure_user(user=SSH_USER, group='root')
    else:
        unison.ensure_user(user=SSH_USER, group='keystone')
    homedir = unison.get_homedir(SSH_USER)
    if not os.path.isdir(homedir):
        mkdir(homedir, SSH_USER, 'juju_keystone', 0o775)

    if git_install_requested():
        if config_value_changed('openstack-origin-git'):
            status_set('maintenance', 'Running Git install')
            git_install(config('openstack-origin-git'))
    elif not config('action-managed-upgrade'):
        if openstack_upgrade_available('keystone'):
            status_set('maintenance', 'Running openstack upgrade')
            do_openstack_upgrade_reexec(configs=CONFIGS)

    config_changed_postupgrade()
    def __call__(self):
        from keystone_utils import (
            snap_install_requested,
        )
        ctxt = {}
        debug = config('debug')
        if debug:
            ctxt['root_level'] = 'DEBUG'
        log_level = config('log-level')
        log_level_accepted_params = ['WARNING', 'INFO', 'DEBUG', 'ERROR']
        if log_level in log_level_accepted_params:
            ctxt['log_level'] = config('log-level')
        else:
            log("log-level must be one of the following states "
                "(WARNING, INFO, DEBUG, ERROR) keeping the current state.")
            ctxt['log_level'] = None
        if snap_install_requested():
            ctxt['snap_install'] = config('openstack-origin')

        return ctxt
Exemple #6
0
    def __call__(self):
        from keystone_utils import (
            snap_install_requested, )
        ctxt = {}
        debug = config('debug')
        if debug:
            ctxt['root_level'] = 'DEBUG'
        log_level = config('log-level')
        log_level_accepted_params = ['WARNING', 'INFO', 'DEBUG', 'ERROR']
        if log_level in log_level_accepted_params:
            ctxt['log_level'] = config('log-level')
        else:
            log("log-level must be one of the following states "
                "(WARNING, INFO, DEBUG, ERROR) keeping the current state.")
            ctxt['log_level'] = None
        if snap_install_requested():
            ctxt['log_file'] = ('/var/snap/keystone/common/log/keystone.log')
        else:
            ctxt['log_file'] = '/var/log/keystone/keystone.log'

        return ctxt
def cluster_changed():
    unison.ssh_authorized_peers(user=SSH_USER,
                                group='juju_keystone',
                                peer_interface='cluster',
                                ensure_local_user=True)
    # NOTE(jamespage) re-echo passwords for peer storage
    echo_whitelist = ['_passwd', 'identity-service:', 'ssl-cert-master',
                      'db-initialised', 'ssl-cert-available-updates']
    log("Peer echo whitelist: %s" % (echo_whitelist), level=DEBUG)
    peer_echo(includes=echo_whitelist, force=True)

    check_peer_actions()

    # NOTE(coreycb): Can dropp check once snap has alias support and
    # drops privileges.
    if not snap_install_requested():
        initialise_pki()

    # Figure out if we need to mandate a sync
    units = get_ssl_sync_request_units()
    synced_units = relation_get(attribute='ssl-synced-units',
                                unit=local_unit())
    diff = None
    if synced_units:
        synced_units = json.loads(synced_units)
        diff = set(units).symmetric_difference(set(synced_units))

    if units and (not synced_units or diff):
        log("New peers joined and need syncing - %s" %
            (', '.join(units)), level=DEBUG)
        update_all_identity_relation_units_force_sync()
    else:
        update_all_identity_relation_units()

    if not is_elected_leader(CLUSTER_RES) and is_ssl_cert_master():
        # Force and sync and trigger a sync master re-election since we are not
        # leader anymore.
        force_ssl_sync()
    else:
        CONFIGS.write_all()
Exemple #8
0
    def __call__(self):
        from keystone_utils import (
            api_port,
            endpoint_url,
            resolve_address,
            PUBLIC,
            ADMIN,
            ADMIN_DOMAIN,
            snap_install_requested,
            get_api_version,
        )
        ctxt = {}
        ctxt['api_version'] = get_api_version()
        ctxt['admin_role'] = config('admin-role')
        if ctxt['api_version'] > 2:
            ctxt['service_tenant_id'] = \
                leader_get(attribute='service_tenant_id')
            ctxt['admin_domain_name'] = ADMIN_DOMAIN
            ctxt['admin_domain_id'] = \
                leader_get(attribute='admin_domain_id')
            ctxt['default_domain_id'] = \
                leader_get(attribute='default_domain_id')
            # This is required prior to system-scope being implemented (Queens)
            ctxt['transitional_charm_user_id'] = leader_get(
                attribute='transitional_charm_user_id')
        ctxt['admin_port'] = determine_api_port(api_port('keystone-admin'),
                                                singlenode_mode=True)
        ctxt['public_port'] = determine_api_port(api_port('keystone-public'),
                                                 singlenode_mode=True)

        ctxt['debug'] = config('debug')
        ctxt['verbose'] = config('verbose')
        ctxt['token_expiration'] = config('token-expiration')

        ctxt['identity_backend'] = config('identity-backend')
        ctxt['assignment_backend'] = config('assignment-backend')
        ctxt['token_provider'] = config('token-provider')
        ctxt['fernet_max_active_keys'] = config('fernet-max-active-keys')
        if config('identity-backend') == 'ldap':
            ctxt['ldap_server'] = config('ldap-server')
            ctxt['ldap_user'] = config('ldap-user')
            ctxt['ldap_password'] = config('ldap-password')
            ctxt['ldap_suffix'] = config('ldap-suffix')
            ctxt['ldap_readonly'] = config('ldap-readonly')
            ldap_flags = config('ldap-config-flags')
            if ldap_flags:
                flags = context.config_flags_parser(ldap_flags)
                ctxt['ldap_config_flags'] = flags

        # Only try to decode it if there is something actually set - this
        # siliences a NoneType warning in the logs if it isn't set
        password_security_compliance = config('password-security-compliance')
        if password_security_compliance:
            ctxt['password_security_compliance'] = (
                self._decode_password_security_compliance_string(
                    password_security_compliance))

        # Base endpoint URL's which are used in keystone responses
        # to unauthenticated requests to redirect clients to the
        # correct auth URL.
        ctxt['public_endpoint'] = endpoint_url(
            resolve_address(PUBLIC),
            api_port('keystone-public')).replace('v2.0', '')
        ctxt['admin_endpoint'] = endpoint_url(
            resolve_address(ADMIN),
            api_port('keystone-admin')).replace('v2.0', '')

        if snap_install_requested():
            ctxt['domain_config_dir'] = (
                '/var/snap/keystone/common/etc/keystone/domains')
            ctxt['log_config'] = (
                '/var/snap/keystone/common/etc/keystone/logging.conf')
            ctxt['paste_config_file'] = (
                '/var/snap/keystone/common/etc/keystone/keystone-paste.ini')
        else:
            ctxt['domain_config_dir'] = '/etc/keystone/domains'
            ctxt['log_config'] = ('/etc/keystone/logging.conf')
            ctxt['paste_config_file'] = '/etc/keystone/keystone-paste.ini'

        return ctxt
Exemple #9
0
    def __call__(self):
        from keystone_utils import (
            api_port,
            set_admin_token,
            endpoint_url,
            resolve_address,
            PUBLIC,
            ADMIN,
            PKI_CERTS_DIR,
            ensure_pki_cert_paths,
            ADMIN_DOMAIN,
            snap_install_requested,
            get_api_version,
        )
        ctxt = {}
        ctxt['token'] = set_admin_token(config('admin-token'))
        ctxt['api_version'] = get_api_version()
        ctxt['admin_role'] = config('admin-role')
        if ctxt['api_version'] > 2:
            ctxt['service_tenant_id'] = \
                leader_get(attribute='service_tenant_id')
            ctxt['admin_domain_name'] = ADMIN_DOMAIN
            ctxt['admin_domain_id'] = \
                leader_get(attribute='admin_domain_id')
            ctxt['default_domain_id'] = \
                leader_get(attribute='default_domain_id')
        ctxt['admin_port'] = determine_api_port(api_port('keystone-admin'),
                                                singlenode_mode=True)
        ctxt['public_port'] = determine_api_port(api_port('keystone-public'),
                                                 singlenode_mode=True)

        ctxt['debug'] = config('debug')
        ctxt['verbose'] = config('verbose')
        ctxt['token_expiration'] = config('token-expiration')

        ctxt['identity_backend'] = config('identity-backend')
        ctxt['assignment_backend'] = config('assignment-backend')
        if config('identity-backend') == 'ldap':
            ctxt['ldap_server'] = config('ldap-server')
            ctxt['ldap_user'] = config('ldap-user')
            ctxt['ldap_password'] = config('ldap-password')
            ctxt['ldap_suffix'] = config('ldap-suffix')
            ctxt['ldap_readonly'] = config('ldap-readonly')
            ldap_flags = config('ldap-config-flags')
            if ldap_flags:
                flags = context.config_flags_parser(ldap_flags)
                ctxt['ldap_config_flags'] = flags

        enable_pki = config('enable-pki')
        if enable_pki and bool_from_string(enable_pki):
            log("Enabling PKI", level=DEBUG)
            ctxt['token_provider'] = 'pki'

            # NOTE(jamespage): Only check PKI configuration if the PKI
            #                  token format is in use, which has been
            #                  removed as of OpenStack Ocata.
            ensure_pki_cert_paths()
            certs = os.path.join(PKI_CERTS_DIR, 'certs')
            privates = os.path.join(PKI_CERTS_DIR, 'privates')
            ctxt['enable_signing'] = True
            ctxt.update({
                'certfile': os.path.join(certs, 'signing_cert.pem'),
                'keyfile': os.path.join(privates, 'signing_key.pem'),
                'ca_certs': os.path.join(certs, 'ca.pem'),
                'ca_key': os.path.join(certs, 'ca_key.pem')
            })
        else:
            ctxt['enable_signing'] = False

        # Base endpoint URL's which are used in keystone responses
        # to unauthenticated requests to redirect clients to the
        # correct auth URL.
        ctxt['public_endpoint'] = endpoint_url(
            resolve_address(PUBLIC),
            api_port('keystone-public')).replace('v2.0', '')
        ctxt['admin_endpoint'] = endpoint_url(
            resolve_address(ADMIN),
            api_port('keystone-admin')).replace('v2.0', '')

        if snap_install_requested():
            ctxt['domain_config_dir'] = (
                '/var/snap/keystone/common/etc/keystone/domains')
            ctxt['log_config'] = (
                '/var/snap/keystone/common/etc/keystone/logging.conf')
            ctxt['paste_config_file'] = (
                '/var/snap/keystone/common/etc/keystone/keystone-paste.ini')
        else:
            ctxt['domain_config_dir'] = '/etc/keystone/domains'
            ctxt['log_config'] = ('/etc/keystone/logging.conf')
            ctxt['paste_config_file'] = '/etc/keystone/keystone-paste.ini'

        return ctxt
    def __call__(self):
        from keystone_utils import (
            api_port, set_admin_token, endpoint_url, resolve_address,
            PUBLIC, ADMIN, PKI_CERTS_DIR, ensure_pki_cert_paths, ADMIN_DOMAIN,
            snap_install_requested,
        )
        ctxt = {}
        ctxt['token'] = set_admin_token(config('admin-token'))
        ctxt['api_version'] = int(config('preferred-api-version'))
        ctxt['admin_role'] = config('admin-role')
        if ctxt['api_version'] > 2:
            ctxt['service_tenant_id'] = \
                leader_get(attribute='service_tenant_id')
            ctxt['admin_domain_name'] = ADMIN_DOMAIN
            ctxt['admin_domain_id'] = \
                leader_get(attribute='admin_domain_id')
            ctxt['default_domain_id'] = \
                leader_get(attribute='default_domain_id')
        ctxt['admin_port'] = determine_api_port(api_port('keystone-admin'),
                                                singlenode_mode=True)
        ctxt['public_port'] = determine_api_port(api_port('keystone-public'),
                                                 singlenode_mode=True)

        ctxt['debug'] = config('debug')
        ctxt['verbose'] = config('verbose')
        ctxt['token_expiration'] = config('token-expiration')

        ctxt['identity_backend'] = config('identity-backend')
        ctxt['assignment_backend'] = config('assignment-backend')
        if config('identity-backend') == 'ldap':
            ctxt['ldap_server'] = config('ldap-server')
            ctxt['ldap_user'] = config('ldap-user')
            ctxt['ldap_password'] = config('ldap-password')
            ctxt['ldap_suffix'] = config('ldap-suffix')
            ctxt['ldap_readonly'] = config('ldap-readonly')
            ldap_flags = config('ldap-config-flags')
            if ldap_flags:
                flags = context.config_flags_parser(ldap_flags)
                ctxt['ldap_config_flags'] = flags

        enable_pki = config('enable-pki')
        if enable_pki and bool_from_string(enable_pki):
            log("Enabling PKI", level=DEBUG)
            ctxt['token_provider'] = 'pki'

        ensure_pki_cert_paths()
        certs = os.path.join(PKI_CERTS_DIR, 'certs')
        privates = os.path.join(PKI_CERTS_DIR, 'privates')
        ctxt.update({'certfile': os.path.join(certs, 'signing_cert.pem'),
                     'keyfile': os.path.join(privates, 'signing_key.pem'),
                     'ca_certs': os.path.join(certs, 'ca.pem'),
                     'ca_key': os.path.join(certs, 'ca_key.pem')})

        # Base endpoint URL's which are used in keystone responses
        # to unauthenticated requests to redirect clients to the
        # correct auth URL.
        ctxt['public_endpoint'] = endpoint_url(
            resolve_address(PUBLIC),
            api_port('keystone-public')).replace('v2.0', '')
        ctxt['admin_endpoint'] = endpoint_url(
            resolve_address(ADMIN),
            api_port('keystone-admin')).replace('v2.0', '')

        if snap_install_requested():
            ctxt['snap_install'] = config('openstack-origin')

        return ctxt
    def __call__(self):
        from keystone_utils import (
            api_port,
            set_admin_token,
            endpoint_url,
            resolve_address,
            PUBLIC,
            ADMIN,
            ADMIN_DOMAIN,
            snap_install_requested,
            get_api_version,
        )
        ctxt = {}
        ctxt['token'] = set_admin_token(config('admin-token'))
        ctxt['api_version'] = get_api_version()
        ctxt['admin_role'] = config('admin-role')
        if ctxt['api_version'] > 2:
            ctxt['service_tenant_id'] = \
                leader_get(attribute='service_tenant_id')
            ctxt['admin_domain_name'] = ADMIN_DOMAIN
            ctxt['admin_domain_id'] = \
                leader_get(attribute='admin_domain_id')
            ctxt['default_domain_id'] = \
                leader_get(attribute='default_domain_id')
        ctxt['admin_port'] = determine_api_port(api_port('keystone-admin'),
                                                singlenode_mode=True)
        ctxt['public_port'] = determine_api_port(api_port('keystone-public'),
                                                 singlenode_mode=True)

        ctxt['debug'] = config('debug')
        ctxt['verbose'] = config('verbose')
        ctxt['token_expiration'] = config('token-expiration')

        ctxt['identity_backend'] = config('identity-backend')
        ctxt['assignment_backend'] = config('assignment-backend')
        ctxt['token_provider'] = config('token-provider')
        ctxt['fernet_max_active_keys'] = config('fernet-max-active-keys')
        if config('identity-backend') == 'ldap':
            ctxt['ldap_server'] = config('ldap-server')
            ctxt['ldap_user'] = config('ldap-user')
            ctxt['ldap_password'] = config('ldap-password')
            ctxt['ldap_suffix'] = config('ldap-suffix')
            ctxt['ldap_readonly'] = config('ldap-readonly')
            ldap_flags = config('ldap-config-flags')
            if ldap_flags:
                flags = context.config_flags_parser(ldap_flags)
                ctxt['ldap_config_flags'] = flags

        # Base endpoint URL's which are used in keystone responses
        # to unauthenticated requests to redirect clients to the
        # correct auth URL.
        ctxt['public_endpoint'] = endpoint_url(
            resolve_address(PUBLIC),
            api_port('keystone-public')).replace('v2.0', '')
        ctxt['admin_endpoint'] = endpoint_url(
            resolve_address(ADMIN),
            api_port('keystone-admin')).replace('v2.0', '')

        if snap_install_requested():
            ctxt['domain_config_dir'] = (
                '/var/snap/keystone/common/etc/keystone/domains')
            ctxt['log_config'] = (
                '/var/snap/keystone/common/etc/keystone/logging.conf')
            ctxt['paste_config_file'] = (
                '/var/snap/keystone/common/etc/keystone/keystone-paste.ini')
        else:
            ctxt['domain_config_dir'] = '/etc/keystone/domains'
            ctxt['log_config'] = ('/etc/keystone/logging.conf')
            ctxt['paste_config_file'] = '/etc/keystone/keystone-paste.ini'

        return ctxt
    def __call__(self):
        from keystone_utils import (
            api_port, set_admin_token, endpoint_url, resolve_address,
            PUBLIC, ADMIN, ADMIN_DOMAIN,
            snap_install_requested, get_api_version,
        )
        ctxt = {}
        ctxt['token'] = set_admin_token(config('admin-token'))
        ctxt['api_version'] = get_api_version()
        ctxt['admin_role'] = config('admin-role')
        if ctxt['api_version'] > 2:
            ctxt['service_tenant_id'] = \
                leader_get(attribute='service_tenant_id')
            ctxt['admin_domain_name'] = ADMIN_DOMAIN
            ctxt['admin_domain_id'] = \
                leader_get(attribute='admin_domain_id')
            ctxt['default_domain_id'] = \
                leader_get(attribute='default_domain_id')
        ctxt['admin_port'] = determine_api_port(api_port('keystone-admin'),
                                                singlenode_mode=True)
        ctxt['public_port'] = determine_api_port(api_port('keystone-public'),
                                                 singlenode_mode=True)

        ctxt['debug'] = config('debug')
        ctxt['verbose'] = config('verbose')
        ctxt['token_expiration'] = config('token-expiration')

        ctxt['identity_backend'] = config('identity-backend')
        ctxt['assignment_backend'] = config('assignment-backend')
        ctxt['token_provider'] = config('token-provider')
        ctxt['fernet_max_active_keys'] = config('fernet-max-active-keys')
        if config('identity-backend') == 'ldap':
            ctxt['ldap_server'] = config('ldap-server')
            ctxt['ldap_user'] = config('ldap-user')
            ctxt['ldap_password'] = config('ldap-password')
            ctxt['ldap_suffix'] = config('ldap-suffix')
            ctxt['ldap_readonly'] = config('ldap-readonly')
            ldap_flags = config('ldap-config-flags')
            if ldap_flags:
                flags = context.config_flags_parser(ldap_flags)
                ctxt['ldap_config_flags'] = flags

        # Base endpoint URL's which are used in keystone responses
        # to unauthenticated requests to redirect clients to the
        # correct auth URL.
        ctxt['public_endpoint'] = endpoint_url(
            resolve_address(PUBLIC),
            api_port('keystone-public')).replace('v2.0', '')
        ctxt['admin_endpoint'] = endpoint_url(
            resolve_address(ADMIN),
            api_port('keystone-admin')).replace('v2.0', '')

        if snap_install_requested():
            ctxt['domain_config_dir'] = (
                '/var/snap/keystone/common/etc/keystone/domains')
            ctxt['log_config'] = (
                '/var/snap/keystone/common/etc/keystone/logging.conf')
            ctxt['paste_config_file'] = (
                '/var/snap/keystone/common/etc/keystone/keystone-paste.ini')
        else:
            ctxt['domain_config_dir'] = '/etc/keystone/domains'
            ctxt['log_config'] = ('/etc/keystone/logging.conf')
            ctxt['paste_config_file'] = '/etc/keystone/keystone-paste.ini'

        return ctxt