#!/bin/bash
#
# lib/rpc_backend
# Interface for interactig with different rpc backend
# rpc backend settings

# Dependencies:
#
# - ``functions`` file
# - ``RABBIT_{HOST|PASSWORD|USERID}`` must be defined when RabbitMQ is used
# - ``RPC_MESSAGING_PROTOCOL`` option for configuring the messaging protocol

# ``stack.sh`` calls the entry points in this order:
#
# - check_rpc_backend
# - install_rpc_backend
# - restart_rpc_backend
# - iniset_rpc_backend

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

RPC_MESSAGING_PROTOCOL=${RPC_MESSAGING_PROTOCOL:-0.9}

# TODO(sdague): RPC backend selection is super wonky because we treat
# messaging server as a service, which it really isn't for multi host
QPID_HOST=${QPID_HOST:-}

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


# Make sure we only have one rpc backend enabled.
# Also check the specified rpc backend is available on your platform.
function check_rpc_backend {
    local c svc

    local rpc_needed=1
    # We rely on the fact that filenames in lib/* match the service names
    # that can be passed as arguments to is_service_enabled.
    # We check for a call to iniset_rpc_backend in these files, meaning
    # the service needs a backend.
    rpc_candidates=$(grep -rl iniset_rpc_backend $TOP_DIR/lib/ | awk -F/ '{print $NF}')
    for c in ${rpc_candidates}; do
        if is_service_enabled $c; then
            rpc_needed=0
            break
        fi
    done
    local rpc_backend_cnt=0
    for svc in qpid zeromq rabbit; do
        is_service_enabled $svc &&
        (( rpc_backend_cnt++ )) || true
    done
    if [ "$rpc_backend_cnt" -gt 1 ]; then
        echo "ERROR: only one rpc backend may be enabled,"
        echo "       set only one of 'rabbit', 'qpid', 'zeromq'"
        echo "       via ENABLED_SERVICES."
    elif [ "$rpc_backend_cnt" == 0 ] && [ "$rpc_needed" == 0 ]; then
        echo "ERROR: at least one rpc backend must be enabled,"
        echo "       set one of 'rabbit', 'qpid', 'zeromq'"
        echo "       via ENABLED_SERVICES."
    fi

    if is_service_enabled qpid && ! qpid_is_supported; then
        die $LINENO "Qpid support is not available for this version of your distribution."
    fi
}

# 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
    elif is_service_enabled qpid; then
        if is_fedora; then
            uninstall_package qpid-cpp-server
        elif is_ubuntu; then
            uninstall_package qpidd
        else
            exit_distro_not_supported "qpid installation"
        fi
    elif is_service_enabled zeromq; then
        if is_fedora; then
            uninstall_package zeromq python-zmq
            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
                uninstall_package redis python-redis
            fi
        elif is_ubuntu; then
            uninstall_package libzmq1 python-zmq
            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
                uninstall_package redis-server python-redis
            fi
        elif is_suse; then
            uninstall_package libzmq1 python-pyzmq
            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
                uninstall_package redis python-redis
            fi
        else
            exit_distro_not_supported "zeromq installation"
        fi
    fi

    # Remove the AMQP 1.0 messaging libraries
    if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
        if is_fedora; then
            uninstall_package qpid-proton-c-devel
            uninstall_package python-qpid-proton
        fi
        # TODO(kgiusti) ubuntu cleanup
    fi
}

# install rpc backend
function install_rpc_backend {
    # Regardless of the broker used, if AMQP 1.0 is configured load
    # the necessary messaging client libraries for oslo.messaging
    if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
        if is_fedora; then
            install_package qpid-proton-c-devel
            install_package python-qpid-proton
        elif is_ubuntu; then
            # TODO(kgiusti) The QPID AMQP 1.0 protocol libraries
            # are not yet in the ubuntu repos. Enable these installs
            # once they are present:
            #install_package libqpid-proton2-dev
            #install_package python-qpid-proton
            # Also add 'uninstall' directives in cleanup_rpc_backend()!
            exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
        else
            exit_distro_not_supported "QPID AMQP 1.0 Proton libraries"
        fi
        # Install pyngus client API
        # TODO(kgiusti) can remove once python qpid bindings are
        # available on all supported platforms _and_ pyngus is added
        # to the requirements.txt file in oslo.messaging
        pip_install pyngus
    fi

    if is_service_enabled rabbit; then
        # Install rabbitmq-server
        install_package rabbitmq-server
    elif is_service_enabled qpid; then
        if is_fedora; then
            install_package qpid-cpp-server
        elif is_ubuntu; then
            install_package qpidd
        else
            exit_distro_not_supported "qpid installation"
        fi
        _configure_qpid
    elif is_service_enabled zeromq; then
        if is_fedora; then
            install_package zeromq python-zmq
            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
                install_package redis python-redis
            fi
        elif is_ubuntu; then
            install_package libzmq1 python-zmq
            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
                install_package redis-server python-redis
            fi
        elif is_suse; then
            install_package libzmq1 python-pyzmq
            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
                install_package redis python-redis
            fi
        else
            exit_distro_not_supported "zeromq installation"
        fi
        # Necessary directory for socket location.
        sudo mkdir -p /var/run/openstack
        sudo chown $STACK_USER /var/run/openstack
    fi

    # If using the QPID broker, install the QPID python client API
    if is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
        install_package python-qpid
    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
        local i
        for i in `seq 10`; do
            local rc=0

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

            if is_fedora || is_suse; then
                # service is not started by default
                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
        if is_service_enabled n-cell; then
            # Add partitioned access for the child cell
            if [ -z `sudo rabbitmqctl list_vhosts | grep child_cell` ]; then
                sudo rabbitmqctl add_vhost child_cell
                sudo rabbitmqctl set_permissions -p child_cell $RABBIT_USERID ".*" ".*" ".*"
            fi
        fi
    elif is_service_enabled qpid; then
        echo_summary "Starting qpid"
        restart_service qpidd
    fi
}

