#!/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``
# - ``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
# - bootstrap_keystone
# - create_keystone_accounts
# - stop_keystone
# - cleanup_keystone
# - _cleanup_keystone_apache_wsgi

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

# Defaults
# --------

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

# Keystone virtual environment
if [[ ${USE_VENV} = True ]]; then
    PROJECT_VENV["keystone"]=${KEYSTONE_DIR}.venv
    KEYSTONE_BIN_DIR=${PROJECT_VENV["keystone"]}/bin
else
    KEYSTONE_BIN_DIR=$(get_python_exec_prefix)
fi

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}

# NOTE(sdague): remove in Newton
KEYSTONE_CATALOG_BACKEND="sql"

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

# Select the token persistence backend driver
KEYSTONE_TOKEN_BACKEND=${KEYSTONE_TOKEN_BACKEND:-sql}

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

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

# Select the Role backend driver
KEYSTONE_ROLE_BACKEND=${KEYSTONE_ROLE_BACKEND:-sql}

# Select the Resource backend driver
KEYSTONE_RESOURCE_BACKEND=${KEYSTONE_RESOURCE_BACKEND:-sql}

# Select Keystone's token provider (and format)
# Choose from 'uuid', 'pki', 'pkiz', or 'fernet'
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}

# 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 $(apache_site_config_for keystone)
}

# _config_keystone_apache_wsgi() - Set WSGI config files of Keystone
function _config_keystone_apache_wsgi {
    local keystone_apache_conf
    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
    local venv_path=""

    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
    if [[ ${USE_VENV} = True ]]; then
        venv_path="python-path=${PROJECT_VENV["keystone"]}/lib/$(python_version)/site-packages"
    fi

    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|%SSLENGINE%|$keystone_ssl|g;
        s|%SSLCERTFILE%|$keystone_certfile|g;
        s|%SSLKEYFILE%|$keystone_keyfile|g;
        s|%USER%|$STACK_USER|g;
        s|%VIRTUALENV%|$venv_path|g
        s|%KEYSTONE_BIN%|$KEYSTONE_BIN_DIR|g
    " -i $keystone_apache_conf
}

# configure_keystone() - Set config files, create data dirs, etc
function configure_keystone {
    sudo install -d -o $STACK_USER $KEYSTONE_CONF_DIR

    if [[ "$KEYSTONE_CONF_DIR" != "$KEYSTONE_DIR/etc" ]]; then
        install -m 600 $KEYSTONE_DIR/etc/keystone.conf.sample $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

    if [ "$ENABLE_IDENTITY_V2" == "False" ]; then
        # Only Identity v3 API should be available; then disable v2 pipelines
        inidelete $KEYSTONE_PASTE_INI composite:main \\/v2.0
        inidelete $KEYSTONE_PASTE_INI composite:admin \\/v2.0
    fi

    # 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

    iniset $KEYSTONE_CONF identity driver "$KEYSTONE_IDENTITY_BACKEND"
    iniset $KEYSTONE_CONF assignment driver "$KEYSTONE_ASSIGNMENT_BACKEND"
    iniset $KEYSTONE_CONF role driver "$KEYSTONE_ROLE_BACKEND"
    iniset $KEYSTONE_CONF resource driver "$KEYSTONE_RESOURCE_BACKEND"

    # Enable caching
    iniset $KEYSTONE_CONF cache enabled "True"
    iniset $KEYSTONE_CONF cache backend "oslo_cache.memcache_pool"
    iniset $KEYSTONE_CONF cache memcache_servers $SERVICE_HOST:11211

    # Do not cache the catalog backend due to https://bugs.launchpad.net/keystone/+bug/1537617
    iniset $KEYSTONE_CONF catalog caching "False"

    iniset_rpc_backend keystone $KEYSTONE_CONF

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

        iniset $KEYSTONE_CONF eventlet_server_ssl enable True
        iniset $KEYSTONE_CONF eventlet_server_ssl certfile $KEYSTONE_SSL_CERT
        iniset $KEYSTONE_CONF eventlet_server_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 eventlet_server public_port $KEYSTONE_SERVICE_PORT_INT
        iniset $KEYSTONE_CONF eventlet_server admin_port $KEYSTONE_AUTH_PORT_INT

        iniset $KEYSTONE_CONF DEFAULT public_endpoint $KEYSTONE_SERVICE_URI
        iniset $KEYSTONE_CONF DEFAULT admin_endpoint $KEYSTONE_AUTH_URI
    fi

    if [[ "$KEYSTONE_TOKEN_FORMAT" != "" ]]; then
        iniset $KEYSTONE_CONF token provider $KEYSTONE_TOKEN_FORMAT
    fi

    iniset $KEYSTONE_CONF database connection `database_connection_url keystone`

    iniset $KEYSTONE_CONF token driver "$KEYSTONE_TOKEN_BACKEND"

    # 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
        iniset $KEYSTONE_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s"
        iniset $KEYSTONE_CONF DEFAULT logging_default_format_string "%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s"
        iniset $KEYSTONE_CONF DEFAULT logging_debug_format_suffix "%(asctime)s.%(msecs)03d %(funcName)s %(pathname)s:%(lineno)d"
        iniset $KEYSTONE_CONF DEFAULT logging_exception_prefix "%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s"
        _config_keystone_apache_wsgi
    else
        iniset $KEYSTONE_CONF eventlet_server admin_bind_host "$KEYSTONE_ADMIN_BIND_HOST"
        iniset $KEYSTONE_CONF eventlet_server admin_workers "$API_WORKERS"
        # Public workers will use the server default, typically number of CPU.
    fi

    iniset $KEYSTONE_CONF DEFAULT max_token_size 16384

    iniset $KEYSTONE_CONF fernet_tokens key_repository "$KEYSTONE_CONF_DIR/fernet-keys/"
}

