From 0457b96cd5b5252010208ee8f74d0a3da49573b2 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Thu, 8 Jan 2015 12:39:33 -0500 Subject: added opssh.py --- inventory/multi_ec2.py | 1 + 1 file changed, 1 insertion(+) (limited to 'inventory') diff --git a/inventory/multi_ec2.py b/inventory/multi_ec2.py index d8c2dc854..c60bb50d2 100755 --- a/inventory/multi_ec2.py +++ b/inventory/multi_ec2.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# vim: expandtab:tabstop=4:shiftwidth=4 from time import time import argparse -- cgit v1.2.3 From ee96928a2d1c21c5d2319418f4cf6ca774a3e010 Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Thu, 5 Feb 2015 16:02:36 -0500 Subject: Attempting to only refresh cache when doing --list on ossh. --- bin/ansibleutil.py | 10 +++++++--- bin/ossh | 18 +++++++++++------- inventory/aws/ec2.ini | 4 ++-- inventory/multi_ec2.py | 15 ++++++++++++++- 4 files changed, 34 insertions(+), 13 deletions(-) (limited to 'inventory') diff --git a/bin/ansibleutil.py b/bin/ansibleutil.py index ed35ef8f9..6df3e7126 100644 --- a/bin/ansibleutil.py +++ b/bin/ansibleutil.py @@ -11,8 +11,12 @@ class AnsibleUtil(object): 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): + def get_inventory(self,args=[]): cmd = [self.multi_ec2_path] + + if args: + cmd.extend(args) + env = {} p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, env=env) @@ -50,8 +54,8 @@ class AnsibleUtil(object): return groups - def build_host_dict(self): - inv = self.get_inventory() + def build_host_dict(self, args=[]): + inv = self.get_inventory(args) inst_by_env = {} for dns, host in inv['_meta']['hostvars'].items(): diff --git a/bin/ossh b/bin/ossh index 7f7acc6c2..1fa987d21 100755 --- a/bin/ossh +++ b/bin/ossh @@ -39,15 +39,15 @@ class Ossh(object): self.ansible = ansibleutil.AnsibleUtil() - self.host_inventory = self.get_hosts() + # get a dict of host inventory + if self.args.list: + self.get_hosts() + else: + self.get_hosts(True) 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() @@ -106,7 +106,7 @@ class Ossh(object): if self.args.login_name: self.user = self.args.login_name - def get_hosts(self): + def get_hosts(self, cache=False): '''Query our host inventory and return a dict where the format equals: @@ -114,7 +114,11 @@ class Ossh(object): ''' # TODO: perform a numerical sort on these hosts # and display them - self.host_inventory = self.ansible.build_host_dict() + + if not cache: + self.host_inventory = self.ansible.build_host_dict() + else: + self.host_inventory = self.ansible.build_host_dict(['--cache-only']) def select_host(self, regex=False): '''select host attempts to match the host specified diff --git a/inventory/aws/ec2.ini b/inventory/aws/ec2.ini index c6693bb1c..cdc22d2d4 100644 --- a/inventory/aws/ec2.ini +++ b/inventory/aws/ec2.ini @@ -11,8 +11,8 @@ # AWS regions to make calls to. Set this to 'all' to make request to all regions # in AWS and merge the results together. Alternatively, set this to a comma # separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2' -#regions = all -regions = us-east-1 +regions = all +#regions = us-east-1 regions_exclude = us-gov-west-1,cn-north-1 # When generating inventory, Ansible needs to know how to address a server. diff --git a/inventory/multi_ec2.py b/inventory/multi_ec2.py index c60bb50d2..499264267 100755 --- a/inventory/multi_ec2.py +++ b/inventory/multi_ec2.py @@ -43,9 +43,15 @@ class MultiEc2(object): else: raise RuntimeError("Could not find valid ec2 credentials in the environment.") + if self.args.cache_only: + # get data from disk + result = self.get_inventory_from_cache() + if not result: + self.get_inventory() + self.write_to_cache() # if its a host query, fetch and do not cache - if self.args.host: + elif self.args.host: self.get_inventory() elif not self.is_cache_valid(): # go fetch the inventories and cache them if cache is expired @@ -186,6 +192,8 @@ class MultiEc2(object): ''' Command line argument processing ''' parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on a provider') + parser.add_argument('--cache-only', action='store_true', default=False, + help='Fetch cached only instances (default: False)') parser.add_argument('--list', action='store_true', default=True, help='List instances (default: True)') parser.add_argument('--host', action='store', default=False, @@ -203,9 +211,14 @@ class MultiEc2(object): ''' Reads the inventory from the cache file and returns it as a JSON object ''' + if not os.path.isfile(self.cache_path): + return None + with open(self.cache_path, 'r') as cache: self.result = json.loads(cache.read()) + return True + def json_format_dict(self, data, pretty=False): ''' Converts a dict to a JSON object and dumps it as a formatted string ''' -- cgit v1.2.3 From cedef18d9450a1b3c8c0f72c10174735529cda04 Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Thu, 5 Feb 2015 17:01:06 -0500 Subject: Removed comments and cleaned up code. --- bin/README_SHELL_COMPLETION | 11 ++++--- bin/ansibleutil.py | 2 -- bin/opssh.py | 66 --------------------------------------- bin/ossh | 75 +++++++++++++-------------------------------- inventory/aws/ec2.ini | 1 - 5 files changed, 28 insertions(+), 127 deletions(-) delete mode 100755 bin/opssh.py (limited to 'inventory') diff --git a/bin/README_SHELL_COMPLETION b/bin/README_SHELL_COMPLETION index 0183544e6..e17b4b205 100644 --- a/bin/README_SHELL_COMPLETION +++ b/bin/README_SHELL_COMPLETION @@ -1,7 +1,7 @@ # ossh is an ssh replacement. -Ossh uses a dynamic inventory cache in order to lookup hostnames and translate them +ossh uses a dynamic inventory cache in order to lookup hostnames and translate them to something meaningful such as an IP address or dns name. This allows us to treat our servers as cattle and not as pets. @@ -13,9 +13,10 @@ You can populate the cache by running `ossh --list`. This will populate the cache file and the completions should become available. -This zsh script will look at the cached version of your -multi_ec2 results in ~/.ansible/tmp/. It will then parse a few -{host}.{env} out of the json and return them to be completable. +This script will look at the cached version of your +multi_ec2 results in ~/.ansible/tmp/multi_ec2_inventory.cache. +It will then parse a few {host}.{env} out of the json +and return them to be completable. # BASH In order to setup bash completion, source the following script: @@ -27,6 +28,6 @@ that the _ossh_zsh_completion script is somewhere in the path of $fpath. Once $fpath includes the _ossh_zsh_completion script then you should -run `exec zsh`. This will then allow you to call `ossh host[TAB]` +run `exec zsh`. This will then allow you to call `ossh host[TAB]` for a list of completions. diff --git a/bin/ansibleutil.py b/bin/ansibleutil.py index 6df3e7126..b12b7b447 100644 --- a/bin/ansibleutil.py +++ b/bin/ansibleutil.py @@ -26,8 +26,6 @@ class AnsibleUtil(object): if p.returncode != 0: raise RuntimeError(err) - #with open('/tmp/ans.out','w') as fd: - #fd.writelines(out) return json.loads(out.strip()) def get_environments(self): diff --git a/bin/opssh.py b/bin/opssh.py deleted file mode 100755 index 6ee390c4c..000000000 --- a/bin/opssh.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -# vim: expandtab:tabstop=4:shiftwidth=4 - -import argparse -import os -import ansibleutil -import sys - -class Program(object): - def __init__(self): - self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) - self.parse_cli_args() - self.ansible = ansibleutil.AnsibleUtil() - - inv = self.ansible.get_inventory() - #print inv.keys() - #sys.exit() - - if self.args.list_environments: - self.list_environments() - sys.exit() - - if self.args.list_groups: - self.list_security_groups() - sys.exit() - - def parse_cli_args(self): - parser = argparse.ArgumentParser( - description='OpenShift Online Operations Parallel SSH' - ) - - parser.add_argument("-v", '--verbosity', action="count", - help="increase output verbosity") - - group = parser.add_mutually_exclusive_group() - - group.add_argument('--list-environments', action="store_true", - help='List all environments') - group.add_argument('--list-groups', action="store_true", - help='List all security groups') - group.add_argument('-e', '--environment', - help='Set the environment') - - self.args = parser.parse_args() - - def list_environments(self): - envs = self.ansible.get_environments() - print - print "Environments" - print "------------" - for env in envs: - print env - print - - def list_security_groups(self): - envs = self.ansible.get_security_groups() - print - print "Groups" - print "------" - for env in envs: - print env - print - - -if __name__ == '__main__': - p = Program() diff --git a/bin/ossh b/bin/ossh index 1fa987d21..f41eedadf 100755 --- a/bin/ossh +++ b/bin/ossh @@ -1,6 +1,6 @@ #!/usr/bin/env python +# vim: expandtab:tabstop=4:shiftwidth=4 -import pdb import argparse import ansibleutil import traceback @@ -8,24 +8,19 @@ 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() + self.ansible = ansibleutil.AnsibleUtil() + + # get a dict of host inventory + if self.args.list: + self.get_hosts() + else: + self.get_hosts(True) + # parse host and user self.process_host() @@ -37,13 +32,6 @@ class Ossh(object): self.parser.print_help() return - self.ansible = ansibleutil.AnsibleUtil() - - # get a dict of host inventory - if self.args.list: - self.get_hosts() - else: - self.get_hosts(True) if self.args.debug: print self.args @@ -56,8 +44,6 @@ class Ossh(object): 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, @@ -73,7 +59,7 @@ class Ossh(object): parser.add_argument('-o', '--ssh_opts', action='store', help='options to pass to SSH.\n \ - "-o ForwardX11 yes"') + "-oForwardX11=yes,TCPKeepAlive=yes"') parser.add_argument('host', nargs='?', default='') self.args = parser.parse_args() @@ -86,7 +72,7 @@ class Ossh(object): self.env = None self.user = None - re_env = re.compile('\.(int|stg|prod|ops)') + re_env = re.compile("\.(" + "|".join(self.host_inventory.keys()) + ")") search = re_env.search(self.args.host) if self.args.env: self.env = self.args.env @@ -106,19 +92,16 @@ class Ossh(object): if self.args.login_name: self.user = self.args.login_name - def get_hosts(self, cache=False): + def get_hosts(self, cache_only=False): '''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 - - if not cache: - self.host_inventory = self.ansible.build_host_dict() - else: + if cache_only: self.host_inventory = self.ansible.build_host_dict(['--cache-only']) + else: + self.host_inventory = self.ansible.build_host_dict() def select_host(self, regex=False): '''select host attempts to match the host specified @@ -127,25 +110,17 @@ class Ossh(object): 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 + # an exact match, return it! + return [(hostname, server_info)] elif re_host.search(hostname): results.append((hostname, server_info)) - if exact: - return exact - elif results: + if results: return results else: print "Could not find specified host: %s in %s" % (self.host, self.env) @@ -153,7 +128,6 @@ class Ossh(object): # default - no results found. return None - def list_hosts(self, limit=None): '''Function to print out the host inventory. @@ -192,10 +166,8 @@ class Ossh(object): '''SSH to a specified host ''' try: - cmd = '/usr/bin/ssh' - # shell args start with the program name in position 1 - ssh_args = [cmd, ] + ssh_args = ['/usr/bin/ssh'] if self.user: ssh_args.append('-l%s' % self.user) @@ -204,7 +176,8 @@ class Ossh(object): ssh_args.append('-vvv') if self.args.ssh_opts: - ssh_args.append("-o%s" % self.args.ssh_opts) + for arg in self.args.ssh_opts.split(","): + ssh_args.append("-o%s" % arg) result = self.select_host() if not result: @@ -235,10 +208,6 @@ class Ossh(object): print sys.exc_info() -def main(): - ossh = Ossh() - - if __name__ == '__main__': - main() + ossh = Ossh() diff --git a/inventory/aws/ec2.ini b/inventory/aws/ec2.ini index cdc22d2d4..8a0c3ad45 100644 --- a/inventory/aws/ec2.ini +++ b/inventory/aws/ec2.ini @@ -12,7 +12,6 @@ # in AWS and merge the results together. Alternatively, set this to a comma # separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2' regions = all -#regions = us-east-1 regions_exclude = us-gov-west-1,cn-north-1 # When generating inventory, Ansible needs to know how to address a server. -- cgit v1.2.3