From b1817bfd9a9a2e755b66b10cf3b74c1145b8f02c Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 17 May 2013 00:39:20 +0200 Subject: Printer: refactor the whole thing, add --verbose flag to show keys with value None --- bin/hostinfo | 17 +++-- hostinfo/printer.py | 199 ++++++++++++++++++++++++++-------------------------- 2 files changed, 111 insertions(+), 105 deletions(-) diff --git a/bin/hostinfo b/bin/hostinfo index 391e7db..5a2a516 100755 --- a/bin/hostinfo +++ b/bin/hostinfo @@ -19,9 +19,9 @@ def _get_data(path): stream = file(path, 'r') return yaml.load(stream) -def print_info(path, key=None, oneline=False): +def print_info(path, key=None, oneline=False, verbose=False): data = _get_data(path) - p = printer.Printer(data, oneline) + p = printer.Printer(data, oneline, verbose) p.info(key) def _print_keys(data, prefix = ''): @@ -71,12 +71,14 @@ def find_host(host): def main(): self_name = sys.argv.pop(0) - optlist, args = getopt.gnu_getopt(sys.argv, 'ofk', ['oneline', 'file', 'keys']) + optlist, args = getopt.gnu_getopt(sys.argv, 'ofkv', + ['oneline', 'file', 'keys', 'verbose']) flags = [opt for (opt, value) in optlist if value == ''] file = '--file' in flags or '-f' in flags oneline = '--oneline' in flags or '-o' in flags keys = '--keys' in flags or '-k' in flags + verbose = '--verbose' in flags or '-v' in flags if len(args) < 1: print('Usage: %s [info]' % self_name) @@ -92,10 +94,11 @@ def main(): elif keys: print_keys(path) else: - if len(args) == 1: - print_info(path, oneline=oneline) - else: - print_info(path, key=args[1], oneline=oneline) + key=None + if len(args) > 1: + key = args[1] + + print_info(path, key=key, oneline=oneline, verbose=verbose) sys.exit(0) if __name__ == '__main__': diff --git a/hostinfo/printer.py b/hostinfo/printer.py index 430b1f6..9d05431 100644 --- a/hostinfo/printer.py +++ b/hostinfo/printer.py @@ -21,119 +21,122 @@ class Printer: 'os': 'Operating System', 'addresses': 'IPs', 'ports': 'Ports', - 'vserver': 'VServer' + 'vserver': 'VServer', + 'services': 'Services', + 'maintainers': 'Maintainers', + 'description': 'Description' } - ignore = ['vserver-host'] + ignore = ['vserver-host', 'groups'] - def __init__(self, data, oneline): + def __init__(self, data, oneline, verbose): self.data = data self.oneline = oneline + self.verbose = verbose def _sort_with_list(self, list, sort): def helper(value): - if value in sort: - return sort.index(value) - return len(sort) + if sort is None: + return value + + (key, full_key) = value + if key in sort: + return sort.index(key) + return "%d %s" % (len(sort), key) return sorted(list, key=helper) - def print_addresses(self, p, value, filter_key): - interfaces = sorted(set([ip['interface'] for ip in value])) - maxlength = max(map(len, interfaces)) - for interface in interfaces: - if filter_key is None: - iface_name = ("%s: " % interface).ljust(maxlength+2) - p_new = Prefix(iface_name, p.pprint, self.oneline) - else: - p_new = p - - if filter_key is None or filter_key == interface: - for ip in value: - if 'vserver' in ip: - continue - - if interface == ip['interface']: - p_new.pprint('%s/%s' % - (ip['address'], ip['netmask'])) - - def print_vserver(self, p, value, filter_key): + def print_addresses(self, value, pprint, prefix, filter_key): + self._print_group_by(value, pprint, prefix, filter_key, + lambda ip: 'vserver' not in ip and ip['interface'] or None, + lambda ip: '%s/%s' % (ip['address'], ip['netmask'])) + + def print_vserver(self, value, pprint, prefix, filter_key): if value == 'guest': - p.pprint('guest running on %s' % self.data['vserver-host']) + pprint('guest running on %s' % self.data['vserver-host']) else: - p.pprint(value) - - def print_ports(self, p, value, filter_key): - processes = set([port['process'] for port in value if 'process' in port]) - processes = self._sort_with_list(processes, - ['sshd', 'nrpe', 'munin-node']) - if len([port for port in value if 'process' not in port]) > 0: - processes.append('UNKNOWN') - - maxlength = max(map(len, processes)) - for process in processes: - if filter_key is None: - process_name = ("%s: " % process).ljust(maxlength+2) - p_new = Prefix(process_name, p.pprint, self.oneline) - else: - p_new = p - - if filter_key is None or filter_key == process: - for port in value: - if 'process' in port and process == port['process'] or \ - 'process' not in port and process == 'UNKNOWN': - if port['proto'] in ['tcp6', 'udp6']: - p_new.pprint('(%s) [%s]:%s' % - (port['proto'].replace('6', ''), - port['ip'], port['port'])) - else: - p_new.pprint('(%s) %s:%s' % - (port['proto'], port['ip'], port['port'])) - - def print_default(self, key, value, filter_key=None): - label = '' - if self.length > 0: - label = '%s: ' % self.get_label(key) - label = label.rjust(self.length) - p = Prefix(label, print, self.oneline) + pprint(value) + + def print_ports(self, value, pprint, prefix, filter_key): + def _print_port(port): + if port['proto'] in ['tcp6', 'udp6']: + return '(%s) [%s]:%s' % (port['proto'].replace('6', ''), + port['ip'], port['port']) + return '(%s) %s:%s' % (port['proto'], port['ip'], port['port']) + self._print_group_by(value, pprint, prefix, filter_key, + lambda port: 'process' in port and port['process'] or 'UNKNOWN', + _print_port, + sort=['sshd', 'nrpe', 'munin-node']) + + def _print(self, value, pprint, prefix='', filter_key=None, sort=None): try: - method = getattr(self, 'print_%s' % key) - method(p, value, filter_key) - except AttributeError: - try: - value = value.strip().splitlines() - except: - pass - - if isinstance(value, list): - for v in value: - p.pprint(v) - else: - p.pprint(value) - - def get_label(self, key): - if key in self.labels: - return self.labels[key] + value = value.strip().splitlines() + except: + pass + + if isinstance(value, dict): + self._print_dict(value, pprint, prefix, filter_key, sort) + elif isinstance(value, list): + for v in value: + pprint(v) + elif value is None: + if self.verbose: + pprint('') + else: + pprint(value) + + def _print_dict(self, value, pprint, prefix, filter_key, sort): + keys = self._sort_with_list( + [(key, full_key) for key in value.keys() + for full_key in [self._get_full_key(prefix, key)] + if full_key not in self.ignore or + filter_key is not None and filter_key.startswith(full_key)], + sort) + maxlength = max(map(len, map(lambda (key, full_key): self._get_label(key, full_key), keys))) + + for (key, full_key) in keys: + if filter_key is None or filter_key.startswith(full_key): + new_filter_key = filter_key + if full_key == filter_key: + new_filter_key = None + + new_pprint = pprint + if filter_key is None: + label = "%s: " % self._get_label(key, full_key) + if prefix == '': + label = label.rjust(maxlength+4) + else: + label = label.ljust(maxlength+2) + + p = Prefix(label, pprint, self.oneline) + new_pprint = p.pprint + + try: + method = getattr(self, 'print_%s' % full_key.replace('.', '_')) + method(value[key], new_pprint, full_key, new_filter_key) + except AttributeError: + self._print(value[key], new_pprint, full_key, new_filter_key) + + def _print_group_by(self, value, pprint, prefix, filter_key, group, format, sort=None): + d = {} + for e in value: + key = group(e) + if key is not None: + d.setdefault(key, []).append(format(e)) + + self._print(d, pprint, prefix, filter_key, sort) + + def _get_full_key(self, prefix, key): + if prefix == '': + return key + return "%s.%s" % (prefix, key) + + def _get_label(self, key, full_key): + if full_key in self.labels: + return self.labels[full_key] return key def info(self, key): - # find max lenght for labels - labels = map(self.get_label, self.data.keys()) - self.length = max(map(len, labels)) + 3 - - if key is not None: - key_extra = None - if '.' in key: - [key, key_extra] = key.split('.', 1) - - self.length = 0 - if key in self.data: - self.print_default(key, self.data[key], key_extra) - else: - keys = self._sort_with_list(self.data.keys(), - ['hostname', 'arch', 'os', - 'addresses', 'ports']) - for key in keys: - if key not in self.ignore: - self.print_default(key, self.data[key]) + self._print(self.data, print, filter_key=key, + sort=['hostname', 'arch', 'os', 'addresses', 'ports']) -- cgit v1.2.3-1-g7c22