#!/bin/bash
# vim: expandtab:tabstop=4:shiftwidth=4


function usage() {
    cat << EOF
Usage: opssh [OPTIONS] command [...]

Options:
  --version             show program's version number and exit
  --help                show this help message and exit
  -l USER, --user=USER  username (OPTIONAL)
  -p PAR, --par=PAR     max number of parallel threads (OPTIONAL)
  --outdir=OUTDIR       output directory for stdout files (OPTIONAL)
  --errdir=ERRDIR       output directory for stderr files (OPTIONAL)
  -e ENV, --env ENV     which environment to use
  -t HOST_TYPE, --host-type HOST_TYPE
                        which host type to use
  --list-host-types     list all of the host types
  --timeout=TIMEOUT     timeout (secs) (0 = no timeout) per host (OPTIONAL)
  -O OPTION, --option=OPTION
                        SSH option (OPTIONAL)
  -v, --verbose         turn on warning and diagnostic messages (OPTIONAL)
  -A, --askpass         Ask for a password (OPTIONAL)
  -x ARGS, --extra-args=ARGS
                        Extra command-line arguments, with processing for
                        spaces, quotes, and backslashes
  -X ARG, --extra-arg=ARG
                        Extra command-line argument
  -i, --inline          inline aggregated output and error for each server
  --inline-stdout       inline standard output for each server
  -I, --send-input      read from standard input and send as input to ssh
  -P, --print           print output as we get it

Example: opssh -t ex-srv -e stg -l irb2 --outdir /tmp/foo uptime

EOF
}

if [ $# -eq 0 ] || [ "$1" == "--help" ]
then
    usage
    exit 1
fi

# See if ohi is installed
if ! which ohi &>/dev/null ; then
    echo "ERROR: can't find ohi (OpenShift Host Inventory) on your system, please either install the openshift-ansible-bin package, or add openshift-ansible/bin to your path."

    exit 10
fi

PAR=200
USER=root
TIMEOUT=0
ARGS=()
ENV=""
HOST_TYPE=""
while [ $# -gt 0 ] ; do
    case $1 in
        -t|--host-type)
            shift # get past the option
            HOST_TYPE=$1
            shift # get past the value of the option
            ;;

        -e)
            shift # get past the option
            ENV=$1
            shift # get past the value of the option
            ;;

        --timeout)
            shift # get past the option
            TIMEOUT=$1
            shift # get past the value of the option
            ;;

        -p|--par)
            shift # get past the option
            PAR=$1
            shift # get past the value of the option
            ;;

        -l|--user)
            shift # get past the option
            USER=$1
            shift # get past the value of the option
            ;;

        --list-host-types)
            ohi --list-host-types
            exit 0
            ;;

        -h|--hosts|-H|--host|-o)
            echo "ERROR: unknown option $1"
            exit 20
            ;;

        *)
            args+=("$1")
            shift
            ;;
    esac
done

# Get host list from ohi
if [ -n "$ENV" -a -n "$HOST_TYPE" ] ; then
    HOSTS="$(ohi -t "$HOST_TYPE" -e "$ENV" 2>/dev/null)"
    OHI_ECODE=$?
elif [ -n "$ENV" ] ; then
    HOSTS="$(ohi -e "$ENV" 2>/dev/null)"
    OHI_ECODE=$?
elif [ -n "$HOST_TYPE" ] ; then
    HOSTS="$(ohi -t "$HOST_TYPE" 2>/dev/null)"
    OHI_ECODE=$?
else
    echo
    echo "Error: either -e or -t must be specified"
    echo
    exit 10
fi

if [ $OHI_ECODE -ne 0 ] ; then
    echo
    echo "ERROR: ohi failed with exit code $OHI_ECODE"
    echo
    echo "This is usually caused by a bad value passed for host-type or environment."
    echo
    exit 25
fi

exec pssh -t $TIMEOUT -p $PAR -l $USER -h <(echo "$HOSTS") "${args[@]}"