#!/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:
#
# - functions
# - dib (if HEAT_CREATE_TEST_IMAGE=True)

# 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
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_STACK_DOMAIN=$(trueorfalse True HEAT_STACK_DOMAIN)
HEAT_API_HOST=${HEAT_API_HOST:-$HOST_IP}
HEAT_API_PORT=${HEAT_API_PORT:-8004}

# other default options
HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-trusts}

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

# configure_heat() - Set config files, create data dirs, etc
function configure_heat {
    if [[ "$HEAT_STANDALONE" = "True" ]]; then
        setup_develop $HEAT_DIR/contrib/heat_keystoneclient_v2
    fi

    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 identity_uri $KEYSTONE_AUTH_URI
    iniset $HEAT_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_URI/v2.0
    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

    if is_ssl_enabled_service "key"; then
        iniset $HEAT_CONF clients_keystone ca_file $SSL_BUNDLE_FILE
    fi

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

    # paste_deploy
    if [[ "$HEAT_STANDALONE" = "True" ]]; then
        iniset $HEAT_CONF paste_deploy flavor standalone
        iniset $HEAT_CONF DEFAULT keystone_backend heat_keystoneclient_v2.client.KeystoneClientV2
        iniset $HEAT_CONF clients_heat url "http://$HEAT_API_HOST:$HEAT_API_PORT/v1/%(tenant_id)s"
    fi

    # OpenStack API
    iniset $HEAT_CONF heat_api bind_port $HEAT_API_PORT

    # 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 {
    # migrated from files/keystone_data.sh
    local service_tenant=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
    local admin_role=$(openstack role list | awk "/ admin / { print \$2 }")

    local heat_user=$(get_or_create_user "heat" \
        "$SERVICE_PASSWORD" $service_tenant)
    get_or_add_user_role $admin_role $heat_user $service_tenant

    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"

    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_functional_test_image() - Build and upload functional test image
function build_heat_functional_test_image {
    if is_service_enabled dib; then
        build_dib_pip_repo "$OCC_DIR $OAC_DIR $ORC_DIR $HEAT_CFNTOOLS_DIR"
        local image_name=heat-functional-tests-image

        # The elements to invoke disk-image-create with
        local image_elements="vm fedora selinux-permissive pypi \
            os-collect-config os-refresh-config os-apply-config heat-cfntools \
            heat-config heat-config-cfn-init heat-config-puppet heat-config-script"

        # Elements path for tripleo-image-elements and heat-templates software-config
        local elements_path=$TIE_DIR/elements:$HEAT_TEMPLATES_REPO_DIR/hot/software-config/elements

        disk_image_create_upload "$image_name" "$image_elements" "$elements_path"
        iniset $TEMPEST_CONFIG orchestration image_ref $image_name
    else
        echo "Error, HEAT_CREATE_TEST_IMAGE=True requires dib" >&2
        echo "Add \"enable_service dib\" to your localrc" >&2
        exit 1
    fi
}

# Restore xtrace
$XTRACE

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