martin f. krafft | f37f068 | 2013-06-14 16:36:20 +0200 | [diff] [blame] | 1 | # |
| 2 | # -*- coding: utf-8 -*- |
| 3 | # |
| 4 | # This file is part of reclass (http://github.com/madduck/reclass) |
| 5 | # |
| 6 | # Copyright © 2007–13 martin f. krafft <madduck@madduck.net> |
| 7 | # Released under the terms of the Artistic Licence 2.0 |
| 8 | # |
| 9 | import yaml, os, optparse, posix, sys |
| 10 | |
| 11 | def _make_parser(name, version, description, defaults={}): |
| 12 | parser = optparse.OptionParser(version=version) |
| 13 | parser.prog = name |
| 14 | parser.version = version |
| 15 | parser.description = description |
| 16 | parser.usage = '%prog [options] ( --inventory | --nodeinfo <nodename> )' |
| 17 | |
| 18 | options_group = optparse.OptionGroup(parser, 'Options', |
| 19 | 'Configure the way {0} works'.format(name)) |
| 20 | options_group.add_option('-t', '--storage-type', dest='storage_type', |
| 21 | default=defaults.get('storage_type', 'yaml_fs'), |
| 22 | help='the type of storage backend to use [%default]') |
| 23 | options_group.add_option('-u', '--nodes-uri', dest='nodes_uri', |
| 24 | default=defaults.get('nodes_uri', None), |
| 25 | help='the URI to the nodes storage [%default]'), |
| 26 | options_group.add_option('-c', '--classes-uri', dest='classes_uri', |
| 27 | default=defaults.get('classes_uri', None), |
| 28 | help='the URI to the classes storage [%default]') |
| 29 | options_group.add_option('-o', '--output', dest='output', |
| 30 | default=defaults.get('output', 'yaml'), |
| 31 | help='output format (yaml or json) [%default]') |
| 32 | options_group.add_option('-p', '--pretty-print', dest='pretty_print', |
| 33 | default=defaults.get('pretty_print', False), |
| 34 | action="store_true", |
| 35 | help='try to make the output prettier [%default]') |
martin f. krafft | 9a9b0ac | 2013-06-21 21:24:18 +0200 | [diff] [blame] | 36 | options_group.add_option('--applications-postfix', dest='applications_postfix', |
| 37 | default=defaults.get('applications_postfix', '_hosts'), |
| 38 | help="the postfix to apply to groups made from applications ['%default']") |
martin f. krafft | f37f068 | 2013-06-14 16:36:20 +0200 | [diff] [blame] | 39 | parser.add_option_group(options_group) |
| 40 | |
| 41 | run_modes = optparse.OptionGroup(parser, 'Modes', |
| 42 | 'Specify one of these to determine what to do.') |
| 43 | run_modes.add_option('-i', '--inventory', action='store_false', dest='node', |
| 44 | help='output the entire inventory') |
| 45 | run_modes.add_option('-n', '--nodeinfo', action='store', dest='node', |
| 46 | default=None, |
| 47 | help='output information for a specific node') |
| 48 | parser.add_option_group(run_modes) |
| 49 | |
| 50 | return parser |
| 51 | |
| 52 | def _parse_and_check_options(parser): |
| 53 | options, args = parser.parse_args() |
| 54 | |
| 55 | def usage_error(msg): |
| 56 | sys.stderr.write(msg + '\n\n') |
| 57 | parser.print_help(sys.stderr) |
| 58 | sys.exit(posix.EX_USAGE) |
| 59 | |
| 60 | if len(args) > 0: |
| 61 | usage_error('No arguments allowed') |
| 62 | elif options.node is None: |
| 63 | usage_error('You need to either pass --inventory or --nodeinfo <nodename>') |
| 64 | elif options.output not in ('json', 'yaml'): |
| 65 | usage_error('Unknown output format: {0}'.format(options.output)) |
| 66 | elif options.nodes_uri is None: |
| 67 | usage_error('Must specify at least --nodes-uri') |
| 68 | |
| 69 | options.classes_uri = options.classes_uri or options.nodes_uri |
| 70 | |
| 71 | return options |
| 72 | |
| 73 | def read_config_file(path): |
| 74 | if os.path.exists(path): |
| 75 | return yaml.safe_load(file(path)) |
| 76 | else: |
| 77 | return {} |
| 78 | |
| 79 | def get_options(name, version, description, config_file=None): |
| 80 | config_data = {} |
| 81 | if config_file is not None: |
| 82 | config_data.update(read_config_file(config_file)) |
| 83 | parser = _make_parser(name, version, description, config_data) |
| 84 | return _parse_and_check_options(parser) |