#!/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_CACHE_DIR=${PLACEMENT_AUTH_CACHE_DIR:-/var/cache/placement}
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"
    sudo rm -f $PLACEMENT_AUTH_CACHE_DIR/*
}

# _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_auth_token_middleware $PLACEMENT_CONF placement $PLACEMENT_AUTH_CACHE_DIR
    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"
}

# create_placement_cache_dir() - Create directories for keystone cache
function create_placement_cache_dir {
    # Create cache dir
    sudo install -d -o $STACK_USER $PLACEMENT_AUTH_CACHE_DIR
    rm -f $PLACEMENT_AUTH_CACHE_DIR/*
}

# init_placement() - Create service user and endpoints
function init_placement {
    recreate_database placement
    $PLACEMENT_BIN_DIR/placement-manage db sync
    create_placement_accounts
    create_placement_cache_dir
}

# 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" "$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:
