#!/bin/bash
#
# 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=${KEYSTONE_TOKEN_FORMAT:-}
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}

# V3 URIs
KEYSTONE_AUTH_URI_V3=$KEYSTONE_AUTH_URI/v3
KEYSTONE_SERVICE_URI_V3=$KEYSTONE_SERVICE_URI/v3


# Functions
# ---------

# Test if Keystone is enabled
# is_keystone_enabled
function is_keystone_enabled {
    [[ ,${ENABLED_SERVICES}, =~ ,"key", ]] && return 0
    return 1
}

# 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/*
    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

    iniset_rpc_backend keystone $KEYSTONE_CONF DEFAULT

    # 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

    iniset $KEYSTONE_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL

    if [ "$KEYSTONE_USE_MOD_WSGI" == "True" ]; then
        # 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.
}

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")
    local admin_role=$(get_or_create_role "admin")
    get_or_add_user_project_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@example.com")

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

    get_or_create_group "developers" "default" "openstack developers"
    get_or_create_group "testers" "default"

    # 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
}

# Create a user that is capable of verifying keystone tokens for use with auth_token middleware.
#
# create_service_user <name> [role]
#
# The role defaults to the service role. It is allowed to be provided as optional as historically
# a lot of projects have configured themselves with the admin or other role here if they are
# using this user for other purposes beyond simply auth_token middleware.
function create_service_user {
    local role=${2:-service}

    local user=$(get_or_create_user "$1" "$SERVICE_PASSWORD")
    get_or_add_user_project_role "$role" "$user" "$SERVICE_TENANT_NAME"
}

# 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_plugin password
    iniset $conf_file $section auth_url $KEYSTONE_AUTH_URI
    iniset $conf_file $section username $admin_user
    iniset $conf_file $section password $SERVICE_PASSWORD
    iniset $conf_file $section user_domain_id default
    iniset $conf_file $section project_name $SERVICE_TENANT_NAME
    iniset $conf_file $section project_domain_id default

    iniset $conf_file $section auth_uri $KEYSTONE_SERVICE_URI
    iniset $conf_file $section cafile $SSL_BUNDLE_FILE
    iniset $conf_file $section signing_dir $signing_dir
}

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

    # (Re)create keystone database
    recreate_database keystone

    # 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
        # Start Keystone in a screen window
        run_process key "$KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF"
    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 ! wait_for_service $SERVICE_TIMEOUT $auth_protocol://$KEYSTONE_SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/; 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
}


# Restore xtrace
$XTRACE

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