#!/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

    # 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"
        iniset_rpc_backend sahara $SAHARA_CONF_FILE
    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"
}

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


# Restore xtrace
$XTRACE

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