#!/bin/bash
#
# lib/placement
# Functions to control the configuration and operation of the **Placement** service
#
# Currently the placement service is embedded in nova. Eventually we
# expect this to change so this file is started as a separate entity
# despite making use of some *NOVA* variables and files.

# Dependencies:
#
# - ``functions`` file
# - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
# - ``FILES``

# ``stack.sh`` calls the entry points in this order:
#
# - install_placement
# - cleanup_placement
# - configure_placement
# - init_placement
# - start_placement
# - stop_placement

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

# Defaults
# --------

PLACEMENT_CONF_DIR=/etc/nova
PLACEMENT_CONF=$PLACEMENT_CONF_DIR/nova.conf
PLACEMENT_AUTH_STRATEGY=${PLACEMENT_AUTH_STRATEGY:-placement}


# The placement service can optionally use a separate database
# connection. Set PLACEMENT_DB_ENABLED to True to use it.
# NOTE(cdent): This functionality depends on some code that is not
# yet merged in nova but is coming soon.
PLACEMENT_DB_ENABLED=$(trueorfalse False PLACEMENT_DB_ENABLED)

if is_ssl_enabled_service "placement-api" || is_service_enabled tls-proxy; then
    PLACEMENT_SERVICE_PROTOCOL="https"
fi

# Public facing bits
PLACEMENT_SERVICE_PROTOCOL=${PLACEMENT_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
PLACEMENT_SERVICE_HOST=${PLACEMENT_SERVICE_HOST:-$SERVICE_HOST}

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

# Test if any placement services are enabled
# is_placement_enabled
function is_placement_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"placement-api" ]] && return 0
    return 1
}

# cleanup_placement() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_placement {
    sudo rm -f $(apache_site_config_for placement-api)
}

# _config_placement_apache_wsgi() - Set WSGI config files
function _config_placement_apache_wsgi {
    local placement_api_apache_conf
    local venv_path=""
    local nova_bin_dir=""
    nova_bin_dir=$(get_python_exec_prefix)
    placement_api_apache_conf=$(apache_site_config_for placement-api)

    # reuse nova's cert if a cert is being used
    if is_ssl_enabled_service "placement-api"; then
        placement_ssl="SSLEngine On"
        placement_certfile="SSLCertificateFile $NOVA_SSL_CERT"
        placement_keyfile="SSLCertificateKeyFile $NOVA_SSL_KEY"
    fi
    # reuse nova's venv if there is one as placement code lives
    # there
    if [[ ${USE_VENV} = True ]]; then
        venv_path="python-path=${PROJECT_VENV["nova"]}/lib/$(python_version)/site-packages"
        nova_bin_dir=${PROJECT_VENV["nova"]}/bin
    fi

    sudo cp $FILES/apache-placement-api.template $placement_api_apache_conf
    sudo sed -e "
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%PUBLICWSGI%|$nova_bin_dir/nova-placement-api|g;
        s|%SSLENGINE%|$placement_ssl|g;
        s|%SSLCERTFILE%|$placement_certfile|g;
        s|%SSLKEYFILE%|$placement_keyfile|g;
        s|%USER%|$STACK_USER|g;
        s|%VIRTUALENV%|$venv_path|g
        s|%APIWORKERS%|$API_WORKERS|g
    " -i $placement_api_apache_conf
}

function configure_placement_nova_compute {
    iniset $NOVA_CONF placement auth_type "password"
    iniset $NOVA_CONF placement auth_url "$KEYSTONE_SERVICE_URI/v3"
    iniset $NOVA_CONF placement username placement
    iniset $NOVA_CONF placement password "$SERVICE_PASSWORD"
    iniset $NOVA_CONF placement user_domain_name "$SERVICE_DOMAIN_NAME"
    iniset $NOVA_CONF placement project_name "$SERVICE_TENANT_NAME"
    iniset $NOVA_CONF placement project_domain_name "$SERVICE_DOMAIN_NAME"
    iniset $NOVA_CONF placement os_region_name "$REGION_NAME"
    # TODO(cdent): auth_strategy, which is common to see in these
    # blocks is not currently used here. For the time being the
    # placement api uses the auth_strategy configuration setting
    # established by the nova api. This avoids, for the time, being,
    # creating redundant configuration items that are just used for
    # testing.
}

# configure_placement() - Set config files, create data dirs, etc
function configure_placement {
    if [ "$PLACEMENT_DB_ENABLED" != False ]; then
        iniset $PLACEMENT_CONF placement_database connection `database_connection_url placement`
    fi
    _config_placement_apache_wsgi
}

# create_placement_accounts() - Set up required placement accounts
# and service and endpoints.
function create_placement_accounts {
    create_service_user "placement" "admin"
    local placement_api_url="$PLACEMENT_SERVICE_PROTOCOL://$PLACEMENT_SERVICE_HOST/placement"
    get_or_create_service "placement" "placement" "Placement Service"
    get_or_create_endpoint \
        "placement" \
        "$REGION_NAME" \
        "$placement_api_url"
}

# init_placement() - Create service user and endpoints
# If PLACEMENT_DB_ENABLED is true, create the separate placement db
# using, for now, the api_db migrations.
function init_placement {
    if [ "$PLACEMENT_DB_ENABLED" != False ]; then
        recreate_database placement
        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF api_db sync
    fi
    create_placement_accounts
}

# install_placement() - Collect source and prepare
function install_placement {
    install_apache_wsgi
    if is_ssl_enabled_service "placement-api"; then
        enable_mod_ssl
    fi
}

# start_placement_api() - Start the API processes ahead of other things
function start_placement_api {
    enable_apache_site placement-api
    restart_apache_server
    tail_log placement-api /var/log/$APACHE_NAME/placement-api.log

    echo "Waiting for placement-api to start..."
    if ! wait_for_service $SERVICE_TIMEOUT $PLACEMENT_SERVICE_PROTOCOL://$PLACEMENT_SERVICE_HOST/placement; then
        die $LINENO "placement-api did not start"
    fi
}

function start_placement {
    start_placement_api
}

# stop_placement() - Disable the api service and stop it.
function stop_placement {
    disable_apache_site placement-api
    restart_apache_server
}

# Restore xtrace
$_XTRACE_LIB_PLACEMENT

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