#!/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}
# Nova virtual environment
if [[ ${USE_VENV} = True ]]; then
    PROJECT_VENV["nova"]=${NOVA_DIR}.venv
    PLACEMENT_BIN_DIR=${PROJECT_VENV["nova"]}/bin
else
    PLACEMENT_BIN_DIR=$(get_python_exec_prefix)
fi
PLACEMENT_UWSGI=$PLACEMENT_BIN_DIR/nova-placement-api
PLACEMENT_UWSGI_CONF=$PLACEMENT_CONF_DIR/placement-uwsgi.ini

# 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_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 nova-placement-api)
    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 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"
    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

    if [[ "$WSGI_MODE" == "uwsgi" ]]; then
        write_uwsgi_config "$PLACEMENT_UWSGI_CONF" "$PLACEMENT_UWSGI" "/placement"
    else
        _config_placement_apache_wsgi
    fi
}

# 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
        time_start "dbsync"
        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF api_db sync
        time_stop "dbsync"
    fi
    create_placement_accounts
}

# install_placement() - Collect source and prepare
function install_placement {
    install_apache_wsgi
}

# start_placement_api() - Start the API processes ahead of other things
function start_placement_api {
    if [[ "$WSGI_MODE" == "uwsgi" ]]; then
        run_process "placement-api" "$PLACEMENT_BIN_DIR/uwsgi --ini $PLACEMENT_UWSGI_CONF"
    else
        enable_apache_site placement-api
        restart_apache_server
        tail_log placement-api /var/log/$APACHE_NAME/placement-api.log
    fi

    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 {
    if [[ "$WSGI_MODE" == "uwsgi" ]]; then
        stop_process "placement-api"
        remove_uwsgi_config "$PLACEMENT_UWSGI_CONF" "$PLACEMENT_UWSGI"
    else
        disable_apache_site placement-api
        restart_apache_server
    fi
}

# Restore xtrace
$_XTRACE_LIB_PLACEMENT

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