#!/bin/bash

set -eux

SCRIPT_NAME=$(basename $0)

OS_AUTH_URL=${OS_AUTH_URL:-""}
if [ -z "$OS_AUTH_URL" ]; then
    echo "You must source a stackrc file for the Undercloud."
    exit 1
fi

TUSKAR=

function show_options () {
    echo "Usage: $SCRIPT_NAME [options]"
    echo
    echo "Updates an Overcloud."
    echo
    echo "Options:"
    echo "      --tuskar       -- will use tuskar for building the heat Template"
    echo
    exit $1
}

TEMP=$(getopt -o ,h -l,tuskar,help -n $SCRIPT_NAME -- "$@")
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
    case "$1" in
        --tuskar) TUSKAR="1"; shift 1;;
        -h | --help) show_options 0;;
        --) shift ; break ;;
        *) echo "Error: unsupported option $1." ; exit 1 ;;
    esac
done

# setup-baremetal requires this to be set
export TRIPLEO_ROOT=.
CPU=${CPU:-1}
MEM=${MEM:-4096}
DISK=${DISK:-30}
ARCH=${ARCH:-amd64}
MACS=${MACS:-"52:54:00:b5:bd:f0 52:54:00:f2:be:f0"}
VIRTUAL_POWER_USER=${VIRTUAL_POWER_USER:-$USER}
VIRTUAL_POWER_HOST=${VIRTUAL_POWER_HOST:-"192.168.122.1"}
SSH_KEY=${SSH_KEY:-""}
PM_IPS=( ${PM_IPS:-} )
PM_USERS=( ${PM_USERS:-} )
PM_PASSWORDS=( ${PM_PASSWORDS:-} )
export USE_IRONIC=1
export ROOT_DISK=${ROOT_DISK:-10}

source tripleo-overcloud-passwords

# Undercloud passwords must all be sourced into this script since we make use
# of $UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD below
source tripleo-undercloud-passwords

# Define the interface that will be bridged onto the Neutron defined
# network.
NeutronPublicInterface=${NeutronPublicInterface:-eth0}
HypervisorNeutronPublicInterface=${HypervisorNeutronPublicInterface:-$NeutronPublicInterface}
NEUTRON_NETWORK_TYPE=${NEUTRON_NETWORK_TYPE:-gre}
# Define the overcloud libvirt type for virtualization. kvm for
# baremetal, qemu for an overcloud running in vm's.
OVERCLOUD_LIBVIRT_TYPE=${OVERCLOUD_LIBVIRT_TYPE:-qemu}
NtpServer=${NtpServer:-""}

CONTROLSCALE=${CONTROLSCALE:-1}
COMPUTESCALE=${COMPUTESCALE:-1}
BLOCKSTORAGESCALE=${BLOCKSTORAGESCALE:-1}
SWIFTSTORAGESCALE=${SWIFTSTORAGESCALE:-1}

# Default flavor parameters
export OVERCLOUD_CONTROL_FLAVOR=${OVERCLOUD_CONTROL_FLAVOR:-"baremetal"}
export OVERCLOUD_COMPUTE_FLAVOR=${OVERCLOUD_COMPUTE_FLAVOR:-"baremetal"}
export OVERCLOUD_BLOCKSTORAGE_FLAVOR=${OVERCLOUD_BLOCKSTORAGE_FLAVOR:-"baremetal"}
export OVERCLOUD_SWIFTSTORAGE_FLAVOR=${OVERCLOUD_SWIFTSTORAGE_FLAVOR:-"baremetal"}

NeutronControlPlaneID=$(neutron net-show ctlplane | grep ' id ' | awk '{print $4}')