# 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
# alt_demo             admin      admin
# alt_demo             alt_demo   Member, anotherrole
# invisible_to_admin   demo       Member

# Group                Users      Roles                 Tenant
# ------------------------------------------------------------------
# admins               admin      admin                 admin
# nonadmins            demo       Member, anotherrole   demo


# Migrated from keystone_data.sh
function create_keystone_accounts {

    # The keystone bootstrapping process (performed via keystone-manage bootstrap)
    # creates an admin user, admin role and admin project. As a sanity check
    # we exercise the CLI to retrieve the IDs for these values.
    local admin_tenant
    admin_tenant=$(openstack project show "admin" -f value -c id)
    local admin_user
    admin_user=$(openstack user show "admin" -f value -c id)
    local admin_role
    admin_role=$(openstack role show "admin" -f value -c id)

    get_or_add_user_domain_role $admin_role $admin_user default

    # Create service project/role
    get_or_create_project "$SERVICE_TENANT_NAME" default

    # 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
    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
    another_role=$(get_or_create_role "anotherrole")

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

    # demo
    local demo_tenant
    demo_tenant=$(get_or_create_project "demo" default)
    local demo_user
    demo_user=$(get_or_create_user "demo" \
        "$ADMIN_PASSWORD" "default" "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

    # alt_demo
    local alt_demo_tenant
    alt_demo_tenant=$(get_or_create_project "alt_demo" default)
    local alt_demo_user
    alt_demo_user=$(get_or_create_user "alt_demo" \
        "$ADMIN_PASSWORD" "default" "alt_demo@example.com")

    get_or_add_user_project_role $member_role $alt_demo_user $alt_demo_tenant
    get_or_add_user_project_role $admin_role $admin_user $alt_demo_tenant
    get_or_add_user_project_role $another_role $alt_demo_user $alt_demo_tenant

    # groups
    local admin_group
    admin_group=$(get_or_create_group "admins" \
        "default" "openstack admin group")
    local non_admin_group
    non_admin_group=$(get_or_create_group "nonadmins" \
        "default" "non-admin group")

    get_or_add_group_project_role $member_role $non_admin_group $demo_tenant
    get_or_add_group_project_role $another_role $non_admin_group $demo_tenant
    get_or_add_group_project_role $member_role $non_admin_group $alt_demo_tenant
    get_or_add_group_project_role $another_role $non_admin_group $alt_demo_tenant
    get_or_add_group_project_role $admin_role $admin_group $admin_tenant
}

# 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
    user=$(get_or_create_user "$1" "$SERVICE_PASSWORD" default)
    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_type 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
    iniset $conf_file $section memcache_servers $SERVICE_HOST:11211
}

