#!/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"

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