Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # -*- coding: utf-8 -*- |
| 3 | # |
| 4 | # This file is part of reclass (http://github.com/madduck/reclass) |
| 5 | # |
| 6 | # Copyright © 2007–14 martin f. krafft <madduck@madduck.net> |
| 7 | # Released under the terms of the Artistic Licence 2.0 |
| 8 | # |
| 9 | |
| 10 | import os, sys, posix |
| 11 | |
Jiri Broulik | d326461 | 2018-06-14 17:06:40 +0200 | [diff] [blame] | 12 | from six import iteritems |
| 13 | |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 14 | from reclass import get_storage, output, get_path_mangler |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 15 | from reclass.core import Core |
| 16 | from reclass.errors import ReclassException |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 17 | from reclass.config import find_and_read_configfile, get_options |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 18 | from reclass.constants import MODE_NODEINFO |
| 19 | from reclass.defaults import * |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 20 | from reclass.settings import Settings |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 21 | from reclass.version import * |
| 22 | |
| 23 | def ext_pillar(minion_id, pillar, |
| 24 | storage_type=OPT_STORAGE_TYPE, |
| 25 | inventory_base_uri=OPT_INVENTORY_BASE_URI, |
| 26 | nodes_uri=OPT_NODES_URI, |
| 27 | classes_uri=OPT_CLASSES_URI, |
| 28 | class_mappings=None, |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 29 | propagate_pillar_data_to_reclass=False, |
| 30 | **kwargs): |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 31 | |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 32 | path_mangler = get_path_mangler(storage_type) |
| 33 | nodes_uri, classes_uri = path_mangler(inventory_base_uri, nodes_uri, classes_uri) |
| 34 | storage = get_storage(storage_type, nodes_uri, classes_uri) |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 35 | input_data = None |
| 36 | if propagate_pillar_data_to_reclass: |
| 37 | input_data = pillar |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 38 | settings = Settings(kwargs) |
| 39 | reclass = Core(storage, class_mappings, settings, input_data=input_data) |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 40 | |
| 41 | data = reclass.nodeinfo(minion_id) |
| 42 | params = data.get('parameters', {}) |
| 43 | params['__reclass__'] = {} |
| 44 | params['__reclass__']['nodename'] = minion_id |
| 45 | params['__reclass__']['applications'] = data['applications'] |
| 46 | params['__reclass__']['classes'] = data['classes'] |
| 47 | params['__reclass__']['environment'] = data['environment'] |
| 48 | return params |
| 49 | |
| 50 | |
| 51 | def top(minion_id, storage_type=OPT_STORAGE_TYPE, |
| 52 | inventory_base_uri=OPT_INVENTORY_BASE_URI, nodes_uri=OPT_NODES_URI, |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 53 | classes_uri=OPT_CLASSES_URI, class_mappings=None, **kwargs): |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 54 | |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 55 | path_mangler = get_path_mangler(storage_type) |
| 56 | nodes_uri, classes_uri = path_mangler(inventory_base_uri, nodes_uri, classes_uri) |
| 57 | storage = get_storage(storage_type, nodes_uri, classes_uri) |
| 58 | settings = Settings(kwargs) |
| 59 | reclass = Core(storage, class_mappings, settings, input_data=None) |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 60 | |
| 61 | # if the minion_id is not None, then return just the applications for the |
| 62 | # specific minion, otherwise return the entire top data (which we need for |
| 63 | # CLI invocations of the adapter): |
| 64 | if minion_id is not None: |
| 65 | data = reclass.nodeinfo(minion_id) |
| 66 | applications = data.get('applications', []) |
| 67 | env = data['environment'] |
| 68 | return {env: applications} |
| 69 | |
| 70 | else: |
| 71 | data = reclass.inventory() |
| 72 | nodes = {} |
Jiri Broulik | d326461 | 2018-06-14 17:06:40 +0200 | [diff] [blame] | 73 | for (node_id, node_data) in iteritems(data['nodes']): |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 74 | env = node_data['environment'] |
| 75 | if env not in nodes: |
| 76 | nodes[env] = {} |
| 77 | nodes[env][node_id] = node_data['applications'] |
| 78 | |
| 79 | return nodes |
| 80 | |
| 81 | |
| 82 | def cli(): |
| 83 | try: |
| 84 | inventory_dir = os.path.abspath(os.path.dirname(sys.argv[0])) |
| 85 | defaults = {'pretty_print' : True, |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 86 | 'no_refs' : False, |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 87 | 'output' : 'yaml', |
| 88 | 'inventory_base_uri': inventory_dir |
| 89 | } |
| 90 | defaults.update(find_and_read_configfile()) |
| 91 | options = get_options(RECLASS_NAME, VERSION, DESCRIPTION, |
| 92 | inventory_shortopt='-t', |
| 93 | inventory_longopt='--top', |
| 94 | inventory_help='output the state tops (inventory)', |
| 95 | nodeinfo_shortopt='-p', |
| 96 | nodeinfo_longopt='--pillar', |
| 97 | nodeinfo_dest='nodename', |
| 98 | nodeinfo_help='output pillar data for a specific node', |
| 99 | defaults=defaults) |
| 100 | class_mappings = defaults.get('class_mappings') |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 101 | defaults.update(vars(options)) |
| 102 | defaults.pop("storage_type", None) |
| 103 | defaults.pop("inventory_base_uri", None) |
| 104 | defaults.pop("nodes_uri", None) |
| 105 | defaults.pop("classes_uri", None) |
| 106 | defaults.pop("class_mappings", None) |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 107 | |
| 108 | if options.mode == MODE_NODEINFO: |
| 109 | data = ext_pillar(options.nodename, {}, |
| 110 | storage_type=options.storage_type, |
| 111 | inventory_base_uri=options.inventory_base_uri, |
| 112 | nodes_uri=options.nodes_uri, |
| 113 | classes_uri=options.classes_uri, |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 114 | class_mappings=class_mappings, |
| 115 | **defaults) |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 116 | else: |
| 117 | data = top(minion_id=None, |
| 118 | storage_type=options.storage_type, |
| 119 | inventory_base_uri=options.inventory_base_uri, |
| 120 | nodes_uri=options.nodes_uri, |
| 121 | classes_uri=options.classes_uri, |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 122 | class_mappings=class_mappings, |
| 123 | **defaults) |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 124 | |
Jiri Broulik | 30e05a6 | 2018-06-14 13:31:24 +0200 | [diff] [blame] | 125 | print output(data, options.output, options.pretty_print, options.no_refs) |
Filip Pytloun | fff50fc | 2015-06-24 14:57:21 +0200 | [diff] [blame] | 126 | |
| 127 | except ReclassException, e: |
| 128 | e.exit_with_message(sys.stderr) |
| 129 | |
| 130 | sys.exit(posix.EX_OK) |
| 131 | |
| 132 | if __name__ == '__main__': |
| 133 | cli() |