summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorKenny Woodson <kwoodson@redhat.com>2015-02-03 15:08:26 -0500
committerKenny Woodson <kwoodson@redhat.com>2015-02-03 15:08:26 -0500
commit6481ca629cc2bcf5bd9c7f15be14a77e57086514 (patch)
treebe8f5580f34630127ff83b5cfa9de1a31c1f3db9 /bin
parentd3dee2db1c87b074075b3bbcbe8931862ee7eca3 (diff)
downloadopenshift-6481ca629cc2bcf5bd9c7f15be14a77e57086514.tar.gz
openshift-6481ca629cc2bcf5bd9c7f15be14a77e57086514.tar.bz2
openshift-6481ca629cc2bcf5bd9c7f15be14a77e57086514.tar.xz
openshift-6481ca629cc2bcf5bd9c7f15be14a77e57086514.zip
ossh script added for ssh meta query capabilities
Diffstat (limited to 'bin')
-rw-r--r--bin/ansibleutil.py22
-rwxr-xr-xbin/ossh.py195
2 files changed, 202 insertions, 15 deletions
diff --git a/bin/ansibleutil.py b/bin/ansibleutil.py
index a16a4dca9..26fb25493 100644
--- a/bin/ansibleutil.py
+++ b/bin/ansibleutil.py
@@ -22,8 +22,8 @@ class AnsibleUtil(object):
if p.returncode != 0:
raise RuntimeError(err)
- with open('/tmp/ans.out','w') as fd:
- fd.writelines(out)
+ #with open('/tmp/ans.out','w') as fd:
+ #fd.writelines(out)
return json.loads(out.strip())
def get_environments(self):
@@ -50,18 +50,22 @@ class AnsibleUtil(object):
return groups
- def get_host_address(self):
- pattern = re.compile(r'^tag_Name_(.*)')
+ def build_host_dict(self):
inv = self.get_inventory()
- inst_names = {}
- for key in inv.keys():
- m = pattern.match(key)
- if m: inst_names[m.group(1)] = inv[key]
+ inst_by_env = {}
+ for dns, host in inv['_meta']['hostvars'].items():
+ if host['ec2_tag_environment'] not in inst_by_env:
+ inst_by_env[host['ec2_tag_environment']] = {}
+
+ #if inst_by_env[host['ec2_tag_environment']][host['ec2_tag_Name']]:
+ #raise Exception('Duplicate ec2_tag_Name found: %s' % host['ec2_tag_Name'])
+ host_id = "%s:%s" % (host['ec2_tag_Name'],host['ec2_id'])
+ inst_by_env[host['ec2_tag_environment']][host_id] = host
- return inst_names
+ return inst_by_env
diff --git a/bin/ossh.py b/bin/ossh.py
index 2a24e807d..d0f4a1475 100755
--- a/bin/ossh.py
+++ b/bin/ossh.py
@@ -1,9 +1,12 @@
#!/usr/bin/env python
+import pdb
import argparse
import ansibleutil
+import traceback
import sys
import os
+import re
# use dynamic inventory
@@ -12,6 +15,11 @@ import os
# list instances that match pattern
# python!
+# list environment stuff as well
+# 3 states:
+# - an exact match; return result
+# - a partial match; return all regex results
+# - no match; None
class Ossh(object):
def __init__(self):
@@ -19,22 +27,197 @@ class Ossh(object):
self.parse_cli_args()
self.ansible = ansibleutil.AnsibleUtil()
- self.list_hosts()
-
+ self.host_inventory = self.get_hosts()
+
+
+ if self.args.debug:
+ print self.args
+
+ # get a dict of host inventory
+ self.get_hosts()
+
+ # parse host and user
+ self.process_host()
+
+ # perform the SSH
+ if self.args.list:
+ self.list_hosts()
+ else:
+ self.ssh()
+
def parse_cli_args(self):
parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.')
- parser.add_argument('-l', '--list', default=True,
+ parser.add_argument('-r', '--random', action="store",
+ help="Choose a random host")
+ parser.add_argument('-e', '--env', action="store",
+ help="Which environment to search for the host ")
+ parser.add_argument('-d', '--debug', default=False,
+ action="store_true", help="debug mode")
+ parser.add_argument('-v', '--verbose', default=False,
+ action="store_true", help="Verbose?")
+ parser.add_argument('--list', default=False,
action="store_true", help="list out hosts")
+ parser.add_argument('host')
+ parser.add_argument('-c', '--command', action='store',
+ help='Command to run on remote host')
+ parser.add_argument('-l', '--login_name', action='store',
+ help='User in which to ssh as')
+
+ parser.add_argument('-o', '--ssh_opts', action='store',
+ help='options to pass to SSH.\n \
+ "-o ForwardX11 yes"')
self.args = parser.parse_args()
- def list_hosts(self):
+ def process_host(self):
+ '''Determine host name and user name for SSH.
+ '''
+ self.env = None
+
+ re_env = re.compile('\.(int|stg|prod|ops)')
+ search = re_env.search(self.args.host)
+ if self.args.env:
+ self.env = self.args.env
+ elif search:
+ # take the first?
+ self.env = search.groups()[0]
+
+ # remove env from hostname command line arg if found
+ if search:
+ self.args.host = re_env.split(self.args.host)[0]
+
+ # parse username if passed
+ if '@' in self.args.host:
+ self.user, self.host = self.args.host.split('@')
+ else:
+ self.host = self.args.host
+ if self.args.login_name:
+ self.user = self.args.login_name
+ else:
+ self.user = os.environ['USER']
+
+
+
+ def get_hosts(self):
+ '''Query our host inventory and return a dict where the format
+ equals:
+
+ dict['servername'] = dns_name
+ '''
# TODO: perform a numerical sort on these hosts
# and display them
- print self.ansible.get_host_address()
+ self.host_inventory = self.ansible.build_host_dict()
+
+ def select_host(self, regex=False):
+ '''select host attempts to match the host specified
+ on the command line with a list of hosts.
+
+ if regex is specified then we will attempt to match
+ all *{host_string}* equivalents.
+ '''
+# list environment stuff as well
+# 3 states:
+# - an exact match; return result
+# - a partial match; return all regex results
+# - no match; None
+ re_host = re.compile(self.host)
+
+ exact = []
+ results = []
+ for hostname, server_info in self.host_inventory[self.env].items():
+ if hostname.split(':')[0] == self.host:
+ exact.append((hostname, server_info))
+ break
+ elif re_host.search(hostname):
+ results.append((hostname, server_info))
+
+ if exact:
+ return exact
+ elif results:
+ return results
+ else:
+ print "Could not find specified host: %s in %s" % (self.host, self.env)
+
+ # default - no results found.
+ return None
+
+
+ def list_hosts(self, limit=None):
+ '''Function to print out the host inventory.
+
+ Takes a single parameter to limit the number of hosts printed.
+ '''
+
+ if self.env:
+ results = self.select_host(True)
+ if len(results) == 1:
+ hostname, server_info = results[0]
+ sorted_keys = server_info.keys()
+ sorted_keys.sort()
+ for key in sorted_keys:
+ print '{0:<35} {1}'.format(key, server_info[key])
+ else:
+ for host_id, server_info in results[:limit]:
+ name = server_info['ec2_tag_Name']
+ ec2_id = server_info['ec2_id']
+ ip = server_info['ec2_ip_address']
+ print '{ec2_tag_Name:<35} {ec2_tag_environment:<8} {ec2_id:<15} {ec2_ip_address}'.format(**server_info)
+
+ if limit:
+ print
+ print 'Showing only the first %d results...' % limit
+ print
+
+ else:
+ for env, host_ids in self.host_inventory.items():
+ for host_id, server_info in host_ids.items():
+ name = server_info['ec2_tag_Name']
+ ec2_id = server_info['ec2_id']
+ ip = server_info['ec2_ip_address']
+ print '{ec2_tag_Name:<35} {ec2_tag_environment:<5} {ec2_id:<15} {ec2_ip_address}'.format(**server_info)
def ssh(self):
- pass
+ '''SSH to a specified host
+ '''
+ try:
+ cmd = '/usr/bin/ssh'
+ ssh_args = [cmd, '-l%s' % self.user]
+ #ssh_args = [cmd, ]
+
+ if self.args.verbose:
+ ssh_args.append('-vvv')
+
+ if self.args.ssh_opts:
+ ssh_args.append("-o%s" % self.args.ssh_opts)
+
+ result = self.select_host()
+ if not result:
+ return # early exit, no results
+
+ if len(result) > 1:
+ self.list_hosts(10)
+ return # early exit, too many results
+
+ # Assume we have one and only one.
+ hostname, server_info = result[0]
+ ip = server_info['ec2_ip_address']
+
+ ssh_args.append(ip)
+
+ #last argument
+ if self.args.command:
+ ssh_args.append("%s" % self.args.command)
+
+ if self.args.debug:
+ print "SSH to %s in %s as %s" % (hostname, self.env, self.user)
+
+ print "Running: %s\n" % ' '.join(ssh_args)
+
+ os.execve('/usr/bin/ssh', ssh_args, os.environ)
+ except:
+ print traceback.print_exc()
+ print sys.exc_info()
+
def main():
ossh = Ossh()