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


# 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
        if [ -n "$RABBIT_USERID" ]; then
            sudo rabbitmqctl delete_user "$RABBIT_USERID"
        fi
        uninstall_package rabbitmq-server
        sudo killall epmd || sudo killall -9 epmd
        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 redis
        elif is_ubuntu; then
            uninstall_package libzmq1 python-zmq redis-server
        elif is_suse; then
            uninstall_package libzmq1 python-pyzmq redis
        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
        # NOTE(ewindisch): Redis is not strictly necessary
        # but there is a matchmaker driver that works
        # really well & out of the box for multi-node.
        if is_fedora; then
            install_package zeromq python-zmq redis
        elif is_ubuntu; then
            install_package libzmq1 python-zmq redis-server
        elif is_suse; then
            install_package libzmq1 python-pyzmq redis
        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=1059028
        local i
        for i in `seq 10`; do
            if is_fedora || is_suse; then
                # service is not started by default
                restart_service rabbitmq-server
            fi
            rabbit_setuser "$RABBIT_USERID" "$RABBIT_PASSWORD"
            # change the rabbit password since the default is "guest"
            sudo rabbitmqctl change_password $RABBIT_USERID $RABBIT_PASSWORD && break
            [[ $i -eq "10" ]] && die $LINENO "Failed to set rabbitmq password"
        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
}

# 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 ${package}.openstack.common.rpc.impl_zmq
        iniset $file $section rpc_zmq_matchmaker \
            ${package}.openstack.common.rpc.matchmaker_redis.MatchMakerRedis
        # Set MATCHMAKER_REDIS_HOST if running multi-node.
        MATCHMAKER_REDIS_HOST=${MATCHMAKER_REDIS_HOST:-127.0.0.1}
        iniset $file matchmaker_redis host $MATCHMAKER_REDIS_HOST
    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 ${package}.openstack.common.rpc.impl_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 ${package}.openstack.common.rpc.impl_kombu
        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
        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:
