summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2013-05-31 03:11:50 +0200
committerAlexander Sulfrian <alexander@sulfrian.net>2013-06-05 19:12:58 +0200
commit1ba44287db6ea216caeb9bd3bf4cc3e32874abf7 (patch)
tree4ce41fc621670365cd536ddd007d9f829bb8ff7d
parentf16781bdcaa54f9c2ef635cf0c18bdca7c60817d (diff)
downloadtools-1ba44287db6ea216caeb9bd3bf4cc3e32874abf7.tar.gz
tools-1ba44287db6ea216caeb9bd3bf4cc3e32874abf7.tar.bz2
tools-1ba44287db6ea216caeb9bd3bf4cc3e32874abf7.zip
hostinfo: add basic search mechanism
-rwxr-xr-xbin/hostinfo103
1 files 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)