#!/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)
    remove_uwsgi_config "$PLACEMENT_UWSGI_CONF" "$PLACEMENT_UWSGI"
}

# _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 {
    # Use the provided config file path or default to $NOVA_CONF.
    local conf=${1:-$NOVA_CONF}
    iniset $conf placement auth_type "password"
    iniset $conf placement auth_url "$KEYSTONE_SERVICE_URI"
    iniset $conf placement username placement
    iniset $conf placement password "$SERVICE_PASSWORD"
    iniset $conf placement user_domain_name "$SERVICE_DOMAIN_NAME"
    iniset $conf placement project_name "$SERVICE_TENANT_NAME"
    iniset $conf placement project_domain_name "$SERVICE_DOMAIN_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
    # Install the openstackclient placement client plugin for CLI
    # TODO(mriedem): Use pip_install_gr once osc-placement is in g-r.
    pip_install osc-placement
}

# 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 --procname-prefix placement --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"
    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:
