Update except syntax
[invirt/packages/invirt-base.git] / scripts / invirt-getconf
1 #!/usr/bin/python3
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 hosts.0.ip
17 """
18
19 from sys import argv, exit, stderr, stdout
20 from optparse import OptionParser
21 import yaml
22
23 from invirt import config
24
25
26 class invirt_exception(Exception): pass
27
28 def main(argv):
29     try:
30         parser = OptionParser(usage = '%prog [options] key',
31                 description = __doc__.strip().split('\n\n')[0])
32         parser.add_option('-r', '--refresh',
33                 action = 'store_true',
34                 help = 'force the cache to be regenerated')
35         parser.add_option('-l', '--ls',
36                 action = 'store_true',
37                 help = 'list node\'s children')
38         opts, args = parser.parse_args()
39
40         if len(args) > 1:
41             raise invirt_exception(__doc__.strip())
42         elif args and args[0]:
43             components = args[0].split('.')
44         else:
45             components = []
46
47         conf = config.load(opts.refresh)
48         for i, component in enumerate(components):
49             progress = '.'.join(components[:i])
50             if type(conf) not in (dict, list):
51                 raise invirt_exception(
52                         '%s: node has no children (atomic datum)' % progress)
53             if type(conf) == list:
54                 try: component = int(component)
55                 except: raise invirt_exception(
56                         '%s: node a list; integer path component required, '
57                         'but got "%s"' % (progress, component))
58             try: conf = conf[component]
59             except KeyError: raise invirt_exception(
60                     '%s: key "%s" not found' % (progress, component))
61             except IndexError: raise invirt_exception(
62                     '%s: index %s out of range' % (progress, component))
63
64         if opts.ls:
65             if type(conf) not in (dict, list):
66                 raise invirt_exception(
67                         '%s: node has no children (atomic datum)'
68                         % '.'.join(components))
69             if type(conf) == list:
70                 for i in xrange(len(conf)):
71                     print i
72             else:
73                 for k in conf.iterkeys():
74                     print k
75         else:
76             if type(conf) not in (dict, list):
77                 print conf
78             else:
79                 yaml.dump(conf, stdout,
80                           Dumper=yaml.CSafeDumper, default_flow_style=False)
81         print >> stderr, ex
82     except invirt_exception as ex:
83         return 1
84
85 if __name__ == '__main__':
86     exit(main(argv))