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

    if [[ ! -d $HEAT_CONF_DIR ]]; then
        sudo mkdir -p $HEAT_CONF_DIR
    fi
    sudo chown $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 DEFAULT
    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

    # 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

    # heat environment
    sudo mkdir -p $HEAT_ENV_DIR
    sudo chown $STACK_USER $HEAT_ENV_DIR
    # copy the default environment
    cp $HEAT_DIR/etc/heat/environment.d/* $HEAT_ENV_DIR/

    # heat template resources.
    sudo mkdir -p $HEAT_TEMPLATES_DIR
    sudo chown $STACK_USER $HEAT_TEMPLATES_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 mkdir -p $HEAT_AUTH_CACHE_DIR
    sudo chown $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
}

# 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

            local heat_service=$(get_or_create_service "heat" \
                    "orchestration" "Heat Orchestration Service")
            get_or_create_endpoint $heat_service \
                "$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"

            local heat_cfn_service=$(get_or_create_service "heat-cfn" \
                    "cloudformation" "Heat CloudFormation Service")
            get_or_create_endpoint $heat_cfn_service \
                "$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_DEFERRED_AUTH == trusts ]]; then
        iniset $HEAT_CONF DEFAULT deferred_auth_method trusts
    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"
    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
}

# Restore xtrace
$XTRACE

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