#!/bin/bash
#
# lib/rpc_backend
# Interface for installing RabbitMQ on the system

# Dependencies:
#
# - ``functions`` file
# - ``RABBIT_{HOST|PASSWORD|USERID}`` must be defined when RabbitMQ is used

# ``stack.sh`` calls the entry points in this order:
#
# - check_rpc_backend
# - install_rpc_backend
# - restart_rpc_backend
# - iniset_rpc_backend (stable interface)
#
# Note: if implementing an out of tree plugin for an RPC backend, you
# should install all services through normal plugin methods, then
# redefine ``iniset_rpc_backend`` in your code. That's the one portion
# of this file which is a standard interface.

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

RABBIT_USERID=${RABBIT_USERID:-stackrabbit}
if is_service_enabled rabbit; then
    RABBIT_HOST=${RABBIT_HOST:-$SERVICE_HOST}
fi

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

# clean up after rpc backend - eradicate all traces so changing backends
# produces a clean switch
function cleanup_rpc_backend {
    if is_service_enabled rabbit; then
        # Obliterate rabbitmq-server
        uninstall_package rabbitmq-server
        # in case it's not actually running, /bin/true at the end
        sudo killall epmd || sudo killall -9 epmd || /bin/true
        if is_ubuntu; then
            # And the Erlang runtime too
            apt_get purge -y erlang*
        fi
    fi
}

# install rpc backend
function install_rpc_backend {
    if is_service_enabled rabbit; then
        # Install rabbitmq-server
        install_package rabbitmq-server
        if is_fedora; then
            # NOTE(jangutter): If rabbitmq is not running (as in a fresh
            # install) then rabbit_setuser triggers epmd@0.0.0.0.socket with
            # socket activation. This fails the first time and does not get
            # cleared. It is benign, but the workaround is to start rabbitmq a
            # bit earlier for RPM based distros.
            sudo systemctl --now enable rabbitmq-server
        fi
    fi
}

# restart the rpc backend
function restart_rpc_backend {
    if is_service_enabled rabbit; then
        # Start rabbitmq-server
        echo_summary "Starting RabbitMQ"
        # NOTE(bnemec): Retry initial rabbitmq configuration to deal with
        # the fact that sometimes it fails to start properly.
        # Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1144100
        # NOTE(tonyb): Extend the original retry logic to only restart rabbitmq
        # every second time around the loop.
        # See: https://bugs.launchpad.net/devstack/+bug/1449056 for details on
        # why this is needed.  This can bee seen on vivid and Debian unstable
        # (May 2015)
        # TODO(tonyb): Remove this when Debian and Ubuntu have a fixed systemd
        # service file.
        local i
        for i in `seq 20`; do
            local rc=0

            [[ $i -eq "20" ]] && die $LINENO "Failed to set rabbitmq password"

            if [[ $(( i % 2 )) == "0" ]] ; then
                restart_service rabbitmq-server
            fi

            rabbit_setuser "$RABBIT_USERID" "$RABBIT_PASSWORD" || rc=$?
            if [ $rc -ne 0 ]; then
                continue
            fi

            # change the rabbit password since the default is "guest"
            sudo rabbitmqctl change_password \
                $RABBIT_USERID $RABBIT_PASSWORD || rc=$?
            if [ $rc -ne 0 ]; then
                continue;
            fi

            break
        done
        # NOTE(frickler): Remove the default guest user
        sudo rabbitmqctl delete_user guest || true
    fi
}

# adds a vhost to the rpc backend
function rpc_backend_add_vhost {
    local vhost="$1"
    if is_service_enabled rabbit; then
        if [ -z `sudo rabbitmqctl list_vhosts | grep $vhost` ]; then
            sudo rabbitmqctl add_vhost $vhost
            sudo rabbitmqctl set_permissions -p $vhost $RABBIT_USERID ".*" ".*" ".*"
        fi
    else
        echo 'RPC backend does not support vhosts'
        return 1
    fi
}

# Returns the address of the RPC backend in URL format.
function get_transport_url {
    local virtual_host=$1
    if is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
        echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/$virtual_host"
    fi
}

# Returns the address of the Notification backend in URL format.  This
# should be used to set the transport_url option in the
# oslo_messaging_notifications group.
function get_notification_url {
    local virtual_host=$1
    if is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
        echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/$virtual_host"
    fi
}

# iniset configuration
function iniset_rpc_backend {
    local package=$1
    local file=$2
    local section=${3:-DEFAULT}
    local virtual_host=$4
    if is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
        iniset $file $section transport_url $(get_transport_url "$virtual_host")
        if [ -n "$RABBIT_HEARTBEAT_TIMEOUT_THRESHOLD" ]; then
            iniset $file oslo_messaging_rabbit heartbeat_timeout_threshold $RABBIT_HEARTBEAT_TIMEOUT_THRESHOLD
        fi
        if [ -n "$RABBIT_HEARTBEAT_RATE" ]; then
            iniset $file oslo_messaging_rabbit heartbeat_rate $RABBIT_HEARTBEAT_RATE
        fi
    fi
}

function rabbit_setuser {
    local user="$1" pass="$2" found="" out=""
    out=$(sudo rabbitmqctl list_users) ||
        { echo "failed to list users" 1>&2; return 1; }
    found=$(echo "$out" | awk '$1 == user { print $1 }' "user=$user")
    if [ "$found" = "$user" ]; then
        sudo rabbitmqctl change_password "$user" "$pass" ||
            { echo "failed changing pass for '$user'" 1>&2; return 1; }
    else
        sudo rabbitmqctl add_user "$user" "$pass" ||
            { echo "failed changing pass for $user"; return 1; }
    fi
    sudo rabbitmqctl set_permissions "$user" ".*" ".*" ".*"
}

# Restore xtrace
$_XTRACE_RPC_BACKEND

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