#!/bin/bash
#
# lib/rpc_backend
# Interface for interactig with different RPC backends

# 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_gr 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"

            restart_service rabbitmq-server

            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:-DEFAULT}
    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 "redis"
            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 oslo_messaging_rabbit rabbit_hosts $RABBIT_HOST
        iniset $file oslo_messaging_rabbit rabbit_password $RABBIT_PASSWORD
        iniset $file oslo_messaging_rabbit rabbit_userid $RABBIT_USERID
        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
}

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