#!/bin/bash
#
# lib/heat
# Install and start **Heat** service

# To enable, add the following to localrc
#
#   ENABLED_SERVICES+=,heat,h-api,h-api-cfn,h-api-cw,h-eng

# Dependencies:
# (none)

# stack.sh
# ---------
# - install_heatclient
# - install_heat
# - configure_heatclient
# - configure_heat
# - init_heat
# - start_heat
# - stop_heat
# - cleanup_heat

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


# Defaults
# --------

# set up default directories
GITDIR["python-heatclient"]=$DEST/python-heatclient

HEAT_DIR=$DEST/heat
HEAT_CFNTOOLS_DIR=$DEST/heat-cfntools
HEAT_TEMPLATES_REPO_DIR=$DEST/heat-templates
OCC_DIR=$DEST/os-collect-config
DIB_UTILS_DIR=$DEST/dib-utils
ORC_DIR=$DEST/os-refresh-config
OAC_DIR=$DEST/os-apply-config

HEAT_PIP_REPO=$DATA_DIR/heat-pip-repo
HEAT_PIP_REPO_PORT=${HEAT_PIP_REPO_PORT:-8899}

HEAT_AUTH_CACHE_DIR=${HEAT_AUTH_CACHE_DIR:-/var/cache/heat}
HEAT_STANDALONE=$(trueorfalse False HEAT_STANDALONE)
HEAT_ENABLE_ADOPT_ABANDON=$(trueorfalse False HEAT_ENABLE_ADOPT_ABANDON)
HEAT_CONF_DIR=/etc/heat
HEAT_CONF=$HEAT_CONF_DIR/heat.conf
HEAT_ENV_DIR=$HEAT_CONF_DIR/environment.d
HEAT_TEMPLATES_DIR=$HEAT_CONF_DIR/templates
HEAT_API_HOST=${HEAT_API_HOST:-$HOST_IP}
HEAT_API_PORT=${HEAT_API_PORT:-8004}


# other default options
if [[ "$HEAT_STANDALONE" = "True" ]]; then
    # for standalone, use defaults which require no service user
    HEAT_STACK_DOMAIN=`trueorfalse False $HEAT_STACK_DOMAIN`
    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-password}
else
    HEAT_STACK_DOMAIN=`trueorfalse True $HEAT_STACK_DOMAIN`
    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-trusts}
fi

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


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

# Test if any Heat services are enabled
# is_heat_enabled
function is_heat_enabled {
    [[ ,${ENABLED_SERVICES} =~ ,"h-" ]] && return 0
    return 1
}