# 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_BIN_DIR/keystone-manage db_sync

    if [[ "$KEYSTONE_TOKEN_FORMAT" == "pki" || "$KEYSTONE_TOKEN_FORMAT" == "pkiz" ]]; then
        # Set up certificates
        rm -rf $KEYSTONE_CONF_DIR/ssl
        $KEYSTONE_BIN_DIR/keystone-manage pki_setup
    fi
    if [[ "$KEYSTONE_TOKEN_FORMAT" == "fernet" ]]; then
        rm -rf "$KEYSTONE_CONF_DIR/fernet-keys/"
        $KEYSTONE_BIN_DIR/keystone-manage fernet_setup
    fi
}

# install_keystoneauth() - Collect source and prepare
function install_keystoneauth {
    if use_library_from_git "keystoneauth"; then
        git_clone_by_name "keystoneauth"
        setup_dev_lib "keystoneauth"
    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 {
    # install_keystonemiddleware() is called when keystonemiddleware is needed
    # to provide an opportunity to install it from the source repo
    if use_library_from_git "keystonemiddleware"; then
        git_clone_by_name "keystonemiddleware"
        setup_dev_lib "keystonemiddleware"
    else
        # When not installing from repo, keystonemiddleware is still needed...
        pip_install_gr keystonemiddleware
    fi
    # Install the memcache library so keystonemiddleware can cache tokens in a
    # shared location.
    pip_install_gr python-memcached
}

# 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

    git_clone $KEYSTONE_REPO $KEYSTONE_DIR $KEYSTONE_BRANCH
    setup_develop $KEYSTONE_DIR

    if is_service_enabled ldap; then
        setup_develop $KEYSTONE_DIR ldap
    fi

    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_BIN_DIR/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

    # (re)start memcached to make sure we have a clean memcache.
    restart_service memcached
}

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

# bootstrap_keystone() - Initialize user, role and project
# This function uses the following GLOBAL variables:
# - ``KEYSTONE_BIN_DIR``
# - ``ADMIN_PASSWORD``
# - ``IDENTITY_API_VERSION``
# - ``KEYSTONE_AUTH_URI``
# - ``REGION_NAME``
# - ``KEYSTONE_SERVICE_PROTOCOL``
# - ``KEYSTONE_SERVICE_HOST``
# - ``KEYSTONE_SERVICE_PORT``
function bootstrap_keystone {

    # Initialize keystone, this will create an 'admin' user, 'admin' project,
    # 'admin' role, and assign the user the role on the project. These resources
    # are created only if they do not already exist.
    $KEYSTONE_BIN_DIR/keystone-manage bootstrap --bootstrap-password $ADMIN_PASSWORD

    # Create the keystone service and endpoints. To do this with the new
    # bootstrapping process, we need to get a token and use that token to
    # interact with the new APIs. The token will only be used to create services
    # and endpoints, thus creating a minimal service catalog.
    # They are unset immediately after.
    # TODO(stevemar): OpenStackClient and KeystoneClient do not have support to
    # handle interactions that not return service catalogs. Eventually remove
    # this section when the support is in place. Use token based auth for now.
    local token_id
    token_id=$(openstack token issue -c id -f value \
        --os-username admin --os-project-name admin \
        --os-user-domain-id default --os-project-domain-id default \
        --os-identity-api-version 3 --os-auth-url $KEYSTONE_AUTH_URI \
        --os-password $ADMIN_PASSWORD)

    export OS_TOKEN=$token_id
    export OS_URL=$KEYSTONE_AUTH_URI/v3
    export OS_IDENTITY_API_VERSION=3

    get_or_create_service "keystone" "identity" "Keystone Identity Service"
    get_or_create_endpoint \
        "identity" \
        "$REGION_NAME" \
        "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION" \
        "$KEYSTONE_AUTH_URI/v$IDENTITY_API_VERSION" \
        "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION"

    unset OS_TOKEN OS_URL OS_IDENTITY_API_VERSION
}

# Restore xtrace
$_XTRACE_KEYSTONE

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