diff options
Diffstat (limited to 'bin/oscp')
| -rwxr-xr-x | bin/oscp | 220 | 
1 files changed, 220 insertions, 0 deletions
| diff --git a/bin/oscp b/bin/oscp new file mode 100755 index 000000000..a139ef38e --- /dev/null +++ b/bin/oscp @@ -0,0 +1,220 @@ +#!/usr/bin/env python +# vim: expandtab:tabstop=4:shiftwidth=4 + +import argparse +import ansibleutil +import traceback +import sys +import os +import re + +class Oscp(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() + +        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.src == '' or self.args.dest == '') and not self.args.list: +            self.parser.print_help() +            return + +        if self.args.debug: +            print self.host +            print self.args + +        # perform the scp +        if self.args.list: +            self.list_hosts() +        else: +            self.scp() + +    def parse_cli_args(self): +        parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.') +        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") +        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('-r', '--recurse', action='store_true', default=False, +                            help='Recursively copy files to or from destination.') +        parser.add_argument('-o', '--ssh_opts', action='store', +                            help='options to pass to SSH.\n \ +                                  "-oPort=22,TCPKeepAlive=yes"') + +        parser.add_argument('src', nargs='?', default='') +        parser.add_argument('dest',nargs='?', default='') + +        self.args = parser.parse_args() +        self.parser = parser + + +    def process_host(self): +        '''Determine host name and user name for SSH. +        ''' +        self.user = '' + +        # is the first param passed a valid file? +        if os.path.isfile(self.args.src) or os.path.isdir(self.args.src): +            self.local_src = True +            self.host = self.args.dest +        else: +            self.local_src = False +            self.host = self.args.src + +        if '@' in self.host: +            re_host = re.compile("(.*@)(.*)(:.*$)") +        else: +            re_host = re.compile("(.*)(:.*$)") + +        search = re_host.search(self.host) + +        if search: +            if len(search.groups()) > 2: +                self.user = search.groups()[0] +                self.host = search.groups()[1] +                self.path = search.groups()[2] +            else: +                self.host = search.groups()[0] +                self.path = search.groups()[1] + +        if self.args.env: +            self.env = self.args.env +        elif "." in self.host: +            self.host, self.env = self.host.split(".") +        else: +            self.env = None + +    def get_hosts(self, cache_only=False): +        '''Query our host inventory and return a dict where the format +           equals: + +           dict['environment'] = [{'servername' : {}}, ] +        ''' +        if cache_only: +            self.host_inventory = self.ansible.build_host_dict_by_env(['--cache-only']) +        else: +            self.host_inventory = self.ansible.build_host_dict_by_env() + +    def select_host(self): +        '''select host attempts to match the host specified +           on the command line with a list of hosts. +        ''' +        results = [] +        for env in self.host_inventory.keys(): +            for hostname, server_info in self.host_inventory[env].items(): +                if hostname.split(':')[0] == self.host: +                    results.append((hostname, server_info)) + +        # attempt to select the correct environment if specified +        if self.env: +            results = filter(lambda result: result[1]['ec2_tag_environment'] == self.env, results) + +        if results: +            return results +        else: +            print "Could not find specified host: %s." % self.host + +        # 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() +            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 scp(self): +        '''scp files to or from a specified host +        ''' +        try: +            # shell args start with the program name in position 1 +            scp_args = ['/usr/bin/scp'] + +            if self.args.verbose: +                scp_args.append('-v') + +            if self.args.recurse: +                scp_args.append('-r') + +            if self.args.ssh_opts: +                for arg in self.args.ssh_opts.split(","): +                    scp_args.append("-o%s" % arg) + +            results = self.select_host() + +            if self.args.debug: print results + +            if not results: +                return # early exit, no results + +            if len(results) > 1: +                print "Multiple results found for %s." % self.host +                for result in results: +                    print "{ec2_tag_Name:<35} {ec2_tag_environment:<5} {ec2_id:<10}".format(**result[1]) +                return # early exit, too many results + +            # Assume we have one and only one. +            hostname, server_info = results[0] +            dns = server_info['ec2_public_dns_name'] + +            host_str = "%s%s%s" % (self.user, dns, self.path) + +            if self.local_src: +                scp_args.append(self.args.src) +                scp_args.append(host_str) +            else: +                scp_args.append(host_str) +                scp_args.append(self.args.dest) + +            print "Running: %s\n" % ' '.join(scp_args) + +            os.execve('/usr/bin/scp', scp_args, os.environ) +        except: +            print traceback.print_exc() +            print sys.exc_info() + + +if __name__ == '__main__': +    oscp = Oscp() + | 
