#!/bin/bash
#
# lib/placement
# Functions to control the configuration and operation of the **Placement** service
#

# 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_DIR=$DEST/placement
PLACEMENT_CONF_DIR=/etc/placement
PLACEMENT_CONF=$PLACEMENT_CONF_DIR/placement.conf
PLACEMENT_AUTH_STRATEGY=${PLACEMENT_AUTH_STRATEGY:-keystone}
# Placement virtual environment
if [[ ${USE_VENV} = True ]]; then
    PROJECT_VENV["placement"]=${PLACEMENT_DIR}.venv
    PLACEMENT_BIN_DIR=${PROJECT_VENV["placement"]}/bin
else
    PLACEMENT_BIN_DIR=$(get_python_exec_prefix)
fi
PLACEMENT_UWSGI=$PLACEMENT_BIN_DIR/placement-api
PLACEMENT_UWSGI_CONF=$PLACEMENT_CONF_DIR/placement-uwsgi.ini

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 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 placement_bin_dir=""
    placement_bin_dir=$(get_python_exec_prefix)
    placement_api_apache_conf=$(apache_site_config_for placement-api)

    if [[ ${USE_VENV} = True ]]; then
        venv_path="python-path=${PROJECT_VENV["placement"]}/lib/$(python_version)/site-packages"
        placement_bin_dir=${PROJECT_VENV["placement"]}/bin
    fi

    sudo cp $FILES/apache-placement-api.template $placement_api_apache_conf
    sudo sed -e "
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%PUBLICWSGI%|$placement_bin_dir/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
}

# create_placement_conf() - Write config
function create_placement_conf {
    rm -f $PLACEMENT_CONF
    iniset $PLACEMENT_CONF placement_database connection `database_connection_url placement`
    iniset $PLACEMENT_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
    iniset $PLACEMENT_CONF api auth_strategy $PLACEMENT_AUTH_STRATEGY
    configure_keystone_authtoken_middleware $PLACEMENT_CONF placement
    setup_logging $PLACEMENT_CONF
}

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

    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
function init_placement {
    recreate_database placement
    $PLACEMENT_BIN_DIR/placement-manage db sync
    create_placement_accounts
}

# install_placement() - Collect source and prepare
function install_placement {
    install_apache_wsgi
    # Install the openstackclient placement client plugin for CLI
    pip_install_gr osc-placement
    git_clone $PLACEMENT_REPO $PLACEMENT_DIR $PLACEMENT_BRANCH
    setup_develop $PLACEMENT_DIR
}

# start_placement_api() - Start the API processes ahead of other things
function start_placement_api {
    if [[ "$WSGI_MODE" == "uwsgi" ]]; then
        run_process "placement-api" "$(which uwsgi) --procname-prefix placement --ini $PLACEMENT_UWSGI_CONF"
    else
        enable_apache_site placement-api
        restart_apache_server
    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:
