# lib/keystone
# Functions to control the configuration and operation of **Keystone**

# Dependencies:
#
# - ``functions`` file
# - ``tls`` file
# - ``DEST``, ``STACK_USER``
# - ``FILES``
# - ``IDENTITY_API_VERSION``
# - ``BASE_SQL_CONN``
# - ``SERVICE_HOST``, ``SERVICE_PROTOCOL``
# - ``SERVICE_TOKEN``
# - ``S3_SERVICE_PORT`` (template backend only)

# ``stack.sh`` calls the entry points in this order:
#
# - install_keystone
# - configure_keystone
# - _config_keystone_apache_wsgi
# - init_keystone
# - start_keystone
# - create_keystone_accounts
# - stop_keystone
# - cleanup_keystone
# - _cleanup_keystone_apache_wsgi

# Save trace setting
XTRACE=$(set +o | grep xtrace)
set +o xtrace

# Defaults
# --------

# Set up default directories
GITDIR["python-keystoneclient"]=$DEST/python-keystoneclient
GITDIR["keystonemiddleware"]=$DEST/keystonemiddleware

KEYSTONE_DIR=$DEST/keystone
KEYSTONE_CONF_DIR=${KEYSTONE_CONF_DIR:-/etc/keystone}
KEYSTONE_CONF=$KEYSTONE_CONF_DIR/keystone.conf
KEYSTONE_PASTE_INI=${KEYSTONE_PASTE_INI:-$KEYSTONE_CONF_DIR/keystone-paste.ini}
KEYSTONE_AUTH_CACHE_DIR=${KEYSTONE_AUTH_CACHE_DIR:-/var/cache/keystone}
if is_suse; then
    KEYSTONE_WSGI_DIR=${KEYSTONE_WSGI_DIR:-/srv/www/htdocs/keystone}
else
    KEYSTONE_WSGI_DIR=${KEYSTONE_WSGI_DIR:-/var/www/keystone}
fi

# Set up additional extensions, such as oauth1, federation
# Example of KEYSTONE_EXTENSIONS=oauth1,federation
KEYSTONE_EXTENSIONS=${KEYSTONE_EXTENSIONS:-}

# Toggle for deploying Keystone under HTTPD + mod_wsgi
KEYSTONE_USE_MOD_WSGI=${KEYSTONE_USE_MOD_WSGI:-${ENABLE_HTTPD_MOD_WSGI_SERVICES}}

# Select the backend for Keystone's service catalog
KEYSTONE_CATALOG_BACKEND=${KEYSTONE_CATALOG_BACKEND:-sql}
KEYSTONE_CATALOG=$KEYSTONE_CONF_DIR/default_catalog.templates

# Select the backend for Tokens
KEYSTONE_TOKEN_BACKEND=${KEYSTONE_TOKEN_BACKEND:-sql}

# Select the backend for Identity
KEYSTONE_IDENTITY_BACKEND=${KEYSTONE_IDENTITY_BACKEND:-sql}

# Select the backend for Assignment
KEYSTONE_ASSIGNMENT_BACKEND=${KEYSTONE_ASSIGNMENT_BACKEND:-sql}

# Select Keystone's token format
# Choose from 'UUID', 'PKI', or 'PKIZ'
KEYSTONE_TOKEN_FORMAT=$(echo ${KEYSTONE_TOKEN_FORMAT} | tr '[:upper:]' '[:lower:]')

# Set Keystone interface configuration
KEYSTONE_AUTH_HOST=${KEYSTONE_AUTH_HOST:-$SERVICE_HOST}
KEYSTONE_AUTH_PORT=${KEYSTONE_AUTH_PORT:-35357}
KEYSTONE_AUTH_PORT_INT=${KEYSTONE_AUTH_PORT_INT:-35358}
KEYSTONE_AUTH_PROTOCOL=${KEYSTONE_AUTH_PROTOCOL:-$SERVICE_PROTOCOL}

# Public facing bits
KEYSTONE_SERVICE_HOST=${KEYSTONE_SERVICE_HOST:-$SERVICE_HOST}
KEYSTONE_SERVICE_PORT=${KEYSTONE_SERVICE_PORT:-5000}
KEYSTONE_SERVICE_PORT_INT=${KEYSTONE_SERVICE_PORT_INT:-5001}
KEYSTONE_SERVICE_PROTOCOL=${KEYSTONE_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}

