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

# Toggle for deploying Heat-API under HTTPD + mod_wsgi
HEAT_USE_MOD_WSGI=${HEAT_USE_MOD_WSGI:-False}

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}

# Support entry points installation of console scripts
HEAT_BIN_DIR=$(get_python_exec_prefix)

# 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

# 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" ] && [ "$HEAT_USE_MOD_WSGI" == "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

    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        _config_heat_apache_wsgi
    fi

    # 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_BIN_DIR/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
    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        install_apache_wsgi
    fi
}

# 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_BIN_DIR/heat-engine --config-file=$HEAT_CONF"

    # If the site is not enabled then we are in a grenade scenario
    local enabled_site_file
    enabled_site_file=$(apache_site_config_for heat-api)
    if [ -f ${enabled_site_file} ] && [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        enable_apache_site heat-api
        enable_apache_site heat-api-cfn
        enable_apache_site heat-api-cloudwatch
        restart_apache_server
        tail_log heat-api /var/log/$APACHE_NAME/heat-api.log
        tail_log heat-api-cfn /var/log/$APACHE_NAME/heat-api-cfn.log
        tail_log heat-api-cloudwatch /var/log/$APACHE_NAME/heat-api-cloudwatch.log
    else
        run_process h-api "$HEAT_BIN_DIR/heat-api --config-file=$HEAT_CONF"
        run_process h-api-cfn "$HEAT_BIN_DIR/heat-api-cfn --config-file=$HEAT_CONF"
        run_process h-api-cw "$HEAT_BIN_DIR/heat-api-cloudwatch --config-file=$HEAT_CONF"
    fi
}

# stop_heat() - Stop running processes
function stop_heat {
    # Kill the screen windows
    stop_process h-eng

    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
        disable_apache_site heat-api
        disable_apache_site heat-api-cfn
        disable_apache_site heat-api-cloudwatch
        restart_apache_server
    else
        local serv
        for serv in h-api h-api-cfn h-api-cw; do
            stop_process $serv
        done
    fi

}

# _cleanup_heat_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
function _cleanup_heat_apache_wsgi {
    sudo rm -f $(apache_site_config_for heat-api)
    sudo rm -f $(apache_site_config_for heat-api-cfn)
    sudo rm -f $(apache_site_config_for heat-api-cloudwatch)
}

# _config_heat_apache_wsgi() - Set WSGI config files of Heat
function _config_heat_apache_wsgi {

    local heat_apache_conf
    heat_apache_conf=$(apache_site_config_for heat-api)
    local heat_cfn_apache_conf
    heat_cfn_apache_conf=$(apache_site_config_for heat-api-cfn)
    local heat_cloudwatch_apache_conf
    heat_cloudwatch_apache_conf=$(apache_site_config_for heat-api-cloudwatch)
    local heat_ssl=""
    local heat_certfile=""
    local heat_keyfile=""
    local heat_api_port=$HEAT_API_PORT
    local heat_cfn_api_port=$HEAT_API_CFN_PORT
    local heat_cw_api_port=$HEAT_API_CW_PORT
    local venv_path=""

    sudo cp $FILES/apache-heat-api.template $heat_apache_conf
    sudo sed -e "
        s|%PUBLICPORT%|$heat_api_port|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
        s|%SSLENGINE%|$heat_ssl|g;
        s|%SSLCERTFILE%|$heat_certfile|g;
        s|%SSLKEYFILE%|$heat_keyfile|g;
        s|%USER%|$STACK_USER|g;
        s|%VIRTUALENV%|$venv_path|g
    " -i $heat_apache_conf

    sudo cp $FILES/apache-heat-api-cfn.template $heat_cfn_apache_conf
    sudo sed -e "
        s|%PUBLICPORT%|$heat_cfn_api_port|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
        s|%SSLENGINE%|$heat_ssl|g;
        s|%SSLCERTFILE%|$heat_certfile|g;
        s|%SSLKEYFILE%|$heat_keyfile|g;
        s|%USER%|$STACK_USER|g;
        s|%VIRTUALENV%|$venv_path|g
    " -i $heat_cfn_apache_conf

    sudo cp $FILES/apache-heat-api-cloudwatch.template $heat_cloudwatch_apache_conf
    sudo sed -e "
        s|%PUBLICPORT%|$heat_cw_api_port|g;
        s|%APACHE_NAME%|$APACHE_NAME|g;
        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
        s|%SSLENGINE%|$heat_ssl|g;
        s|%SSLCERTFILE%|$heat_certfile|g;
        s|%SSLKEYFILE%|$heat_keyfile|g;
        s|%USER%|$STACK_USER|g;
        s|%VIRTUALENV%|$venv_path|g
    " -i $heat_cloudwatch_apache_conf
}


# 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
    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:
