blob: 31179ffada92a3f0b669223d3f8e90ef957a5a8a [file] [log] [blame]
Filip Pytlounfff50fc2015-06-24 14:57:21 +02001#!/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
10import os, sys, posix
11
Jiri Broulikd3264612018-06-14 17:06:40 +020012from six import iteritems
13
Jiri Broulik30e05a62018-06-14 13:31:24 +020014from reclass import get_storage, output, get_path_mangler
Filip Pytlounfff50fc2015-06-24 14:57:21 +020015from reclass.core import Core
16from reclass.errors import ReclassException
Jiri Broulik30e05a62018-06-14 13:31:24 +020017from reclass.config import find_and_read_configfile, get_options
Filip Pytlounfff50fc2015-06-24 14:57:21 +020018from reclass.constants import MODE_NODEINFO
19from reclass.defaults import *
Jiri Broulik30e05a62018-06-14 13:31:24 +020020from reclass.settings import Settings
Filip Pytlounfff50fc2015-06-24 14:57:21 +020021from reclass.version import *
22
23def 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 Broulik30e05a62018-06-14 13:31:24 +020029 propagate_pillar_data_to_reclass=False,
30 **kwargs):
Filip Pytlounfff50fc2015-06-24 14:57:21 +020031
Jiri Broulik30e05a62018-06-14 13:31:24 +020032 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 Pytlounfff50fc2015-06-24 14:57:21 +020035 input_data = None
36 if propagate_pillar_data_to_reclass:
37 input_data = pillar
Jiri Broulik30e05a62018-06-14 13:31:24 +020038 settings = Settings(kwargs)
39 reclass = Core(storage, class_mappings, settings, input_data=input_data)
Filip Pytlounfff50fc2015-06-24 14:57:21 +020040
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
51def top(minion_id, storage_type=OPT_STORAGE_TYPE,
52 inventory_base_uri=OPT_INVENTORY_BASE_URI, nodes_uri=OPT_NODES_URI,
Jiri Broulik30e05a62018-06-14 13:31:24 +020053 classes_uri=OPT_CLASSES_URI, class_mappings=None, **kwargs):
Filip Pytlounfff50fc2015-06-24 14:57:21 +020054
Jiri Broulik30e05a62018-06-14 13:31:24 +020055 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 Pytlounfff50fc2015-06-24 14:57:21 +020060
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 Broulikd3264612018-06-14 17:06:40 +020073 for (node_id, node_data) in iteritems(data['nodes']):
Filip Pytlounfff50fc2015-06-24 14:57:21 +020074 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
82def cli():
83 try:
84 inventory_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
85 defaults = {'pretty_print' : True,
Jiri Broulik30e05a62018-06-14 13:31:24 +020086 'no_refs' : False,
Filip Pytlounfff50fc2015-06-24 14:57:21 +020087 '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 Broulik30e05a62018-06-14 13:31:24 +0200101 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 Pytlounfff50fc2015-06-24 14:57:21 +0200107
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 Broulik30e05a62018-06-14 13:31:24 +0200114 class_mappings=class_mappings,
115 **defaults)
Filip Pytlounfff50fc2015-06-24 14:57:21 +0200116 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 Broulik30e05a62018-06-14 13:31:24 +0200122 class_mappings=class_mappings,
123 **defaults)
Filip Pytlounfff50fc2015-06-24 14:57:21 +0200124
Jiri Broulik30e05a62018-06-14 13:31:24 +0200125 print output(data, options.output, options.pretty_print, options.no_refs)
Filip Pytlounfff50fc2015-06-24 14:57:21 +0200126
127 except ReclassException, e:
128 e.exit_with_message(sys.stderr)
129
130 sys.exit(posix.EX_OK)
131
132if __name__ == '__main__':
133 cli()