# Bind hosts
KEYSTONE_ADMIN_BIND_HOST=${KEYSTONE_ADMIN_BIND_HOST:-$KEYSTONE_SERVICE_HOST}
# Set the tenant for service accounts in Keystone
SERVICE_TENANT_NAME=${SERVICE_TENANT_NAME:-service}

# valid identity backends as per dir keystone/identity/backends
KEYSTONE_VALID_IDENTITY_BACKENDS=kvs,ldap,pam,sql

# valid assignment backends as per dir keystone/identity/backends
KEYSTONE_VALID_ASSIGNMENT_BACKENDS=kvs,ldap,sql

# if we are running with SSL use https protocols
if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
    KEYSTONE_AUTH_PROTOCOL="https"
    KEYSTONE_SERVICE_PROTOCOL="https"
fi

# complete URIs
KEYSTONE_AUTH_URI=${KEYSTONE_AUTH_PROTOCOL}://${KEYSTONE_AUTH_HOST}:${KEYSTONE_AUTH_PORT}
KEYSTONE_SERVICE_URI=${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}

# Functions
# ---------
# cleanup_keystone() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_keystone {
    _cleanup_keystone_apache_wsgi
}

# _cleanup_keystone_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
function _cleanup_keystone_apache_wsgi {
    sudo rm -f $KEYSTONE_WSGI_DIR/*.wsgi
    sudo rm -f $(apache_site_config_for keystone)
}

# _config_keystone_apache_wsgi() - Set WSGI config files of Keystone
function _config_keystone_apache_wsgi {
    sudo mkdir -p $KEYSTONE_WSGI_DIR

    local keystone_apache_conf=$(apache_site_config_for keystone)
    local keystone_ssl=""
    local keystone_certfile=""
    local keystone_keyfile=""
    local keystone_service_port=$KEYSTONE_SERVICE_PORT
    local keystone_auth_port=$KEYSTONE_AUTH_PORT

    if is_ssl_enabled_service key; then
        keystone_ssl="SSLEngine On"
        keystone_certfile="SSLCertificateFile $KEYSTONE_SSL_CERT"
        keystone_keyfile="SSLCertificateKeyFile $KEYSTONE_SSL_KEY"
    fi
    if is_service_enabled tls-proxy; then
        keystone_service_port=$KEYSTONE_SERVICE_PORT_INT
        keystone_auth_port=$KEYSTONE_AUTH_PORT_INT
    fi

    # copy proxy vhost and wsgi file
    sudo cp $KEYSTONE_DIR/httpd/keystone.py $KEYSTONE_WSGI_DIR/main
    sudo cp $KEYSTONE_DIR/httpd/keystone.py $KEYSTONE_WSGI_DIR/admin

    sudo cp $FILES/apache-keystone.template $keystone_apache_conf
    sudo sed -e "
        s|%PUBLICPORT%|$keystone_service_port|g;
        s|%ADMINPORT%|$keystone_auth_port|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%PUBLICWSGI%|$KEYSTONE_WSGI_DIR/main|g;
        s|%ADMINWSGI%|$KEYSTONE_WSGI_DIR/admin|g;
        s|%SSLENGINE%|$keystone_ssl|g;
        s|%SSLCERTFILE%|$keystone_certfile|g;
        s|%SSLKEYFILE%|$keystone_keyfile|g;
        s|%USER%|$STACK_USER|g
    " -i $keystone_apache_conf
}

# configure_keystone() - Set config files, create data dirs, etc
function configure_keystone {
    if [[ ! -d $KEYSTONE_CONF_DIR ]]; then
        sudo mkdir -p $KEYSTONE_CONF_DIR
    fi
    sudo chown $STACK_USER $KEYSTONE_CONF_DIR

    if [[ "$KEYSTONE_CONF_DIR" != "$KEYSTONE_DIR/etc" ]]; then
        cp -p $KEYSTONE_DIR/etc/keystone.conf.sample $KEYSTONE_CONF
        chmod 600 $KEYSTONE_CONF
        cp -p $KEYSTONE_DIR/etc/policy.json $KEYSTONE_CONF_DIR
        if [[ -f "$KEYSTONE_DIR/etc/keystone-paste.ini" ]]; then
            cp -p "$KEYSTONE_DIR/etc/keystone-paste.ini" "$KEYSTONE_PASTE_INI"
        fi
    fi
    if [[ -f "$KEYSTONE_PASTE_INI" ]]; then
        iniset "$KEYSTONE_CONF" paste_deploy config_file "$KEYSTONE_PASTE_INI"
    else
        # compatibility with mixed cfg and paste.deploy configuration
        KEYSTONE_PASTE_INI="$KEYSTONE_CONF"
    fi

    configure_keystone_extensions

    # Rewrite stock ``keystone.conf``

    if is_service_enabled ldap; then
        #Set all needed ldap values
        iniset $KEYSTONE_CONF ldap password $LDAP_PASSWORD
        iniset $KEYSTONE_CONF ldap user $LDAP_MANAGER_DN
        iniset $KEYSTONE_CONF ldap suffix $LDAP_BASE_DN
        iniset $KEYSTONE_CONF ldap use_dumb_member "True"
        iniset $KEYSTONE_CONF ldap user_attribute_ignore "enabled,email,tenants,default_project_id"
        iniset $KEYSTONE_CONF ldap tenant_attribute_ignore "enabled"
        iniset $KEYSTONE_CONF ldap tenant_domain_id_attribute "businessCategory"
        iniset $KEYSTONE_CONF ldap tenant_desc_attribute "description"
        iniset $KEYSTONE_CONF ldap tenant_tree_dn "ou=Projects,$LDAP_BASE_DN"
        iniset $KEYSTONE_CONF ldap user_domain_id_attribute "businessCategory"
        iniset $KEYSTONE_CONF ldap user_tree_dn "ou=Users,$LDAP_BASE_DN"
        iniset $KEYSTONE_CONF DEFAULT member_role_id "9fe2ff9ee4384b1894a90878d3e92bab"
        iniset $KEYSTONE_CONF DEFAULT member_role_name "_member_"
    fi

    # check if identity backend is valid
    if [[ "$KEYSTONE_VALID_IDENTITY_BACKENDS" =~ "$KEYSTONE_IDENTITY_BACKEND" ]]; then
        iniset $KEYSTONE_CONF identity driver "keystone.identity.backends.$KEYSTONE_IDENTITY_BACKEND.Identity"
    fi

    # check if assignment backend is valid
    if [[ "$KEYSTONE_VALID_ASSIGNMENT_BACKENDS" =~ "$KEYSTONE_ASSIGNMENT_BACKEND" ]]; then
        iniset $KEYSTONE_CONF assignment driver "keystone.assignment.backends.$KEYSTONE_ASSIGNMENT_BACKEND.Assignment"
    fi

    # Configure rabbitmq credentials
    if is_service_enabled rabbit; then
        iniset $KEYSTONE_CONF DEFAULT rabbit_password $RABBIT_PASSWORD
        iniset $KEYSTONE_CONF DEFAULT rabbit_host $RABBIT_HOST
    fi

    # Set the URL advertised in the ``versions`` structure returned by the '/' route
    if is_service_enabled tls-proxy; then
        iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/"
        iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/"
    else
        iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(public_port)s/"
        iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(admin_port)s/"
    fi
    iniset $KEYSTONE_CONF DEFAULT admin_bind_host "$KEYSTONE_ADMIN_BIND_HOST"

    # Register SSL certificates if provided
    if is_ssl_enabled_service key; then
        ensure_certificates KEYSTONE

        iniset $KEYSTONE_CONF ssl enable True
        iniset $KEYSTONE_CONF ssl certfile $KEYSTONE_SSL_CERT
        iniset $KEYSTONE_CONF ssl keyfile $KEYSTONE_SSL_KEY
    fi

    if is_service_enabled tls-proxy; then
        # Set the service ports for a proxy to take the originals
        iniset $KEYSTONE_CONF DEFAULT public_port $KEYSTONE_SERVICE_PORT_INT
        iniset $KEYSTONE_CONF DEFAULT admin_port $KEYSTONE_AUTH_PORT_INT
    fi

    iniset $KEYSTONE_CONF DEFAULT admin_token "$SERVICE_TOKEN"

    if [[ "$KEYSTONE_TOKEN_FORMAT" != "" ]]; then
        iniset $KEYSTONE_CONF token provider keystone.token.providers.$KEYSTONE_TOKEN_FORMAT.Provider
    fi

    iniset $KEYSTONE_CONF database connection `database_connection_url keystone`
    iniset $KEYSTONE_CONF ec2 driver "keystone.contrib.ec2.backends.sql.Ec2"

    if [[ "$KEYSTONE_TOKEN_BACKEND" = "sql" ]]; then
        iniset $KEYSTONE_CONF token driver keystone.token.persistence.backends.sql.Token
    elif [[ "$KEYSTONE_TOKEN_BACKEND" = "memcache" ]]; then
        iniset $KEYSTONE_CONF token driver keystone.token.persistence.backends.memcache.Token
    else
        iniset $KEYSTONE_CONF token driver keystone.token.persistence.backends.kvs.Token
    fi

    if [[ "$KEYSTONE_CATALOG_BACKEND" = "sql" ]]; then
        # Configure ``keystone.conf`` to use sql
        iniset $KEYSTONE_CONF catalog driver keystone.catalog.backends.sql.Catalog
        inicomment $KEYSTONE_CONF catalog template_file
    else
        cp -p $FILES/default_catalog.templates $KEYSTONE_CATALOG

        # Add swift endpoints to service catalog if swift is enabled
        if is_service_enabled s-proxy; then
            echo "catalog.RegionOne.object_store.publicURL = http://%SERVICE_HOST%:8080/v1/AUTH_\$(tenant_id)s" >> $KEYSTONE_CATALOG
            echo "catalog.RegionOne.object_store.adminURL = http://%SERVICE_HOST%:8080/" >> $KEYSTONE_CATALOG
            echo "catalog.RegionOne.object_store.internalURL = http://%SERVICE_HOST%:8080/v1/AUTH_\$(tenant_id)s" >> $KEYSTONE_CATALOG
            echo "catalog.RegionOne.object_store.name = Swift Service" >> $KEYSTONE_CATALOG
        fi

        # Add neutron endpoints to service catalog if neutron is enabled
        if is_service_enabled neutron; then
            echo "catalog.RegionOne.network.publicURL = http://%SERVICE_HOST%:$Q_PORT/" >> $KEYSTONE_CATALOG
            echo "catalog.RegionOne.network.adminURL = http://%SERVICE_HOST%:$Q_PORT/" >> $KEYSTONE_CATALOG
            echo "catalog.RegionOne.network.internalURL = http://%SERVICE_HOST%:$Q_PORT/" >> $KEYSTONE_CATALOG
            echo "catalog.RegionOne.network.name = Neutron Service" >> $KEYSTONE_CATALOG
        fi

        sed -e "
            s,%SERVICE_HOST%,$SERVICE_HOST,g;
            s,%S3_SERVICE_PORT%,$S3_SERVICE_PORT,g;
        " -i $KEYSTONE_CATALOG

        # Configure ``keystone.conf`` to use templates
        iniset $KEYSTONE_CONF catalog driver "keystone.catalog.backends.templated.Catalog"
        iniset $KEYSTONE_CONF catalog template_file "$KEYSTONE_CATALOG"
    fi

    # Set up logging
    if [ "$SYSLOG" != "False" ]; then
        iniset $KEYSTONE_CONF DEFAULT use_syslog "True"
    fi

    # Format logging
    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ] && [ "$KEYSTONE_USE_MOD_WSGI" == "False" ]  ; then
        setup_colorized_logging $KEYSTONE_CONF DEFAULT
    fi

    if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
        iniset $KEYSTONE_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
        # Eliminate the %(asctime)s.%(msecs)03d from the log format strings
        iniset $KEYSTONE_CONF DEFAULT logging_context_format_string "%(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s"
        iniset $KEYSTONE_CONF DEFAULT logging_default_format_string "%(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s"
        iniset $KEYSTONE_CONF DEFAULT logging_debug_format_suffix "%(funcName)s %(pathname)s:%(lineno)d"
        iniset $KEYSTONE_CONF DEFAULT logging_exception_prefix "%(process)d TRACE %(name)s %(instance)s"
        _config_keystone_apache_wsgi
    fi

    iniset $KEYSTONE_CONF DEFAULT max_token_size 16384

    iniset $KEYSTONE_CONF DEFAULT admin_workers "$API_WORKERS"
    # Public workers will use the server default, typically number of CPU.

    if [[ -n "$KEYSTONE_TOKEN_HASH_ALGORITHM" ]]; then
        iniset $KEYSTONE_CONF token hash_algorithm "$KEYSTONE_TOKEN_HASH_ALGORITHM"
    fi
}

function configure_keystone_extensions {
    # Add keystone extension into keystone v3 application pipeline
    local extension_value
    local api_v3
    local extension
    local api_v3_extension
    for extension_value in ${KEYSTONE_EXTENSIONS//,/ }; do
        if [[ -z "${extension_value}" ]]; then
            continue
        fi
        api_v3=$(iniget $KEYSTONE_PASTE_INI pipeline:api_v3 pipeline)
        extension=$(echo $api_v3 | sed -ne "/${extension_value}/ p;" )
        if [[ -z $extension ]]; then
            api_v3_extension=$(echo $api_v3 | sed -ne "s/service_v3/${extension_value}_extension service_v3/p;" )
            iniset $KEYSTONE_PASTE_INI pipeline:api_v3 pipeline "$api_v3_extension"
        fi
    done
}

# create_keystone_accounts() - Sets up common required keystone accounts

# Tenant               User       Roles
# ------------------------------------------------------------------
# admin                admin      admin
# service              --         --
# --                   --         service
# --                   --         ResellerAdmin
# --                   --         Member
# demo                 admin      admin
# demo                 demo       Member, anotherrole
# invisible_to_admin   demo       Member

# Migrated from keystone_data.sh
function create_keystone_accounts {

    # admin
    local admin_tenant=$(get_or_create_project "admin")
    local admin_user=$(get_or_create_user "admin" \
        "$ADMIN_PASSWORD" "$admin_tenant")
    local admin_role=$(get_or_create_role "admin")
    get_or_add_user_role $admin_role $admin_user $admin_tenant

    # Create service project/role
    get_or_create_project "$SERVICE_TENANT_NAME"

    # Service role, so service users do not have to be admins
    get_or_create_role service

    # The ResellerAdmin role is used by Nova and Ceilometer so we need to keep it.
    # The admin role in swift allows a user to act as an admin for their tenant,
    # but ResellerAdmin is needed for a user to act as any tenant. The name of this
    # role is also configurable in swift-proxy.conf
    get_or_create_role ResellerAdmin

    # The Member role is used by Horizon and Swift so we need to keep it:
    local member_role=$(get_or_create_role "Member")

    # another_role demonstrates that an arbitrary role may be created and used
    # TODO(sleepsonthefloor): show how this can be used for rbac in the future!
    local another_role=$(get_or_create_role "anotherrole")

    # invisible tenant - admin can't see this one
    local invis_tenant=$(get_or_create_project "invisible_to_admin")

    # demo
    local demo_tenant=$(get_or_create_project "demo")
    local demo_user=$(get_or_create_user "demo" \
        "$ADMIN_PASSWORD" "$demo_tenant" "demo@example.com")

    get_or_add_user_role $member_role $demo_user $demo_tenant
    get_or_add_user_role $admin_role $admin_user $demo_tenant
    get_or_add_user_role $another_role $demo_user $demo_tenant
    get_or_add_user_role $member_role $demo_user $invis_tenant

    # Keystone
    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then

        KEYSTONE_SERVICE=$(get_or_create_service "keystone" \
            "identity" "Keystone Identity Service")
        get_or_create_endpoint $KEYSTONE_SERVICE \
            "$REGION_NAME" \
            "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION" \
            "$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v$IDENTITY_API_VERSION" \
            "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION"
    fi
}

# Configure the API version for the OpenStack projects.
# configure_API_version conf_file version [section]
function configure_API_version {
    local conf_file=$1
    local api_version=$2
    local section=${3:-keystone_authtoken}
    iniset $conf_file $section auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$api_version
}

# Configure the service to use the auth token middleware.
#
# configure_auth_token_middleware conf_file admin_user signing_dir [section]
#
# section defaults to keystone_authtoken, which is where auth_token looks in
# the .conf file. If the paste config file is used (api-paste.ini) then
# provide the section name for the auth_token filter.
function configure_auth_token_middleware {
    local conf_file=$1
    local admin_user=$2
    local signing_dir=$3
    local section=${4:-keystone_authtoken}

    iniset $conf_file $section auth_host $KEYSTONE_AUTH_HOST
    iniset $conf_file $section auth_port $KEYSTONE_AUTH_PORT
    iniset $conf_file $section auth_protocol $KEYSTONE_AUTH_PROTOCOL
    iniset $conf_file $section identity_uri $KEYSTONE_AUTH_URI
    iniset $conf_file $section cafile $SSL_BUNDLE_FILE
    configure_API_version $conf_file $IDENTITY_API_VERSION $section
    iniset $conf_file $section admin_tenant_name $SERVICE_TENANT_NAME
    iniset $conf_file $section admin_user $admin_user
    iniset $conf_file $section admin_password $SERVICE_PASSWORD
    iniset $conf_file $section signing_dir $signing_dir
    if [[ -n "$KEYSTONE_TOKEN_HASH_ALGORITHM" ]]; then
        iniset $conf_file keystone_authtoken hash_algorithms "$KEYSTONE_TOKEN_HASH_ALGORITHM"
    fi
}

# init_keystone() - Initialize databases, etc.
function init_keystone {
    if is_service_enabled ldap; then
        init_ldap
    fi

    # (Re)create keystone database
    recreate_database keystone utf8

    # Initialize keystone database
    $KEYSTONE_DIR/bin/keystone-manage db_sync

    local extension_value
    for extension_value in ${KEYSTONE_EXTENSIONS//,/ }; do
        if [[ -z "${extension_value}" ]]; then
            continue
        fi
        $KEYSTONE_DIR/bin/keystone-manage db_sync --extension "${extension_value}"
    done

    if [[ "$KEYSTONE_TOKEN_FORMAT" != "uuid" ]]; then
        # Set up certificates
        rm -rf $KEYSTONE_CONF_DIR/ssl
        $KEYSTONE_DIR/bin/keystone-manage pki_setup

        # Create cache dir
        sudo mkdir -p $KEYSTONE_AUTH_CACHE_DIR
        sudo chown $STACK_USER $KEYSTONE_AUTH_CACHE_DIR
        rm -f $KEYSTONE_AUTH_CACHE_DIR/*
    fi
}

# install_keystoneclient() - Collect source and prepare
function install_keystoneclient {
    if use_library_from_git "python-keystoneclient"; then
        git_clone_by_name "python-keystoneclient"
        setup_dev_lib "python-keystoneclient"
        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-keystoneclient"]}/tools/,/etc/bash_completion.d/}keystone.bash_completion
    fi
}

# install_keystonemiddleware() - Collect source and prepare
function install_keystonemiddleware {
    if use_library_from_git "keystonemiddleware"; then
        git_clone_by_name "keystonemiddleware"
        setup_dev_lib "keystonemiddleware"
    fi
}

# install_keystone() - Collect source and prepare
function install_keystone {
    # only install ldap if the service has been enabled
    if is_service_enabled ldap; then
        install_ldap
    fi
    if [[ "$KEYSTONE_TOKEN_BACKEND" = "memcache" ]]; then
        # Install memcached and the memcache Python library that keystone uses.
        # Unfortunately the Python library goes by different names in the .deb
        # and .rpm circles.
        install_package memcached
        if is_ubuntu; then
            install_package python-memcache
        else
            install_package python-memcached
        fi
    fi
    git_clone $KEYSTONE_REPO $KEYSTONE_DIR $KEYSTONE_BRANCH
    setup_develop $KEYSTONE_DIR
    if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
        install_apache_wsgi
        if is_ssl_enabled_service "key"; then
            enable_mod_ssl
        fi
    fi
}

# start_keystone() - Start running processes, including screen
function start_keystone {
    # Get right service port for testing
    local service_port=$KEYSTONE_SERVICE_PORT
    local auth_protocol=$KEYSTONE_AUTH_PROTOCOL
    if is_service_enabled tls-proxy; then
        service_port=$KEYSTONE_SERVICE_PORT_INT
        auth_protocol="http"
    fi

    if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
        enable_apache_site keystone
        restart_apache_server
        tail_log key /var/log/$APACHE_NAME/keystone.log
        tail_log key-access /var/log/$APACHE_NAME/keystone_access.log
    else
        local EXTRA_PARAMS=""
        if [ "$ENABLE_DEBUG_LOG_LEVEL" == "True" ]; then
            EXTRA_PARAMS="--debug"
        fi
        # Start Keystone in a screen window
        run_process key "$KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF $EXTRA_PARAMS"
    fi

    echo "Waiting for keystone to start..."
    # Check that the keystone service is running. Even if the tls tunnel
    # should be enabled, make sure the internal port is checked using
    # unencryted traffic at this point.
    if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -k -s $auth_protocol://$KEYSTONE_SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
        die $LINENO "keystone did not start"
    fi

    # Start proxies if enabled
    if is_service_enabled tls-proxy; then
        start_tls_proxy '*' $KEYSTONE_SERVICE_PORT $KEYSTONE_SERVICE_HOST $KEYSTONE_SERVICE_PORT_INT &
        start_tls_proxy '*' $KEYSTONE_AUTH_PORT $KEYSTONE_AUTH_HOST $KEYSTONE_AUTH_PORT_INT &
    fi
}

# stop_keystone() - Stop running processes
function stop_keystone {
    if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
        disable_apache_site keystone
        restart_apache_server
    fi
    # Kill the Keystone screen window
    stop_process key
}

function is_keystone_enabled {
    return is_service_enabled key
}

# Restore xtrace
$XTRACE

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
