| 1 | #!/usr/bin/env python |
|---|
| 2 | |
|---|
| 3 | """ |
|---|
| 4 | invirt-getconf loads an invirt configuration file (either the original YAML |
|---|
| 5 | source or the faster-to-load JSON cache) and prints the configuration option |
|---|
| 6 | with the given name (key). Keys are dot-separated paths into the YAML |
|---|
| 7 | configuration tree. List indexes (0-based) are also treated as path |
|---|
| 8 | components. |
|---|
| 9 | |
|---|
| 10 | (Due to this path language, certain restrictions are placed on the keys used in |
|---|
| 11 | the YAML configuration; e.g., they cannot contain dots.) |
|---|
| 12 | |
|---|
| 13 | Examples: |
|---|
| 14 | |
|---|
| 15 | invirt-getconf db.uri |
|---|
| 16 | invirt-getconf authn.0.type |
|---|
| 17 | """ |
|---|
| 18 | |
|---|
| 19 | from invirt.config import default_src_path, default_cache_path, load |
|---|
| 20 | from sys import argv, exit, stderr, stdout |
|---|
| 21 | from optparse import OptionParser |
|---|
| 22 | |
|---|
| 23 | class invirt_exception(Exception): pass |
|---|
| 24 | |
|---|
| 25 | def main(argv): |
|---|
| 26 | try: |
|---|
| 27 | parser = OptionParser(usage = '%prog [options] key', |
|---|
| 28 | description = __doc__.strip().split('\n\n')[0]) |
|---|
| 29 | parser.add_option('-s', '--src', |
|---|
| 30 | default = default_src_path, |
|---|
| 31 | help = 'the source YAML configuration file to read from') |
|---|
| 32 | parser.add_option('-c', '--cache', |
|---|
| 33 | default = default_cache_path, |
|---|
| 34 | help = 'path to the JSON cache') |
|---|
| 35 | parser.add_option('-r', '--refresh', |
|---|
| 36 | action = 'store_true', |
|---|
| 37 | help = 'force the cache to be regenerated') |
|---|
| 38 | parser.add_option('-l', '--ls', |
|---|
| 39 | action = 'store_true', |
|---|
| 40 | help = 'list node\'s children') |
|---|
| 41 | opts, args = parser.parse_args() |
|---|
| 42 | |
|---|
| 43 | if len(args) > 1: |
|---|
| 44 | raise invirt_exception(__doc__.strip()) |
|---|
| 45 | elif args and args[0]: |
|---|
| 46 | components = args[0].split('.') |
|---|
| 47 | else: |
|---|
| 48 | components = [] |
|---|
| 49 | |
|---|
| 50 | conf = load(opts.src, opts.cache, opts.refresh) |
|---|
| 51 | for i, component in enumerate(components): |
|---|
| 52 | progress = '.'.join(components[:i]) |
|---|
| 53 | if type(conf) not in (dict, list): |
|---|
| 54 | raise invirt_exception( |
|---|
| 55 | '%s: node has no children (atomic datum)' % progress) |
|---|
| 56 | if type(conf) == list: |
|---|
| 57 | try: component = int(component) |
|---|
| 58 | except: raise invirt_exception( |
|---|
| 59 | '%s: node a list; integer path component required, ' |
|---|
| 60 | 'but got "%s"' % (progress, component)) |
|---|
| 61 | try: conf = conf[component] |
|---|
| 62 | except KeyError: raise invirt_exception( |
|---|
| 63 | '%s: key "%s" not found' % (progress, component)) |
|---|
| 64 | except IndexError: raise invirt_exception( |
|---|
| 65 | '%s: index %s out of range' % (progress, component)) |
|---|
| 66 | |
|---|
| 67 | if opts.ls: |
|---|
| 68 | if type(conf) not in (dict, list): |
|---|
| 69 | raise invirt_exception( |
|---|
| 70 | '%s: node has no children (atomic datum)' |
|---|
| 71 | % '.'.join(components)) |
|---|
| 72 | if type(conf) == list: |
|---|
| 73 | for i in xrange(len(conf)): |
|---|
| 74 | print i |
|---|
| 75 | else: |
|---|
| 76 | for k in conf.iterkeys(): |
|---|
| 77 | print k |
|---|
| 78 | else: |
|---|
| 79 | if type(conf) not in (dict, list): |
|---|
| 80 | print conf |
|---|
| 81 | else: |
|---|
| 82 | import yaml |
|---|
| 83 | try: dumper = yaml.CSafeDumper |
|---|
| 84 | except: dumper = yaml.SafeDumper |
|---|
| 85 | yaml.dump(conf, stdout, |
|---|
| 86 | Dumper = dumper, default_flow_style = False) |
|---|
| 87 | except invirt_exception, ex: |
|---|
| 88 | print >> stderr, ex |
|---|
| 89 | return 1 |
|---|
| 90 | |
|---|
| 91 | if __name__ == '__main__': |
|---|
| 92 | exit(main(argv)) |
|---|
| 93 | |
|---|
| 94 | # vim:et:sw=4:ts=4 |
|---|