# 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_DIR}/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_FILE

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

    iniset $SAVANNA_CONF_FILE database connection `database_connection_url savanna`

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

    iniset $SAVANNA_CONF_FILE DEFAULT use_syslog $SYSLOG

    recreate_database savanna utf8
    $SAVANNA_BIN_DIR/savanna-db-manage --config-file $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_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:
