123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- #!/usr/bin/env python
- import pdb
- import argparse
- import ansibleutil
- import traceback
- import sys
- import os
- import re
- # use dynamic inventory
- # list instances
- # symlinked to ~/bin
- # 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):
- self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)))
- self.parse_cli_args()
- # parse host and user
- self.process_host()
- if not self.args.list and not self.env:
- print "Please specify an environment."
- return
- if self.args.host == '' and not self.args.list:
- self.parser.print_help()
- return
- self.ansible = ansibleutil.AnsibleUtil()
- self.host_inventory = self.get_hosts()
- if self.args.debug:
- print self.args
- # get a dict of host inventory
- self.get_hosts()
- # 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('-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('-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"')
- parser.add_argument('host', nargs='?', default='')
- self.args = parser.parse_args()
- self.parser = parser
- 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
- 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):
- '''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()
- if __name__ == '__main__':
- main()
|