blob: aa14dacb35518e8acf16bd564ddfde8c04bb4b74 [file] [log] [blame]
Alex Savatieiev9b2f6512019-02-20 18:05:00 -06001import json
2import os
3import sys
4
5from copy import deepcopy
6
7from cfg_checker.common import utils, const
8from cfg_checker.common import config, logger, logger_cli, pkg_dir
9from cfg_checker.common import salt_utils
10
11node_tmpl = {
12 'role': '',
13 'node_group': '',
14 'status': const.NODE_DOWN,
15 'pillars': {},
16 'grains': {}
17}
18
19
20class SaltNodes(object):
21 def __init__(self):
Alex Savatieieve9613992019-02-21 18:20:35 -060022 logger_cli.info("### Collecting nodes")
Alex Savatieiev9b2f6512019-02-20 18:05:00 -060023 # simple salt rest client
24 self.salt = salt_utils.SaltRemote()
25
26 # Keys for all nodes
27 # this is not working in scope of 2016.8.3, will overide with list
28 # cls.node_keys = cls.salt.list_keys()
29
30 logger_cli.info("### Collecting node names existing in the cloud")
31 self.node_keys = {
32 'minions': config.all_nodes
33 }
34
35 # all that answer ping
36 _active = self.salt.get_active_nodes()
37 logger_cli.debug("-> Nodes responded: {}".format(_active))
38 # just inventory for faster interaction
39 # iterate through all accepted nodes and create a dict for it
40 self.nodes = {}
41 for _name in self.node_keys['minions']:
42 _nc = utils.get_node_code(_name)
43 _rmap = const.all_roles_map
44 _role = _rmap[_nc] if _nc in _rmap else 'unknown'
45 _status = const.NODE_UP if _name in _active else const.NODE_DOWN
46
47 self.nodes[_name] = deepcopy(node_tmpl)
48 self.nodes[_name]['node_group'] = _nc
49 self.nodes[_name]['role'] = _role
50 self.nodes[_name]['status'] = _status
51
52 logger_cli.info("-> {} nodes collected".format(len(self.nodes)))
53
54 def get_nodes(self):
55 return self.nodes
56
57 def execute_script(self, script_filename, args=[]):
58 # form an all nodes compound string to use in salt
59 _active_nodes_string = self.salt.compound_string_from_list(
60 filter(
61 lambda nd: self.nodes[nd]['status'] == const.NODE_UP,
62 self.nodes
63 )
64 )
65 # Prepare script
66 _p = os.path.join(pkg_dir, 'scripts', script_filename)
67 with open(_p, 'rt') as fd:
68 _script = fd.read().splitlines()
69 _storage_path = os.path.join(
70 config.salt_file_root, config.salt_scripts_folder
71 )
72 logger_cli.debug(
73 "# Uploading script {} to master's file cache folder: '{}'".format(
74 script_filename,
75 _storage_path
76 )
77 )
78 _result = self.salt.mkdir("cfg01*", _storage_path)
79 # Form cache, source and target path
80 _cache_path = os.path.join(_storage_path, script_filename)
81 _source_path = os.path.join(
82 'salt://',
83 config.salt_scripts_folder,
84 script_filename
85 )
86 _target_path = os.path.join(
87 '/root',
88 config.salt_scripts_folder,
89 script_filename
90 )
91
92 logger_cli.debug("# Creating file in cache '{}'".format(_cache_path))
93 _result = self.salt.f_touch_master(_cache_path)
94 _result = self.salt.f_append_master(_cache_path, _script)
95 # command salt to copy file to minions
96 logger_cli.debug("# Creating script target folder '{}'".format(_cache_path))
97 _result = self.salt.mkdir(
98 _active_nodes_string,
99 os.path.join(
100 '/root',
101 config.salt_scripts_folder
102 ),
103 tgt_type="compound"
104 )
105 logger_cli.info("-> Running script to all active nodes")
106 _result = self.salt.get_file(
107 _active_nodes_string,
108 _source_path,
109 _target_path,
110 tgt_type="compound"
111 )
112 # execute pkg collecting script
113 logger.debug("Running script to all nodes")
114 # handle results for each node
115 _script_arguments = " ".join(args) if args else ""
116 _result = self.salt.cmd(
117 _active_nodes_string,
118 'cmd.run',
119 param='python {} {}'.format(_target_path, _script_arguments),
120 expr_form="compound"
121 )
122
123 # TODO: Handle error result
124
125 return _result