summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/cluster241
-rwxr-xr-xbin/ohi110
-rw-r--r--bin/openshift-ansible-bin.spec65
-rw-r--r--bin/openshift_ansible.conf.example6
-rw-r--r--bin/openshift_ansible/__init__.py0
-rw-r--r--bin/openshift_ansible/awsutil.py (renamed from bin/awsutil.py)70
-rwxr-xr-xbin/opssh79
-rwxr-xr-xbin/oscp28
-rwxr-xr-xbin/ossh26
-rwxr-xr-xbin/ossh_bash_completion23
10 files changed, 604 insertions, 44 deletions
diff --git a/bin/cluster b/bin/cluster
new file mode 100755
index 000000000..79f1f988f
--- /dev/null
+++ b/bin/cluster
@@ -0,0 +1,241 @@
+#!/usr/bin/env python2
+# vim: expandtab:tabstop=4:shiftwidth=4
+
+import argparse
+import ConfigParser
+import sys
+import os
+
+
+class Cluster(object):
+ """
+ Control and Configuration Interface for OpenShift Clusters
+ """
+ def __init__(self):
+ # setup ansible ssh environment
+ if 'ANSIBLE_SSH_ARGS' not in os.environ:
+ os.environ['ANSIBLE_SSH_ARGS'] = (
+ '-o ForwardAgent=yes '
+ '-o StrictHostKeyChecking=no '
+ '-o UserKnownHostsFile=/dev/null '
+ '-o ControlMaster=auto '
+ '-o ControlPersist=600s '
+ )
+
+ def get_deployment_type(self, args):
+ """
+ Get the deployment_type based on the environment variables and the
+ command line arguments
+ :param args: command line arguments provided by the user
+ :return: string representing the deployment type
+ """
+ deployment_type = 'origin'
+ if args.deployment_type:
+ deployment_type = args.deployment_type
+ elif 'OS_DEPLOYMENT_TYPE' in os.environ:
+ deployment_type = os.environ['OS_DEPLOYMENT_TYPE']
+ return deployment_type
+
+ def create(self, args):
+ """
+ Create an OpenShift cluster for given provider
+ :param args: command line arguments provided by user
+ :return: exit status from run command
+ """
+ env = {'cluster_id': args.cluster_id,
+ 'deployment_type': self.get_deployment_type(args)}
+ playbook = "playbooks/{}/openshift-cluster/launch.yml".format(args.provider)
+ inventory = self.setup_provider(args.provider)
+
+ env['num_masters'] = args.masters
+ env['num_nodes'] = args.nodes
+
+ return self.action(args, inventory, env, playbook)
+
+ def terminate(self, args):
+ """
+ Destroy OpenShift cluster
+ :param args: command line arguments provided by user
+ :return: exit status from run command
+ """
+ env = {'cluster_id': args.cluster_id,
+ 'deployment_type': self.get_deployment_type(args)}
+ playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(args.provider)
+ inventory = self.setup_provider(args.provider)
+
+ return self.action(args, inventory, env, playbook)
+
+ def list(self, args):
+ """
+ List VMs in cluster
+ :param args: command line arguments provided by user
+ :return: exit status from run command
+ """
+ env = {'cluster_id': args.cluster_id,
+ 'deployment_type': self.get_deployment_type(args)}
+ playbook = "playbooks/{}/openshift-cluster/list.yml".format(args.provider)
+ inventory = self.setup_provider(args.provider)
+
+ return self.action(args, inventory, env, playbook)
+
+ def config(self, args):
+ """
+ Configure or reconfigure OpenShift across clustered VMs
+ :param args: command line arguments provided by user
+ :return: exit status from run command
+ """
+ env = {'cluster_id': args.cluster_id,
+ 'deployment_type': self.get_deployment_type(args)}
+ playbook = "playbooks/{}/openshift-cluster/config.yml".format(args.provider)
+ inventory = self.setup_provider(args.provider)
+
+ return self.action(args, inventory, env, playbook)
+
+ def update(self, args):
+ """
+ Update to latest OpenShift across clustered VMs
+ :param args: command line arguments provided by user
+ :return: exit status from run command
+ """
+ env = {'cluster_id': args.cluster_id,
+ 'deployment_type': self.get_deployment_type(args)}
+ playbook = "playbooks/{}/openshift-cluster/update.yml".format(args.provider)
+ inventory = self.setup_provider(args.provider)
+
+ return self.action(args, inventory, env, playbook)
+
+ def setup_provider(self, provider):
+ """
+ Setup ansible playbook environment
+ :param provider: command line arguments provided by user
+ :return: path to inventory for given provider
+ """
+ config = ConfigParser.ConfigParser()
+ if 'gce' == provider:
+ config.readfp(open('inventory/gce/hosts/gce.ini'))
+
+ for key in config.options('gce'):
+ os.environ[key] = config.get('gce', key)
+
+ inventory = '-i inventory/gce/hosts'
+ elif 'aws' == provider:
+ config.readfp(open('inventory/aws/hosts/ec2.ini'))
+
+ for key in config.options('ec2'):
+ os.environ[key] = config.get('ec2', key)
+
+ inventory = '-i inventory/aws/hosts'
+ elif 'libvirt' == provider:
+ inventory = '-i inventory/libvirt/hosts'
+ else:
+ # this code should never be reached
+ raise ValueError("invalid PROVIDER {}".format(provider))
+
+ return inventory
+
+ def action(self, args, inventory, env, playbook):
+ """
+ Build ansible-playbook command line and execute
+ :param args: command line arguments provided by user
+ :param inventory: derived provider library
+ :param env: environment variables for kubernetes
+ :param playbook: ansible playbook to execute
+ :return: exit status from ansible-playbook command
+ """
+
+ verbose = ''
+ if args.verbose > 0:
+ verbose = '-{}'.format('v' * args.verbose)
+
+ ansible_env = '-e \'{}\''.format(
+ ' '.join(['%s=%s' % (key, value) for (key, value) in env.items()])
+ )
+
+ command = 'ansible-playbook {} {} {} {}'.format(
+ verbose, inventory, ansible_env, playbook
+ )
+
+ if args.verbose > 1:
+ command = 'time {}'.format(command)
+
+ if args.verbose > 0:
+ sys.stderr.write('RUN [{}]\n'.format(command))
+ sys.stderr.flush()
+
+ return os.system(command)
+
+
+if __name__ == '__main__':
+ """
+ Implemented to support writing unit tests
+ """
+
+ cluster = Cluster()
+
+ providers = ['gce', 'aws', 'libvirt']
+ parser = argparse.ArgumentParser(
+ description='Python wrapper to ensure proper environment for OpenShift ansible playbooks',
+ )
+ parser.add_argument('-v', '--verbose', action='count',
+ help='Multiple -v options increase the verbosity')
+ parser.add_argument('--version', action='version', version='%(prog)s 0.2')
+
+ meta_parser = argparse.ArgumentParser(add_help=False)
+ meta_parser.add_argument('provider', choices=providers, help='provider')
+ meta_parser.add_argument('cluster_id', help='prefix for cluster VM names')
+ meta_parser.add_argument('-t', '--deployment-type',
+ choices=['origin', 'online', 'enterprise'],
+ help='Deployment type. (default: origin)')
+
+ action_parser = parser.add_subparsers(dest='action', title='actions',
+ description='Choose from valid actions')
+
+ create_parser = action_parser.add_parser('create', help='Create a cluster',
+ parents=[meta_parser])
+ create_parser.add_argument('-m', '--masters', default=1, type=int,
+ help='number of masters to create in cluster')
+ create_parser.add_argument('-n', '--nodes', default=2, type=int,
+ help='number of nodes to create in cluster')
+ create_parser.set_defaults(func=cluster.create)
+
+ config_parser = action_parser.add_parser('config',
+ help='Configure or reconfigure a cluster',
+ parents=[meta_parser])
+ config_parser.set_defaults(func=cluster.config)
+
+ terminate_parser = action_parser.add_parser('terminate',
+ help='Destroy a cluster',
+ parents=[meta_parser])
+ terminate_parser.add_argument('-f', '--force', action='store_true',
+ help='Destroy cluster without confirmation')
+ terminate_parser.set_defaults(func=cluster.terminate)
+
+ update_parser = action_parser.add_parser('update',
+ help='Update OpenShift across cluster',
+ parents=[meta_parser])
+ update_parser.add_argument('-f', '--force', action='store_true',
+ help='Update cluster without confirmation')
+ update_parser.set_defaults(func=cluster.update)
+
+ list_parser = action_parser.add_parser('list', help='List VMs in cluster',
+ parents=[meta_parser])
+ list_parser.set_defaults(func=cluster.list)
+
+ args = parser.parse_args()
+
+ if 'terminate' == args.action and not args.force:
+ answer = raw_input("This will destroy the ENTIRE {} environment. Are you sure? [y/N] ".format(args.cluster_id))
+ if answer not in ['y', 'Y']:
+ sys.stderr.write('\nACTION [terminate] aborted by user!\n')
+ exit(1)
+
+ if 'update' == args.action and not args.force:
+ answer = raw_input("This is destructive and could corrupt {} environment. Continue? [y/N] ".format(args.cluster_id))
+ if answer not in ['y', 'Y']:
+ sys.stderr.write('\nACTION [update] aborted by user!\n')
+ exit(1)
+
+ status = args.func(args)
+ if status != 0:
+ sys.stderr.write("ACTION [{}] failed with exit status {}\n".format(args.action, status))
+ exit(status)
diff --git a/bin/ohi b/bin/ohi
new file mode 100755
index 000000000..408961ee4
--- /dev/null
+++ b/bin/ohi
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# 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
+
+CONFIG_MAIN_SECTION = 'main'
+CONFIG_HOST_TYPE_ALIAS_SECTION = 'host_type_aliases'
+CONFIG_INVENTORY_OPTION = 'inventory'
+
+class Ohi(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
+
+ hosts = None
+ if self.args.host_type is not None and \
+ self.args.env is not None:
+ # Both env and host-type specified
+ hosts = self.aws.get_host_list(host_type=self.args.host_type, \
+ env=self.args.env)
+
+ if self.args.host_type is None and \
+ self.args.env is not None:
+ # Only env specified
+ hosts = self.aws.get_host_list(env=self.args.env)
+
+ if self.args.host_type is not None and \
+ self.args.env is None:
+ # Only host-type specified
+ hosts = self.aws.get_host_list(host_type=self.args.host_type)
+
+ if hosts is None:
+ # We weren't able to determine what they wanted to do
+ raise ArgumentError("Invalid combination of arguments")
+
+ for host in hosts:
+ print host
+ return 0
+
+ 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 Host Inventory')
+
+ 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",
+ help="Which host type to use")
+
+ 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:
+ ohi = Ohi()
+ exitcode = ohi.run()
+ sys.exit(exitcode)
+ except ArgumentError as e:
+ print "\nError: %s\n" % e.message
diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec
new file mode 100644
index 000000000..c7db6f684
--- /dev/null
+++ b/bin/openshift-ansible-bin.spec
@@ -0,0 +1,65 @@
+Summary: OpenShift Ansible Scripts for working with metadata hosts
+Name: openshift-ansible-bin
+Version: 0.0.8
+Release: 1%{?dist}
+License: ASL 2.0
+URL: https://github.com/openshift/openshift-ansible
+Source0: %{name}-%{version}.tar.gz
+Requires: python2, openshift-ansible-inventory
+BuildRequires: python2-devel
+BuildArch: noarch
+
+%description
+Scripts to make it nicer when working with hosts that are defined only by metadata.
+
+%prep
+%setup -q
+
+%build
+
+%install
+mkdir -p %{buildroot}%{_bindir}
+mkdir -p %{buildroot}%{python_sitelib}/openshift_ansible
+mkdir -p %{buildroot}/etc/bash_completion.d
+mkdir -p %{buildroot}/etc/openshift_ansible
+
+cp -p ossh oscp opssh ohi %{buildroot}%{_bindir}
+cp -p openshift_ansible/* %{buildroot}%{python_sitelib}/openshift_ansible
+cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d
+
+cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshift_ansible.conf
+
+%files
+%{_bindir}/*
+%{python_sitelib}/openshift_ansible/
+/etc/bash_completion.d/*
+%config(noreplace) /etc/openshift_ansible/
+
+%changelog
+* Mon Apr 13 2015 Thomas Wiest <twiest@redhat.com> 0.0.8-1
+- fixed bug in opssh where it wouldn't actually run pssh (twiest@redhat.com)
+
+* Mon Apr 13 2015 Thomas Wiest <twiest@redhat.com> 0.0.7-1
+- added the ability to run opssh and ohi on all hosts in an environment, as
+ well as all hosts of the same host-type regardless of environment
+ (twiest@redhat.com)
+- added ohi (twiest@redhat.com)
+* Thu Apr 09 2015 Thomas Wiest <twiest@redhat.com> 0.0.6-1
+- fixed bug where opssh would throw an exception if pssh returned a non-zero
+ exit code (twiest@redhat.com)
+
+* Wed Apr 08 2015 Thomas Wiest <twiest@redhat.com> 0.0.5-1
+- fixed the opssh default output behavior to be consistent with pssh. Also
+ fixed a bug in how directories are named for --outdir and --errdir.
+ (twiest@redhat.com)
+* Tue Mar 31 2015 Thomas Wiest <twiest@redhat.com> 0.0.4-1
+- Fixed when tag was missing and added opssh completion (kwoodson@redhat.com)
+
+* Mon Mar 30 2015 Thomas Wiest <twiest@redhat.com> 0.0.3-1
+- created a python package named openshift_ansible (twiest@redhat.com)
+
+* Mon Mar 30 2015 Thomas Wiest <twiest@redhat.com> 0.0.2-1
+- added config file support to opssh, ossh, and oscp (twiest@redhat.com)
+* Tue Mar 24 2015 Thomas Wiest <twiest@redhat.com> 0.0.1-1
+- new package built with tito
+
diff --git a/bin/openshift_ansible.conf.example b/bin/openshift_ansible.conf.example
new file mode 100644
index 000000000..e891b855a
--- /dev/null
+++ b/bin/openshift_ansible.conf.example
@@ -0,0 +1,6 @@
+#[main]
+#inventory = /usr/share/ansible/inventory/multi_ec2.py
+
+#[host_type_aliases]
+#host-type-one = aliasa,aliasb
+#host-type-two = aliasfortwo
diff --git a/bin/openshift_ansible/__init__.py b/bin/openshift_ansible/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/bin/openshift_ansible/__init__.py
diff --git a/bin/awsutil.py b/bin/openshift_ansible/awsutil.py
index 37259b946..65b269930 100644
--- a/bin/awsutil.py
+++ b/bin/openshift_ansible/awsutil.py
@@ -5,28 +5,36 @@ import os
import json
import re
+class ArgumentError(Exception):
+ def __init__(self, message):
+ self.message = message
+
class AwsUtil(object):
- def __init__(self):
- self.host_type_aliases = {
- 'legacy-openshift-broker': ['broker', 'ex-srv'],
- 'openshift-node': ['node', 'ex-node'],
- 'openshift-messagebus': ['msg'],
- 'openshift-customer-database': ['mongo'],
- 'openshift-website-proxy': ['proxy'],
- 'openshift-community-website': ['drupal'],
- 'package-mirror': ['mirror'],
- }
+ def __init__(self, inventory_path=None, host_type_aliases={}):
+ self.host_type_aliases = host_type_aliases
+ self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)))
+
+ if inventory_path is None:
+ inventory_path = os.path.realpath(os.path.join(self.file_path, \
+ '..', '..', 'inventory', \
+ 'multi_ec2.py'))
+
+ if not os.path.isfile(inventory_path):
+ raise Exception("Inventory file not found [%s]" % inventory_path)
+ self.inventory_path = inventory_path
+ self.setup_host_type_alias_lookup()
+
+ def setup_host_type_alias_lookup(self):
self.alias_lookup = {}
for key, values in self.host_type_aliases.iteritems():
for value in values:
self.alias_lookup[value] = key
- self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)))
- self.multi_ec2_path = os.path.realpath(os.path.join(self.file_path, '..','inventory','multi_ec2.py'))
+
def get_inventory(self,args=[]):
- cmd = [self.multi_ec2_path]
+ cmd = [self.inventory_path]
if args:
cmd.extend(args)
@@ -124,15 +132,45 @@ class AwsUtil(object):
return self.alias_lookup[host_type]
return host_type
+ def gen_env_tag(self, env):
+ """Generate the environment tag
+ """
+ return "tag_environment_%s" % env
+
+ def gen_host_type_tag(self, host_type):
+ """Generate the host type tag
+ """
+ host_type = self.resolve_host_type(host_type)
+ return "tag_host-type_%s" % host_type
+
def gen_env_host_type_tag(self, host_type, env):
"""Generate the environment host type tag
"""
host_type = self.resolve_host_type(host_type)
return "tag_env-host-type_%s-%s" % (env, host_type)
- def get_host_list(self, host_type, env):
+ def get_host_list(self, host_type=None, env=None):
"""Get the list of hosts from the inventory using host-type and environment
"""
inv = self.get_inventory()
- host_type_tag = self.gen_env_host_type_tag(host_type, env)
- return inv[host_type_tag]
+
+ if host_type is not None and \
+ env is not None:
+ # Both host type and environment were specified
+ env_host_type_tag = self.gen_env_host_type_tag(host_type, env)
+ return inv[env_host_type_tag]
+
+ if host_type is None and \
+ env is not None:
+ # Just environment was specified
+ host_type_tag = self.gen_env_tag(env)
+ return inv[host_type_tag]
+
+ if host_type is not None and \
+ env is None:
+ # Just host-type was specified
+ host_type_tag = self.gen_host_type_tag(host_type)
+ return inv[host_type_tag]
+
+ # We should never reach here!
+ raise ArgumentError("Invalid combination of parameters")
diff --git a/bin/opssh b/bin/opssh
index 71e5bf9f2..a4fceb6a8 100755
--- a/bin/opssh
+++ b/bin/opssh
@@ -2,7 +2,6 @@
# vim: expandtab:tabstop=4:shiftwidth=4
import argparse
-import awsutil
import traceback
import sys
import os
@@ -10,54 +9,71 @@ import re
import tempfile
import time
import subprocess
+import ConfigParser
-DEFAULT_PSSH_PAR=200
+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__)))
- self.aws = awsutil.AwsUtil()
+
+ # 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
+ return 0
- if self.args.env and \
- self.args.host_type and \
- self.args.command:
- retval = self.run_pssh()
- if retval != 0:
- raise ValueError("pssh run failed")
+ if self.args.host_type is not None or \
+ self.args.env is not None:
+ return self.run_pssh()
- return
-
- # If it makes it here, we weren't able to determine what they wanted to do
- raise ValueError("Invalid combination of arguments")
+ # 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, '-i', '-t', '0', '-p', str(self.args.par), '--user', self.args.user]
+ 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.append("--outdir='%s'" % self.args.outdir)
+ pssh_args.extend(["--outdir", self.args.outdir])
if self.args.errdir:
- pssh_args.append("--errdir='%s'" % 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)
- hosts = self.aws.get_host_list(self.args.host_type, 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", "%s" % f.name])
- pssh_args.append("%s" % self.args.command)
+ pssh_args.extend(["-h", f.name])
+ pssh_args.append(self.args.command)
print
print "Running: %s" % ' '.join(pssh_args)
@@ -66,6 +82,20 @@ class Opssh(object):
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
@@ -79,7 +109,7 @@ class Opssh(object):
parser.add_argument('-e', '--env', action="store",
help="Which environment to use")
- parser.add_argument('-t', '--host-type', action="store",
+ parser.add_argument('-t', '--host-type', action="store", default=None,
help="Which host type to use")
parser.add_argument('-c', '--command', action='store',
@@ -88,6 +118,9 @@ class Opssh(object):
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))
@@ -107,5 +140,7 @@ if __name__ == '__main__':
try:
opssh = Opssh()
- except ValueError as e:
+ exitcode = opssh.run()
+ sys.exit(exitcode)
+ except ArgumentError as e:
print "\nError: %s\n" % e.message
diff --git a/bin/oscp b/bin/oscp
index 146bbbea5..461ad0a0f 100755
--- a/bin/oscp
+++ b/bin/oscp
@@ -2,21 +2,34 @@
# vim: expandtab:tabstop=4:shiftwidth=4
import argparse
-import awsutil
import traceback
import sys
import os
import re
+import ConfigParser
+
+from openshift_ansible import awsutil
+
+CONFIG_MAIN_SECTION = 'main'
+CONFIG_INVENTORY_OPTION = 'inventory'
class Oscp(object):
def __init__(self):
+ self.inventory = None
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()
# parse host and user
self.process_host()
- self.aws = awsutil.AwsUtil()
+ self.aws = awsutil.AwsUtil(self.inventory)
# get a dict of host inventory
if self.args.list:
@@ -38,9 +51,18 @@ class Oscp(object):
else:
self.scp()
+ 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)
+
def parse_cli_args(self):
parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.')
- parser.add_argument('-e', '--env',
+ parser.add_argument('-e', '--env',
action="store", help="Environment where this server exists.")
parser.add_argument('-d', '--debug', default=False,
action="store_true", help="debug mode")
diff --git a/bin/ossh b/bin/ossh
index 66a4cfb5c..c16ea6eda 100755
--- a/bin/ossh
+++ b/bin/ossh
@@ -2,18 +2,31 @@
# vim: expandtab:tabstop=4:shiftwidth=4
import argparse
-import awsutil
import traceback
import sys
import os
import re
+import ConfigParser
+
+from openshift_ansible import awsutil
+
+CONFIG_MAIN_SECTION = 'main'
+CONFIG_INVENTORY_OPTION = 'inventory'
class Ossh(object):
def __init__(self):
+ self.inventory = None
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.aws = awsutil.AwsUtil(self.inventory)
# get a dict of host inventory
if self.args.list:
@@ -37,6 +50,15 @@ class Ossh(object):
else:
self.ssh()
+ 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)
+
def parse_cli_args(self):
parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.')
parser.add_argument('-e', '--env', action="store",
diff --git a/bin/ossh_bash_completion b/bin/ossh_bash_completion
index 6a95ce6ee..1467de858 100755
--- a/bin/ossh_bash_completion
+++ b/bin/ossh_bash_completion
@@ -1,6 +1,7 @@
__ossh_known_hosts(){
if [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then
- /usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items()])'
+ /usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])'
+
fi
}
@@ -16,3 +17,23 @@ _ossh()
return 0
}
complete -F _ossh ossh oscp
+
+__opssh_known_hosts(){
+ if [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then
+ /usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s" % (host["ec2_tag_host-type"]) for dns, host in z["_meta"]["hostvars"].items() if "ec2_tag_host-type" in host])'
+ fi
+}
+
+_opssh()
+{
+ local cur prev known_hosts
+ COMPREPLY=()
+ cur="${COMP_WORDS[COMP_CWORD]}"
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
+ known_hosts="$(__opssh_known_hosts)"
+ COMPREPLY=( $(compgen -W "${known_hosts}" -- ${cur}))
+
+ return 0
+}
+complete -F _opssh opssh
+