if [ -n "$TUSKAR" ]; then
    PLAN_ID=$( tuskar plan-show overcloud | awk '$2=="uuid" {print $4}' )

    export TUSKAR_PARAMETERS=${TUSKAR_PARAMETERS:-"
    -A NeutronControlPlaneID=${NeutronControlPlaneID}
    -A controller-1::AdminPassword=${OVERCLOUD_ADMIN_PASSWORD}
    -A controller-1::AdminToken=${OVERCLOUD_ADMIN_TOKEN}
    -A cinder-storage-1::AdminPassword=${OVERCLOUD_ADMIN_PASSWORD}
    -A compute-1::AdminPassword=${OVERCLOUD_ADMIN_PASSWORD}
    -A controller-1::SnmpdReadonlyUserPassword=${UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD}
    -A cinder-storage-1::SnmpdReadonlyUserPassword=${UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD}
    -A swift-storage-1::SnmpdReadonlyUserPassword=${UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD}
    -A compute-1::SnmpdReadonlyUserPassword=${UNDERCLOUD_CEILOMETER_SNMPD_PASSWORD}
    -A controller-1::CeilometerPassword=${OVERCLOUD_CEILOMETER_PASSWORD}
    -A controller-1::CeilometerMeteringSecret=${OVERCLOUD_CEILOMETER_SECRET}
    -A compute-1::CeilometerPassword=${OVERCLOUD_CEILOMETER_PASSWORD}
    -A compute-1::CeilometerMeteringSecret=${OVERCLOUD_CEILOMETER_SECRET}
    -A controller-1::CinderPassword=${OVERCLOUD_CINDER_PASSWORD}
    -A cinder-storage-1::CinderPassword=${OVERCLOUD_CINDER_PASSWORD}
    -A controller-1::GlancePassword=${OVERCLOUD_GLANCE_PASSWORD}
    -A controller-1::HeatPassword=${OVERCLOUD_HEAT_PASSWORD}
    -A controller-1::NeutronPassword=${OVERCLOUD_NEUTRON_PASSWORD}
    -A compute-1::NeutronPassword=${OVERCLOUD_NEUTRON_PASSWORD}
    -A controller-1::NovaPassword=${OVERCLOUD_NOVA_PASSWORD}
    -A compute-1::NovaPassword=${OVERCLOUD_NOVA_PASSWORD}
    -A controller-1::SwiftHashSuffix=${OVERCLOUD_SWIFT_HASH}
    -A controller-1::SwiftPassword=${OVERCLOUD_SWIFT_PASSWORD}
    -A controller-1::CinderISCSIHelper=lioadm
    -A cinder-storage-1::CinderISCSIHelper=lioadm
    -A controller-1::CloudName=overcloud
    -A controller-1::NeutronPublicInterface=$NeutronPublicInterface
    -A compute-1::NeutronPublicInterface=$NeutronPublicInterface
    -A compute-1::NovaComputeLibvirtType=$OVERCLOUD_LIBVIRT_TYPE
    -A controller-1::NtpServer=${NtpServer}
    -A compute-1::NtpServer=${NtpServer}
    -A controller-1::NeutronNetworkType=${NEUTRON_NETWORK_TYPE}
    -A compute-1::NeutronNetworkType=${NEUTRON_NETWORK_TYPE}
    -A swift-storage-1::NeutronNetworkType=${NEUTRON_NETWORK_TYPE}
    -A controller-1::NeutronTunnelTypes=${NEUTRON_TUNNEL_TYPES}
    -A compute-1::NeutronTunnelTypes=${NEUTRON_TUNNEL_TYPES}
    -A controller-1::count=${CONTROLSCALE}
    -A compute-1::count=${COMPUTESCALE}
    -A swift-storage-1::count=${SWIFTSTORAGESCALE}
    -A cinder-storage-1::count=${BLOCKSTORAGESCALE}
    "}

    # These attributes can't be changed in Tuskar-UI, so this is the only
    # difference to deploying through UI
    # -A NeutronDnsmasqOptions=dhcp-option-force=26,1400
    # -A NeutronNetworkType=${NEUTRON_NETWORK_TYPE}
    # -A NeutronTunnelTypes=${NEUTRON_TUNNEL_TYPES}

    # Send parameters to tuskar
    tuskar plan-patch $TUSKAR_PARAMETERS $PLAN_ID

    # Get keystone certificates
    HEAT_ENV=${HEAT_ENV:-"overcloud-env.json"}
    KeystoneCACertificate=$(os-apply-config -m $HEAT_ENV --key parameters.KeystoneCACertificate --type raw)
    KeystoneSigningCertificate=$(os-apply-config -m $HEAT_ENV --key parameters.KeystoneSigningCertificate --type raw)
    KeystoneSigningKey=$(os-apply-config -m $HEAT_ENV --key parameters.KeystoneSigningKey --type raw)

    # Sending the Certificates one by one, otherwise there are problems with escaping
    tuskar plan-patch -A controller-1::KeystoneCACertificate="${KeystoneCACertificate}" $PLAN_ID
    tuskar plan-patch -A controller-1::KeystoneSigningCertificate="${KeystoneSigningCertificate}" $PLAN_ID
    tuskar plan-patch -A controller-1::KeystoneSigningKey="${KeystoneSigningKey}" $PLAN_ID

    # Get templates from tuskar
    tuskar plan-templates -O tuskar_templates $PLAN_ID

    OVERCLOUD_YAML_PATH="tuskar_templates/plan.yaml"
    ENVIROMENT_YAML_PATH="tuskar_templates/environment.yaml"

    heat stack-update -f $OVERCLOUD_YAML_PATH \
        -e $ENVIROMENT_YAML_PATH \
        overcloud

else
    if [ -d /usr/share/openstack-tripleo-heat-templates ]; then
        tripleo-heat-merge \
            --included-template-dir /usr/share/openstack-tripleo-heat-templates \
            --scale NovaCompute=$COMPUTESCALE \
            --scale BlockStorage=$BLOCKSTORAGESCALE \
            --scale SwiftStorage=$SWIFTSTORAGESCALE \
            /usr/share/openstack-tripleo-heat-templates/overcloud-source.yaml \
            /usr/share/openstack-tripleo-heat-templates/swift-source.yaml \
            /usr/share/openstack-tripleo-heat-templates/swift-storage-source.yaml \
            /usr/share/openstack-tripleo-heat-templates/ssl-source.yaml \
            /usr/share/openstack-tripleo-heat-templates/block-storage.yaml \
            > overcloud.yaml
        OVERCLOUD_YAML_PATH=overcloud.yaml

        export OVERCLOUD_PARAMETERS=${OVERCLOUD_PARAMETERS:-"\
        -P AdminPassword=${OVERCLOUD_ADMIN_PASSWORD} \
        -P AdminToken=${OVERCLOUD_ADMIN_TOKEN} \
        -P CinderPassword=${OVERCLOUD_CINDER_PASSWORD} \
        -P GlanceLogFile=\"''\" \
        -P GlancePassword=${OVERCLOUD_GLANCE_PASSWORD} \
        -P HeatPassword=${OVERCLOUD_HEAT_PASSWORD} \
        -P NeutronDnsmasqOptions=\"dhcp-option-force=26,1400\" \
        -P NeutronPassword=${OVERCLOUD_NEUTRON_PASSWORD} \
        -P NeutronPublicInterface=$NeutronPublicInterface \
        -P NovaComputeLibvirtType=$OVERCLOUD_LIBVIRT_TYPE \
        -P NovaPassword=${OVERCLOUD_NOVA_PASSWORD} \
        -P SwiftHashSuffix=${OVERCLOUD_SWIFT_HASH} \
        -P SwiftPassword=${OVERCLOUD_SWIFT_PASSWORD} \
        "}

        HEAT_ENVIRONMENT=""

    else
        make -C $INSTACK_ROOT/tripleo-heat-templates overcloud.yaml COMPUTESCALE=$COMPUTESCALE BLOCKSTORAGESCALE=$BLOCKSTORAGESCALE SWIFTSTORAGESCALE=$SWIFTSTORAGESCALE
        OVERCLOUD_YAML_PATH=$INSTACK_ROOT/tripleo-heat-templates/overcloud.yaml

        NeutronControlPlaneID=$(neutron net-show ctlplane | grep ' id ' | awk '{print $4}')

        export OVERCLOUD_PARAMETERS=${OVERCLOUD_PARAMETERS:-"\
        -P AdminPassword=${OVERCLOUD_ADMIN_PASSWORD} \
        -P AdminToken=${OVERCLOUD_ADMIN_TOKEN} \
        -P CeilometerPassword=${OVERCLOUD_CEILOMETER_PASSWORD} \
        -P CeilometerMeteringSecret=${OVERCLOUD_CEILOMETER_SECRET} \
        -P CinderPassword=${OVERCLOUD_CINDER_PASSWORD} \
        -P CinderISCSIHelper=lioadm \
        -P CloudName=overcloud \
        -P GlancePassword=${OVERCLOUD_GLANCE_PASSWORD} \
        -P HeatPassword=${OVERCLOUD_HEAT_PASSWORD} \
        -P NeutronControlPlaneID=$NeutronControlPlaneID \
        -P NeutronDnsmasqOptions=dhcp-option-force=26,1400 \
        -P NeutronPassword=${OVERCLOUD_NEUTRON_PASSWORD} \
        -P NeutronPublicInterface=$NeutronPublicInterface \
        -P NovaComputeLibvirtType=$OVERCLOUD_LIBVIRT_TYPE \
        -P NovaPassword=${OVERCLOUD_NOVA_PASSWORD} \
        -P SwiftHashSuffix=${OVERCLOUD_SWIFT_HASH} \
        -P SwiftPassword=${OVERCLOUD_SWIFT_PASSWORD} \
        -P NeutronNetworkType=${NEUTRON_NETWORK_TYPE} \
        -P NeutronTunnelTypes=${NEUTRON_TUNNEL_TYPES} \
        "}


        HEAT_ENV=${HEAT_ENV:-"${INSTACK_ROOT}/overcloud-env.json"}
        HEAT_ENVIRONMENT="-e ${HEAT_ENV}"

    fi

    heat stack-update -f $OVERCLOUD_YAML_PATH \
        $OVERCLOUD_PARAMETERS \
        $HEAT_ENVIRONMENT \
        overcloud
fi

tripleo wait_for_stack_ready 220 10 overcloud

echo "Overcloud UPDATE_COMPLETE"
echo "Overcloud Updated."
