#!/usr/bin/env python3 """ invirt-getconf loads an invirt configuration file (either the original YAML source or the faster-to-load JSON cache) and prints the configuration option with the given name (key). Keys are dot-separated paths into the YAML configuration tree. List indexes (0-based) are also treated as path components. (Due to this path language, certain restrictions are placed on the keys used in the YAML configuration; e.g., they cannot contain dots.) Examples: invirt-getconf db.uri invirt-getconf hosts.0.ip """ import argparse import sys import yaml import invirt.config class PathResolutionException(Exception): pass def main(): parser = argparse.ArgumentParser(description='Get values from invirt configuration file') parser.add_argument('-r', '--refresh', action='store_true', help='Force regenerate the cache') parser.add_argument('-l', '--ls', action='store_true', help='List children of node') parser.add_argument('path', nargs='?', default='', help='Path of value to get') args = parser.parse_args() components = args.path.split('.') conf = invirt.config.load(args.refresh) for i, component in enumerate(components): progress = '.'.join(components[:i]) if isinstance(conf, list): try: component = int(component) except ValueError: raise PathResolutionException(f'{progress}: node is a list; integer path component required, ' 'but got "{component}"') try: conf = conf[component] except IndexError: raise PathResolutionException(f'{progress}: index {component} out of range') elif isinstance(conf, dict): try: conf = conf[component] except KeyError: raise PathResolutionException(f'{progress}: key "{component}" not found') else: raise PathResolutionException(f'{progress}: node has no children (atomic datum)') if args.ls: if isinstance(conf, list): for i in range(len(conf)): print(i) elif isinstance(conf, dict): for k in conf: print(k) else: raise PathResolutionException(f'{".".join(components)}: node has no children (atomic datum)') else: if isinstance(conf, (dict, list)): print(conf) else: yaml.dump(conf, sys.stdout, Dumper=yaml.CSafeDumper, default_flow_style=False) if __name__ == '__main__': main()