From 1ba44287db6ea216caeb9bd3bf4cc3e32874abf7 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 31 May 2013 03:11:50 +0200 Subject: hostinfo: add basic search mechanism --- bin/hostinfo | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/bin/hostinfo b/bin/hostinfo index 9b4f09d..4c87e98 100755 --- a/bin/hostinfo +++ b/bin/hostinfo @@ -19,6 +19,83 @@ def _get_data(path): stream = file(path, 'r') return yaml.load(stream) +def match_key(data, keys): + if data is None: + return None + + if len(keys) == 0: + return data + + key = keys[0] + rest = keys[1:] + + if key == 'addresses' and 'addresses' in data: + return match_key({a['interface']: a for a in data}, rest) + + if key == 'ports' and 'ports' in data: + return match_key({p['process']: p for p in data}, rest) + + if isinstance(data, dict): + if key in data: + return match_key(data[key], rest) + return None + + if isinstance(data, list): + for elem in data: + result = match_key(elem, keys) + if result is not None: + return result + return None + + if data == key: + return data + + return None + +def match(host, search): + if search[0] != '?': + sys.stderr.write("Invalid search string.") + sys.exit(1) + search = search[1:] + + negate = False + if search[0] == '~': + search = search[1:] + negate = True + + key_elem = search.split('.') + data = host + prev_key = None + + result = match_key(data, key_elem) + if negate: + if result is not None: + return (search, None) + return (None, True) + return (search, result) + +def print_search(basepath, flags, search): + def _get_label(host): + if flags.short: + return host.replace('.spline.inf.fu-berlin.de','') + return host + + metadata = os.path.join(basepath, 'metadata', 'hosts') + if not os.path.exists(metadata): + sys.stderr.write("Invalid hostinfo data. 'metadata/hosts' not found!\n\n") + sys.exit(1) + + hosts = _get_data(metadata) + for host in hosts['hosts']: + data = _get_data(os.path.join(basepath, host)) + key, result = match(data, search) + if result is not None: + if key is None: + print(host) + else: + p = printer.Printer(data, flags) + p.info(key, label=_get_label(host), maxlength=max(map(len, map(_get_label, hosts['hosts'])))) + def print_info(path, flags, key=None): data = _get_data(path) p = printer.Printer(data, flags) @@ -126,18 +203,22 @@ def main(): parser.print_help() sys.exit(1) - # info - path = find_host(basepath, args.name) - if path is None: - sys.stderr.write("Host '%s' could not be found!\n" % args.name) - sys.exit(1) - - if args.file: - print(path) - elif args.keys: - print_keys(path) + if args.name.startswith('?'): + # search + print_search(basepath, search=args.name, flags=args) else: - print_info(path, key=args.filter, flags=args) + # info + path = find_host(basepath, args.name) + if path is None: + sys.stderr.write("Host '%s' could not be found!\n" % args.name) + sys.exit(1) + + if args.file: + print(path) + elif args.keys: + print_keys(path) + else: + print_info(path, key=args.filter, flags=args) sys.exit(0) -- cgit v1.2.3-1-g7c22