# builds transport url string
function get_transport_url {
    if is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
        echo "qpid://$QPID_USERNAME:$QPID_PASSWORD@$QPID_HOST:5672/"
    elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
        echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/"
    fi
}

# iniset cofiguration
function iniset_rpc_backend {
    local package=$1
    local file=$2
    local section=$3
    if is_service_enabled zeromq; then
        iniset $file $section rpc_backend "zmq"
        iniset $file $section rpc_zmq_host `hostname`
        if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
            iniset $file $section rpc_zmq_matchmaker \
                oslo.messaging._drivers.matchmaker_redis.MatchMakerRedis
            MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
            iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
        else
            die $LINENO "Other matchmaker drivers not supported"
        fi
    elif is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
        # For Qpid use the 'amqp' oslo.messaging transport when AMQP 1.0 is used
        if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
            iniset $file $section rpc_backend "amqp"
        else
            iniset $file $section rpc_backend "qpid"
        fi
        iniset $file $section qpid_hostname ${QPID_HOST:-$SERVICE_HOST}
        if [ -n "$QPID_USERNAME" ]; then
            iniset $file $section qpid_username $QPID_USERNAME
            iniset $file $section qpid_password $QPID_PASSWORD
        fi
    elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
        iniset $file $section rpc_backend "rabbit"
        iniset $file $section rabbit_hosts $RABBIT_HOST
        iniset $file $section rabbit_password $RABBIT_PASSWORD
        iniset $file $section rabbit_userid $RABBIT_USERID
    fi
}

# Check if qpid can be used on the current distro.
# qpid_is_supported
function qpid_is_supported {
    if [[ -z "$DISTRO" ]]; then
        GetDistro
    fi

    # Qpid is not in openSUSE
    ( ! is_suse )
}

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" ".*" ".*" ".*"
}

# Set up the various configuration files used by the qpidd broker
function _configure_qpid {

    # the location of the configuration files have changed since qpidd 0.14
    local qpid_conf_file
    if [ -e /etc/qpid/qpidd.conf ]; then
        qpid_conf_file=/etc/qpid/qpidd.conf
    elif [ -e /etc/qpidd.conf ]; then
        qpid_conf_file=/etc/qpidd.conf
    else
        exit_distro_not_supported "qpidd.conf file not found!"
    fi

    # force the ACL file to a known location
    local qpid_acl_file=/etc/qpid/qpidd.acl
    if [ ! -e $qpid_acl_file ]; then
        sudo mkdir -p -m 755 `dirname $qpid_acl_file`
        sudo touch $qpid_acl_file
        sudo chmod o+r $qpid_acl_file
    fi
    sudo sed -i.bak '/^acl-file=/d' $qpid_conf_file
    echo "acl-file=$qpid_acl_file" | sudo tee --append $qpid_conf_file

    sudo sed -i '/^auth=/d' $qpid_conf_file
    if [ -z "$QPID_USERNAME" ]; then
        # no QPID user configured, so disable authentication
        # and access control
        echo "auth=no" | sudo tee --append $qpid_conf_file
        cat <<EOF | sudo tee $qpid_acl_file
acl allow all all
EOF
    else
        # Configure qpidd to use PLAIN authentication, and add
        # QPID_USERNAME to the ACL:
        echo "auth=yes" | sudo tee --append $qpid_conf_file
        if [ -z "$QPID_PASSWORD" ]; then
            read_password QPID_PASSWORD "ENTER A PASSWORD FOR QPID USER $QPID_USERNAME"
        fi
        # Create ACL to allow $QPID_USERNAME full access
        cat <<EOF | sudo tee $qpid_acl_file
group admin ${QPID_USERNAME}@QPID
acl allow admin all
acl deny all all
EOF
        # Add user to SASL database
        if is_ubuntu; then
            install_package sasl2-bin
        elif is_fedora; then
            install_package cyrus-sasl-lib
            install_package cyrus-sasl-plain
        fi
        local sasl_conf_file=/etc/sasl2/qpidd.conf
        sudo sed -i.bak '/PLAIN/!s/mech_list: /mech_list: PLAIN /' $sasl_conf_file
        local sasl_db=`sudo grep sasldb_path $sasl_conf_file | cut -f 2 -d ":" | tr -d [:blank:]`
        if [ ! -e $sasl_db ]; then
            sudo mkdir -p -m 755 `dirname $sasl_db`
        fi
        echo $QPID_PASSWORD | sudo saslpasswd2 -c -p -f $sasl_db -u QPID $QPID_USERNAME
        sudo chmod o+r $sasl_db
    fi

    # If AMQP 1.0 is specified, ensure that the version of the
    # broker can support AMQP 1.0 and configure the queue and
    # topic address patterns used by oslo.messaging.
    if [ "$RPC_MESSAGING_PROTOCOL" == "AMQP1" ]; then
        QPIDD=$(type -p qpidd)
        if ! $QPIDD --help | grep -q "queue-patterns"; then
            exit_distro_not_supported "qpidd with AMQP 1.0 support"
        fi
        if ! grep -q "queue-patterns=exclusive" $qpid_conf_file; then
            cat <<EOF | sudo tee --append $qpid_conf_file
queue-patterns=exclusive
queue-patterns=unicast
topic-patterns=broadcast
EOF
        fi
    fi
}

# Restore xtrace
$XTRACE

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