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

    # Configure rabbitmq credentials
    if is_service_enabled rabbit; then
        iniset $KEYSTONE_CONF DEFAULT rabbit_userid $RABBIT_USERID
        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

    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:
