# lib/savanna

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

# ``stack.sh`` calls the entry points in this order:
#
# install_savanna
# configure_savanna
# start_savanna
# stop_savanna

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


# Defaults
# --------

# Set up default repos
SAVANNA_REPO=${SAVANNA_REPO:-${GIT_BASE}/openstack/savanna.git}
SAVANNA_BRANCH=${SAVANNA_BRANCH:-master}

# Set up default directories
SAVANNA_DIR=$DEST/savanna
SAVANNA_CONF_DIR=${SAVANNA_CONF_DIR:-/etc/savanna}
SAVANNA_CONF_FILE=savanna.conf
SAVANNA_DEBUG=${SAVANNA_DEBUG:-True}

SAVANNA_SERVICE_HOST=${SAVANNA_SERVICE_HOST:-$SERVICE_HOST}
SAVANNA_SERVICE_PORT=${SAVANNA_SERVICE_PORT:-8386}
SAVANNA_SERVICE_PROTOCOL=${SAVANNA_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}

# Support entry points installation of console scripts
if [[ -d $SAVANNA_DIR/bin ]]; then
    SAVANNA_BIN_DIR=$SAVANNA_DIR/bin
else
    SAVANNA_BIN_DIR=$(get_python_exec_prefix)
fi

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

# create_savanna_accounts() - Set up common required savanna accounts
#
# Tenant      User       Roles
# ------------------------------
# service     savanna    admin
function create_savanna_accounts() {

    SERVICE_TENANT=$(keystone tenant-list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
    ADMIN_ROLE=$(keystone role-list | awk "/ admin / { print \$2 }")

    SAVANNA_USER=$(keystone user-create \
        --name=savanna \
        --pass="$SERVICE_PASSWORD" \
        --tenant-id $SERVICE_TENANT \
        --email=savanna@example.com \
        | grep " id " | get_field 2)
    keystone user-role-add \
        --tenant-id $SERVICE_TENANT \
        --user-id $SAVANNA_USER \
        --role-id $ADMIN_ROLE

    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
        SAVANNA_SERVICE=$(keystone service-create \
            --name=savanna \
            --type=data_processing \
            --description="Savanna Data Processing" \
            | grep " id " | get_field 2)
        keystone endpoint-create \
            --region RegionOne \
            --service_id $SAVANNA_SERVICE \
            --publicurl "$SAVANNA_SERVICE_PROTOCOL://$SAVANNA_SERVICE_HOST:$SAVANNA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
            --adminurl "$SAVANNA_SERVICE_PROTOCOL://$SAVANNA_SERVICE_HOST:$SAVANNA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
            --internalurl "$SAVANNA_SERVICE_PROTOCOL://$SAVANNA_SERVICE_HOST:$SAVANNA_SERVICE_PORT/v1.1/\$(tenant_id)s"
    fi
}

# configure_savanna() - Set config files, create data dirs, etc
function configure_savanna() {

    if [[ ! -d $SAVANNA_CONF_DIR ]]; then
        sudo mkdir -p $SAVANNA_CONF_DIR
    fi
    sudo chown $STACK_USER $SAVANNA_CONF_DIR

    # Copy over savanna configuration file and configure common parameters.
    cp $SAVANNA_DIR/etc/savanna/savanna.conf.sample $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE

    iniset $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE DEFAULT os_admin_password $SERVICE_PASSWORD
    iniset $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE DEFAULT os_admin_username savanna
    iniset $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE DEFAULT os_admin_tenant_name $SERVICE_TENANT_NAME
    iniset $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE DEFAULT debug $SAVANNA_DEBUG

    iniset $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE database connection `database_connection_url savanna`

    if is_service_enabled neutron; then
        iniset $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE DEFAULT use_neutron true
        iniset $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE DEFAULT use_floating_ips true
    fi

    iniset $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE DEFAULT use_syslog $SYSLOG

    recreate_database savanna utf8
    $SAVANNA_BIN_DIR/savanna-db-manage --config-file $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE upgrade head
}

# install_savanna() - Collect source and prepare
function install_savanna() {
    git_clone $SAVANNA_REPO $SAVANNA_DIR $SAVANNA_BRANCH
    setup_develop $SAVANNA_DIR
}

# start_savanna() - Start running processes, including screen
function start_savanna() {
    screen_it savanna "cd $SAVANNA_DIR && $SAVANNA_BIN_DIR/savanna-api --config-file $SAVANNA_CONF_DIR/$SAVANNA_CONF_FILE"
}

# stop_savanna() - Stop running processes
function stop_savanna() {
    # Kill the Savanna screen windows
    screen -S $SCREEN_NAME -p savanna -X kill
}


# Restore xtrace
$XTRACE

# Local variables:
# mode: shell-script
# End:
