#!/bin/bash
#
# lib/sahara

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

# ``stack.sh`` calls the entry points in this order:
#
# install_sahara
# install_python_saharaclient
# configure_sahara
# sahara_register_images
# start_sahara
# stop_sahara
# cleanup_sahara

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


# Defaults
# --------

# Set up default repos

# Set up default directories
GITDIR["python-saharaclient"]=$DEST/python-saharaclient
SAHARA_DIR=$DEST/sahara

SAHARA_CONF_DIR=${SAHARA_CONF_DIR:-/etc/sahara}
SAHARA_CONF_FILE=${SAHARA_CONF_DIR}/sahara.conf

SAHARA_SERVICE_HOST=${SAHARA_SERVICE_HOST:-$SERVICE_HOST}
SAHARA_SERVICE_PORT=${SAHARA_SERVICE_PORT:-8386}
SAHARA_SERVICE_PROTOCOL=${SAHARA_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}

SAHARA_AUTH_CACHE_DIR=${SAHARA_AUTH_CACHE_DIR:-/var/cache/sahara}

SAHARA_ENABLED_PLUGINS=${SAHARA_ENABLED_PLUGINS:-vanilla,hdp,cdh,spark,fake}

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

# Tell Tempest this project is present
TEMPEST_SERVICES+=,sahara

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

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

    create_service_user "sahara"

    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then

        # TODO: remove "data_processing" service when #1356053 will be fixed
        local sahara_service_old=$(openstack service create \
            "data_processing" \
            --name "sahara" \
            --description "Sahara Data Processing" \
            -f value -c id
        )
        local sahara_service_new=$(openstack service create \
            "data-processing" \
            --name "sahara" \
            --description "Sahara Data Processing" \
            -f value -c id
        )
        get_or_create_endpoint $sahara_service_old \
            "$REGION_NAME" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s"
        get_or_create_endpoint $sahara_service_new \
            "$REGION_NAME" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s" \
            "$SAHARA_SERVICE_PROTOCOL://$SAHARA_SERVICE_HOST:$SAHARA_SERVICE_PORT/v1.1/\$(tenant_id)s"
    fi
}

# cleanup_sahara() - Remove residual data files, anything left over from
# previous runs that would need to clean up.
function cleanup_sahara {

    # Cleanup auth cache dir
    sudo rm -rf $SAHARA_AUTH_CACHE_DIR
}

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

    if [[ -f $SAHARA_DIR/etc/sahara/policy.json ]]; then
        cp -p $SAHARA_DIR/etc/sahara/policy.json $SAHARA_CONF_DIR
    fi

    # Create auth cache dir
    sudo install -d -o $STACK_USER -m 700 $SAHARA_AUTH_CACHE_DIR
    rm -rf $SAHARA_AUTH_CACHE_DIR/*

    configure_auth_token_middleware $SAHARA_CONF_FILE sahara $SAHARA_AUTH_CACHE_DIR

    iniset_rpc_backend sahara $SAHARA_CONF_FILE DEFAULT

    # Set configuration to send notifications

    if is_service_enabled ceilometer; then
        iniset $SAHARA_CONF_FILE DEFAULT enable_notifications "true"
        iniset $SAHARA_CONF_FILE DEFAULT notification_driver "messaging"
    fi

    iniset $SAHARA_CONF_FILE DEFAULT verbose True
    iniset $SAHARA_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL

    iniset $SAHARA_CONF_FILE DEFAULT plugins $SAHARA_ENABLED_PLUGINS

    iniset $SAHARA_CONF_FILE database connection `database_connection_url sahara`

    if is_service_enabled neutron; then
        iniset $SAHARA_CONF_FILE DEFAULT use_neutron true

        if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then
            iniset $SAHARA_CONF_FILE neutron ca_file $SSL_BUNDLE_FILE
        fi
    else
        iniset $SAHARA_CONF_FILE DEFAULT use_neutron false
    fi

    if is_service_enabled heat; then
        iniset $SAHARA_CONF_FILE DEFAULT infrastructure_engine heat

        if is_ssl_enabled_service "heat" || is_service_enabled tls-proxy; then
            iniset $SAHARA_CONF_FILE heat ca_file $SSL_BUNDLE_FILE
        fi
    else
        iniset $SAHARA_CONF_FILE DEFAULT infrastructure_engine direct
    fi

    if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
        iniset $SAHARA_CONF_FILE cinder ca_file $SSL_BUNDLE_FILE
    fi

    if is_ssl_enabled_service "nova" || is_service_enabled tls-proxy; then
        iniset $SAHARA_CONF_FILE nova ca_file $SSL_BUNDLE_FILE
    fi

    if is_ssl_enabled_service "swift" || is_service_enabled tls-proxy; then
        iniset $SAHARA_CONF_FILE swift ca_file $SSL_BUNDLE_FILE
    fi

    if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
        iniset $SAHARA_CONF_FILE keystone ca_file $SSL_BUNDLE_FILE
    fi

    iniset $SAHARA_CONF_FILE DEFAULT use_syslog $SYSLOG

    # Format logging
    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
        setup_colorized_logging $SAHARA_CONF_FILE DEFAULT
    fi

    recreate_database sahara
    $SAHARA_BIN_DIR/sahara-db-manage --config-file $SAHARA_CONF_FILE upgrade head
}

# install_sahara() - Collect source and prepare
function install_sahara {
    git_clone $SAHARA_REPO $SAHARA_DIR $SAHARA_BRANCH
    setup_develop $SAHARA_DIR
}

# install_python_saharaclient() - Collect source and prepare
function install_python_saharaclient {
    if use_library_from_git "python-saharaclient"; then
        git_clone_by_name "python-saharaclient"
        setup_dev_lib "python-saharaclient"
    fi
}

# sahara_register_images() - Registers images in sahara image registry
function sahara_register_images {
    if is_service_enabled heat && [[ ! -z "$HEAT_CFN_IMAGE_URL" ]]; then
        # Register heat image for Fake plugin
        local fake_plugin_properties="--property _sahara_tag_0.1=True"
        fake_plugin_properties+=" --property _sahara_tag_fake=True"
        fake_plugin_properties+=" --property _sahara_username=fedora"
        openstack --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT image set $(basename "$HEAT_CFN_IMAGE_URL" ".qcow2") $fake_plugin_properties
    fi
}

# start_sahara() - Start running processes, including screen
function start_sahara {
    run_process sahara "$SAHARA_BIN_DIR/sahara-all --config-file $SAHARA_CONF_FILE"
    run_process sahara-api "$SAHARA_BIN_DIR/sahara-api --config-file $SAHARA_CONF_FILE"
    run_process sahara-eng "$SAHARA_BIN_DIR/sahara-engine --config-file $SAHARA_CONF_FILE"
}

# stop_sahara() - Stop running processes
function stop_sahara {
    # Kill the Sahara screen windows
    stop_process sahara
    stop_process sahara-api
    stop_process sahara-eng
}


# Restore xtrace
$XTRACE

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