diff options
| author | Wesley Hearn <wesley.s.hearn@gmail.com> | 2015-05-06 10:27:42 -0400 | 
|---|---|---|
| committer | Wesley Hearn <wesley.s.hearn@gmail.com> | 2015-05-06 10:27:42 -0400 | 
| commit | 1d8e743921a48a5abd2ca75323321f6db261101b (patch) | |
| tree | 8f3370fd2d9537a568d97e48ece9e18f3d0032bb /bin/opssh | |
| parent | 196d37e2ffa0d7f4221a857b143fd09f84a9d00b (diff) | |
| parent | e0b2d98a6cac21cfa555afe4d660cb62c1180856 (diff) | |
| download | openshift-1d8e743921a48a5abd2ca75323321f6db261101b.tar.gz openshift-1d8e743921a48a5abd2ca75323321f6db261101b.tar.bz2 openshift-1d8e743921a48a5abd2ca75323321f6db261101b.tar.xz openshift-1d8e743921a48a5abd2ca75323321f6db261101b.zip  | |
Merge pull request #208 from openshift/master
Merge Master Into INT
Diffstat (limited to 'bin/opssh')
| -rwxr-xr-x | bin/opssh | 274 | 
1 files changed, 131 insertions, 143 deletions
@@ -1,146 +1,134 @@ -#!/usr/bin/env python +#!/bin/bash  # vim: expandtab:tabstop=4:shiftwidth=4 -import argparse -import traceback -import sys -import os -import re -import tempfile -import time -import subprocess -import ConfigParser -from openshift_ansible import awsutil -from openshift_ansible.awsutil import ArgumentError - -DEFAULT_PSSH_PAR = 200 -PSSH = '/usr/bin/pssh' -CONFIG_MAIN_SECTION = 'main' -CONFIG_HOST_TYPE_ALIAS_SECTION = 'host_type_aliases' -CONFIG_INVENTORY_OPTION = 'inventory' - -class Opssh(object): -    def __init__(self): -        self.inventory = None -        self.host_type_aliases = {} -        self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) - -        # Default the config path to /etc -        self.config_path = os.path.join(os.path.sep, 'etc',  \ -                                        'openshift_ansible', \ -                                        'openshift_ansible.conf') - -        self.parse_cli_args() -        self.parse_config_file() - -        self.aws = awsutil.AwsUtil(self.inventory, self.host_type_aliases) - -    def run(self): -        if self.args.list_host_types: -            self.aws.print_host_types() -            return 0 - -        if self.args.host_type is not None or \ -           self.args.env is not None: -            return self.run_pssh() - -        # We weren't able to determine what they wanted to do -        raise ArgumentError("Invalid combination of arguments") - -    def run_pssh(self): -        """Actually run the pssh command based off of the supplied options -        """ - -        # Default set of options -        pssh_args = [PSSH, '-t', '0', '-p', str(self.args.par), '--user', self.args.user] - -        if self.args.inline: -            pssh_args.append("--inline") - -        if self.args.outdir: -            pssh_args.extend(["--outdir", self.args.outdir]) - -        if self.args.errdir: -            pssh_args.extend(["--errdir", self.args.errdir]) - -        hosts = self.aws.get_host_list(host_type=self.args.host_type, -                                       env=self.args.env) - -        with tempfile.NamedTemporaryFile(prefix='opssh-', delete=True) as f: -            for h in hosts: -                f.write(h + os.linesep) -            f.flush() - -            pssh_args.extend(["-h", f.name]) -            pssh_args.append(self.args.command) - -            print -            print "Running: %s" % ' '.join(pssh_args) -            print -            return subprocess.call(pssh_args) - -        return None - -    def parse_config_file(self): -        if os.path.isfile(self.config_path): -            config = ConfigParser.ConfigParser() -            config.read(self.config_path) - -            if config.has_section(CONFIG_MAIN_SECTION) and \ -               config.has_option(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION): -                self.inventory = config.get(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION) - -            self.host_type_aliases = {} -            if config.has_section(CONFIG_HOST_TYPE_ALIAS_SECTION): -                for alias in config.options(CONFIG_HOST_TYPE_ALIAS_SECTION): -                    value = config.get(CONFIG_HOST_TYPE_ALIAS_SECTION, alias).split(',') -                    self.host_type_aliases[alias] = value - -    def parse_cli_args(self): -        """Setup the command line parser with the options we want -        """ - -        parser = argparse.ArgumentParser(description='Openshift Online PSSH Tool.') - -        parser.add_argument('--list-host-types', default=False, action='store_true', -                       help='List all of the host types') - -        parser.add_argument('-e', '--env', action="store", -                       help="Which environment to use") - -        parser.add_argument('-t', '--host-type', action="store", default=None, -                       help="Which host type to use") - -        parser.add_argument('-c', '--command', action='store', -                       help='Command to run on remote host(s)') - -        parser.add_argument('--user', action='store', default='root', -                       help='username') - -        parser.add_argument('-i', '--inline', default=False, action='store_true', -                       help='inline aggregated output and error for each server') - -        parser.add_argument('-p', '--par', action='store', default=DEFAULT_PSSH_PAR, -                       help=('max number of parallel threads (default %s)' % DEFAULT_PSSH_PAR)) - -        parser.add_argument('--outdir', action='store', -                       help='output directory for stdout files') - -        parser.add_argument('--errdir', action='store', -                       help='output directory for stderr files') - -        self.args = parser.parse_args() - - -if __name__ == '__main__': -    if len(sys.argv) == 1: -        print "\nError: No options given. Use --help to see the available options\n" -        sys.exit(0) - -    try: -        opssh = Opssh() -        exitcode = opssh.run() -        sys.exit(exitcode) -    except ArgumentError as e: -        print "\nError: %s\n" % e.message +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[@]}"  | 