# cleanup_heat() - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_heat {
    sudo rm -rf $HEAT_AUTH_CACHE_DIR
    sudo rm -rf $HEAT_ENV_DIR
    sudo rm -rf $HEAT_TEMPLATES_DIR
    sudo rm -rf $HEAT_CONF_DIR
}

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

    sudo install -d -o $STACK_USER $HEAT_CONF_DIR
    # remove old config files
    rm -f $HEAT_CONF_DIR/heat-*.conf

    HEAT_API_CFN_HOST=${HEAT_API_CFN_HOST:-$HOST_IP}
    HEAT_API_CFN_PORT=${HEAT_API_CFN_PORT:-8000}
    HEAT_ENGINE_HOST=${HEAT_ENGINE_HOST:-$SERVICE_HOST}
    HEAT_ENGINE_PORT=${HEAT_ENGINE_PORT:-8001}
    HEAT_API_CW_HOST=${HEAT_API_CW_HOST:-$HOST_IP}
    HEAT_API_CW_PORT=${HEAT_API_CW_PORT:-8003}
    HEAT_API_PASTE_FILE=$HEAT_CONF_DIR/api-paste.ini
    HEAT_POLICY_FILE=$HEAT_CONF_DIR/policy.json

    cp $HEAT_DIR/etc/heat/api-paste.ini $HEAT_API_PASTE_FILE
    cp $HEAT_DIR/etc/heat/policy.json $HEAT_POLICY_FILE

    # common options
    iniset_rpc_backend heat $HEAT_CONF
    iniset $HEAT_CONF DEFAULT heat_metadata_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT
    iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1/waitcondition
    iniset $HEAT_CONF DEFAULT heat_watch_server_url http://$HEAT_API_CW_HOST:$HEAT_API_CW_PORT
    iniset $HEAT_CONF database connection `database_connection_url heat`
    iniset $HEAT_CONF DEFAULT auth_encryption_key $(generate_hex_string 16)

    iniset $HEAT_CONF DEFAULT region_name_for_services "$REGION_NAME"

    # logging
    iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
    iniset $HEAT_CONF DEFAULT use_syslog $SYSLOG
    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
        # Add color to logging output
        setup_colorized_logging $HEAT_CONF DEFAULT tenant user
    fi

    iniset $HEAT_CONF DEFAULT deferred_auth_method $HEAT_DEFERRED_AUTH

    # NOTE(jamielennox): heat re-uses specific values from the
    # keystone_authtoken middleware group and so currently fails when using the
    # auth plugin setup. This should be fixed in heat.  Heat is also the only
    # service that requires the auth_uri to include a /v2.0. Remove this custom
    # setup when bug #1300246 is resolved.
    iniset $HEAT_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_URI/v2.0
    if [[ "$HEAT_STANDALONE" = "True" ]]; then
        iniset $HEAT_CONF paste_deploy flavor standalone
        iniset $HEAT_CONF clients_heat url "http://$HEAT_API_HOST:$HEAT_API_PORT/v1/%(tenant_id)s"
    else
        iniset $HEAT_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
        iniset $HEAT_CONF keystone_authtoken admin_user heat
        iniset $HEAT_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
        iniset $HEAT_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
        iniset $HEAT_CONF keystone_authtoken cafile $SSL_BUNDLE_FILE
        iniset $HEAT_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR
    fi

    # ec2authtoken
    iniset $HEAT_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_URI/v2.0

    # OpenStack API
    iniset $HEAT_CONF heat_api bind_port $HEAT_API_PORT
    iniset $HEAT_CONF heat_api workers "$API_WORKERS"

    # Cloudformation API
    iniset $HEAT_CONF heat_api_cfn bind_port $HEAT_API_CFN_PORT

    # Cloudwatch API
    iniset $HEAT_CONF heat_api_cloudwatch bind_port $HEAT_API_CW_PORT

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

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

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

    if [[ "$HEAT_ENABLE_ADOPT_ABANDON" = "True" ]]; then
        iniset $HEAT_CONF DEFAULT enable_stack_adopt true
        iniset $HEAT_CONF DEFAULT enable_stack_abandon true
    fi

    sudo install -d -o $STACK_USER $HEAT_ENV_DIR $HEAT_TEMPLATES_DIR

    # copy the default environment
    cp $HEAT_DIR/etc/heat/environment.d/* $HEAT_ENV_DIR/

    # copy the default templates
    cp $HEAT_DIR/etc/heat/templates/* $HEAT_TEMPLATES_DIR/

}

# init_heat() - Initialize database
function init_heat {

    # (re)create heat database
    recreate_database heat

    $HEAT_DIR/bin/heat-manage db_sync
    create_heat_cache_dir
}

# create_heat_cache_dir() - Part of the init_heat() process
function create_heat_cache_dir {
    # Create cache dirs
    sudo install -d -o $STACK_USER $HEAT_AUTH_CACHE_DIR
}

# install_heatclient() - Collect source and prepare
function install_heatclient {
    if use_library_from_git "python-heatclient"; then
        git_clone_by_name "python-heatclient"
        setup_dev_lib "python-heatclient"
        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-heatclient"]}/tools/,/etc/bash_completion.d/}heat.bash_completion
    fi
}

# install_heat() - Collect source and prepare
function install_heat {
    git_clone $HEAT_REPO $HEAT_DIR $HEAT_BRANCH
    setup_develop $HEAT_DIR
}

# install_heat_other() - Collect source and prepare
function install_heat_other {
    git_clone $HEAT_CFNTOOLS_REPO $HEAT_CFNTOOLS_DIR $HEAT_CFNTOOLS_BRANCH
    git_clone $HEAT_TEMPLATES_REPO $HEAT_TEMPLATES_REPO_DIR $HEAT_TEMPLATES_BRANCH
    git_clone $OAC_REPO $OAC_DIR $OAC_BRANCH
    git_clone $OCC_REPO $OCC_DIR $OCC_BRANCH
    git_clone $ORC_REPO $ORC_DIR $ORC_BRANCH
    git_clone $DIB_UTILS_REPO $DIB_UTILS_DIR $DIB_UTILS_BRANCH
}

# start_heat() - Start running processes, including screen
function start_heat {
    run_process h-eng "$HEAT_DIR/bin/heat-engine --config-file=$HEAT_CONF"
    run_process h-api "$HEAT_DIR/bin/heat-api --config-file=$HEAT_CONF"
    run_process h-api-cfn "$HEAT_DIR/bin/heat-api-cfn --config-file=$HEAT_CONF"
    run_process h-api-cw "$HEAT_DIR/bin/heat-api-cloudwatch --config-file=$HEAT_CONF"
}

# stop_heat() - Stop running processes
function stop_heat {
    # Kill the screen windows
    local serv
    for serv in h-eng h-api h-api-cfn h-api-cw; do
        stop_process $serv
    done
}

# create_heat_accounts() - Set up common required heat accounts
function create_heat_accounts {
    if [[ "$HEAT_STANDALONE" != "True" ]]; then

        create_service_user "heat" "admin"

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

            get_or_create_service "heat" "orchestration" "Heat Orchestration Service"
            get_or_create_endpoint "orchestration" \
                "$REGION_NAME" \
                "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
                "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
                "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s"

            get_or_create_service "heat-cfn" "cloudformation" "Heat CloudFormation Service"
            get_or_create_endpoint "cloudformation"  \
                "$REGION_NAME" \
                "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
                "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
                "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1"
        fi

        # heat_stack_user role is for users created by Heat
        get_or_create_role "heat_stack_user"
    fi

    if [[ "$HEAT_STACK_DOMAIN" == "True" ]]; then
        # Note we have to pass token/endpoint here because the current endpoint and
        # version negotiation in OSC means just --os-identity-api-version=3 won't work
        D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KEYSTONE_SERVICE_URI_V3 \
            --os-identity-api-version=3 domain list | grep ' heat ' | get_field 1)

        if [[ -z "$D_ID" ]]; then
            D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KEYSTONE_SERVICE_URI_V3 \
                --os-identity-api-version=3 domain create heat \
                --description "Owns users and projects created by heat" \
                | grep ' id ' | get_field 2)
            iniset $HEAT_CONF DEFAULT stack_user_domain_id ${D_ID}

            openstack --os-token $OS_TOKEN --os-url=$KEYSTONE_SERVICE_URI_V3 \
                --os-identity-api-version=3 user create --password $SERVICE_PASSWORD \
                --domain $D_ID heat_domain_admin \
                --description "Manages users and projects created by heat"
            openstack --os-token $OS_TOKEN --os-url=$KEYSTONE_SERVICE_URI_V3 \
                --os-identity-api-version=3 role add \
                --user heat_domain_admin --domain ${D_ID} admin
            iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
            iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
        fi
    fi
}

# build_heat_pip_mirror() - Build a pip mirror containing heat agent projects
function build_heat_pip_mirror {
    local project_dirs="$OCC_DIR $OAC_DIR $ORC_DIR $HEAT_CFNTOOLS_DIR $DIB_UTILS_DIR"
    local projpath proj package

    rm -rf $HEAT_PIP_REPO
    mkdir -p $HEAT_PIP_REPO

    echo "<html><body>" > $HEAT_PIP_REPO/index.html
    for projpath in $project_dirs; do
        proj=$(basename $projpath)
        mkdir -p $HEAT_PIP_REPO/$proj
        pushd $projpath
        rm -rf dist
        python setup.py sdist
        pushd dist
        package=$(ls *)
        mv $package $HEAT_PIP_REPO/$proj/$package
        popd

        echo "<html><body><a href=\"$package\">$package</a></body></html>" > $HEAT_PIP_REPO/$proj/index.html
        echo "<a href=\"$proj\">$proj</a><br/>" >> $HEAT_PIP_REPO/index.html

        popd
    done

    echo "</body></html>" >> $HEAT_PIP_REPO/index.html

    local heat_pip_repo_apache_conf=$(apache_site_config_for heat_pip_repo)

    sudo cp $FILES/apache-heat-pip-repo.template $heat_pip_repo_apache_conf
    sudo sed -e "
        s|%HEAT_PIP_REPO%|$HEAT_PIP_REPO|g;
        s|%HEAT_PIP_REPO_PORT%|$HEAT_PIP_REPO_PORT|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
    " -i $heat_pip_repo_apache_conf
    enable_apache_site heat_pip_repo
    restart_apache_server
    sudo iptables -I INPUT -d $HOST_IP -p tcp --dport $HEAT_PIP_REPO_PORT -j ACCEPT || true
}

# Restore xtrace
$XTRACE

# Tell emacs to use shell-script-mode
## Local variables:
## mode: shell-script
## End:
