ossh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #!/usr/bin/env python
  2. # vim: expandtab:tabstop=4:shiftwidth=4
  3. import argparse
  4. import ansibleutil
  5. import traceback
  6. import sys
  7. import os
  8. import re
  9. class Ossh(object):
  10. def __init__(self):
  11. self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)))
  12. self.parse_cli_args()
  13. self.ansible = ansibleutil.AnsibleUtil()
  14. # get a dict of host inventory
  15. if self.args.list:
  16. self.get_hosts()
  17. else:
  18. self.get_hosts(True)
  19. # parse host and user
  20. self.process_host()
  21. if not self.args.list and not self.env:
  22. print "Please specify an environment."
  23. return
  24. if self.args.host == '' and not self.args.list:
  25. self.parser.print_help()
  26. return
  27. if self.args.debug:
  28. print self.args
  29. # perform the SSH
  30. if self.args.list:
  31. self.list_hosts()
  32. else:
  33. self.ssh()
  34. def parse_cli_args(self):
  35. parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.')
  36. parser.add_argument('-e', '--env', action="store",
  37. help="Which environment to search for the host ")
  38. parser.add_argument('-d', '--debug', default=False,
  39. action="store_true", help="debug mode")
  40. parser.add_argument('-v', '--verbose', default=False,
  41. action="store_true", help="Verbose?")
  42. parser.add_argument('--list', default=False,
  43. action="store_true", help="list out hosts")
  44. parser.add_argument('-c', '--command', action='store',
  45. help='Command to run on remote host')
  46. parser.add_argument('-l', '--login_name', action='store',
  47. help='User in which to ssh as')
  48. parser.add_argument('-o', '--ssh_opts', action='store',
  49. help='options to pass to SSH.\n \
  50. "-oForwardX11=yes,TCPKeepAlive=yes"')
  51. parser.add_argument('host', nargs='?', default='')
  52. self.args = parser.parse_args()
  53. self.parser = parser
  54. def process_host(self):
  55. '''Determine host name and user name for SSH.
  56. '''
  57. self.env = None
  58. self.user = None
  59. re_env = re.compile("\.(" + "|".join(self.host_inventory.keys()) + ")")
  60. search = re_env.search(self.args.host)
  61. if self.args.env:
  62. self.env = self.args.env
  63. elif search:
  64. # take the first?
  65. self.env = search.groups()[0]
  66. # remove env from hostname command line arg if found
  67. if search:
  68. self.args.host = re_env.split(self.args.host)[0]
  69. # parse username if passed
  70. if '@' in self.args.host:
  71. self.user, self.host = self.args.host.split('@')
  72. else:
  73. self.host = self.args.host
  74. if self.args.login_name:
  75. self.user = self.args.login_name
  76. def get_hosts(self, cache_only=False):
  77. '''Query our host inventory and return a dict where the format
  78. equals:
  79. dict['servername'] = dns_name
  80. '''
  81. if cache_only:
  82. self.host_inventory = self.ansible.build_host_dict_by_env(['--cache-only'])
  83. else:
  84. self.host_inventory = self.ansible.build_host_dict_by_env()
  85. def select_host(self):
  86. '''select host attempts to match the host specified
  87. on the command line with a list of hosts.
  88. '''
  89. results = []
  90. for env in self.host_inventory.keys():
  91. for hostname, server_info in self.host_inventory[env].items():
  92. if hostname.split(':')[0] == self.host:
  93. results.append((hostname, server_info))
  94. # attempt to select the correct environment if specified
  95. if self.env:
  96. results = filter(lambda result: result[1]['ec2_tag_environment'] == self.env, results)
  97. if results:
  98. return results
  99. else:
  100. print "Could not find specified host: %s." % self.host
  101. # default - no results found.
  102. return None
  103. def list_hosts(self, limit=None):
  104. '''Function to print out the host inventory.
  105. Takes a single parameter to limit the number of hosts printed.
  106. '''
  107. if self.env:
  108. results = self.select_host()
  109. if len(results) == 1:
  110. hostname, server_info = results[0]
  111. sorted_keys = server_info.keys()
  112. sorted_keys.sort()
  113. for key in sorted_keys:
  114. print '{0:<35} {1}'.format(key, server_info[key])
  115. else:
  116. for host_id, server_info in results[:limit]:
  117. name = server_info['ec2_tag_Name']
  118. ec2_id = server_info['ec2_id']
  119. ip = server_info['ec2_ip_address']
  120. print '{ec2_tag_Name:<35} {ec2_tag_environment:<8} {ec2_id:<15} {ec2_ip_address}'.format(**server_info)
  121. if limit:
  122. print
  123. print 'Showing only the first %d results...' % limit
  124. print
  125. else:
  126. for env, host_ids in self.host_inventory.items():
  127. for host_id, server_info in host_ids.items():
  128. name = server_info['ec2_tag_Name']
  129. ec2_id = server_info['ec2_id']
  130. ip = server_info['ec2_ip_address']
  131. print '{ec2_tag_Name:<35} {ec2_tag_environment:<5} {ec2_id:<15} {ec2_ip_address}'.format(**server_info)
  132. def ssh(self):
  133. '''SSH to a specified host
  134. '''
  135. try:
  136. # shell args start with the program name in position 1
  137. ssh_args = ['/usr/bin/ssh']
  138. if self.user:
  139. ssh_args.append('-l%s' % self.user)
  140. if self.args.verbose:
  141. ssh_args.append('-vvv')
  142. if self.args.ssh_opts:
  143. for arg in self.args.ssh_opts.split(","):
  144. ssh_args.append("-o%s" % arg)
  145. result = self.select_host()
  146. if not result:
  147. return # early exit, no results
  148. if len(result) > 1:
  149. self.list_hosts(10)
  150. return # early exit, too many results
  151. # Assume we have one and only one.
  152. hostname, server_info = result[0]
  153. dns = server_info['ec2_public_dns_name']
  154. ssh_args.append(dns)
  155. #last argument
  156. if self.args.command:
  157. ssh_args.append("%s" % self.args.command)
  158. print "Running: %s\n" % ' '.join(ssh_args)
  159. os.execve('/usr/bin/ssh', ssh_args, os.environ)
  160. except:
  161. print traceback.print_exc()
  162. print sys.exc_info()
  163. if __name__ == '__main__':
  164. ossh = Ossh()