blob: 132bfea9a514e6fe5316050fe252fe964f819a85 [file] [log] [blame]
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +00001import os
2import yaml
3import requests
4import re
Oleksii Zhurbae592ed12018-06-21 18:01:09 -05005import sys, traceback
Oleksii Zhurba3dbed242017-10-31 19:58:53 +00006
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +00007
Mikhail Chernikc492a682018-08-27 22:41:17 +02008class AuthenticationError(Exception):
9 pass
10
11
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000012class salt_remote:
Oleksii Zhurba3dbed242017-10-31 19:58:53 +000013 def cmd(self, tgt, fun, param=None, expr_form=None, tgt_type=None):
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +000014 config = get_configuration()
Valentyn Khalin81dd23d2018-09-20 15:39:07 +030015 url = config['SALT_URL'].strip()
16 if not re.match("^(http|https)://", url):
17 raise AuthenticationError("Salt URL should start \
18 with http or https, given - {}".format(url))
Oleksii Zhurbae592ed12018-06-21 18:01:09 -050019 proxies = {"http": None, "https": None}
Oleksii Zhurba3dbed242017-10-31 19:58:53 +000020 headers = {'Accept': 'application/json'}
21 login_payload = {'username': config['SALT_USERNAME'],
22 'password': config['SALT_PASSWORD'], 'eauth': 'pam'}
23 accept_key_payload = {'fun': fun, 'tgt': tgt, 'client': 'local',
Oleksii Zhurba7a671112018-01-12 11:50:56 -060024 'expr_form': expr_form, 'tgt_type': tgt_type,
25 'timeout': config['salt_timeout']}
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000026 if param:
Oleksii Zhurba3dbed242017-10-31 19:58:53 +000027 accept_key_payload['arg'] = param
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000028
Oleksii Zhurbae592ed12018-06-21 18:01:09 -050029 try:
30 login_request = requests.post(os.path.join(url, 'login'),
31 headers=headers, data=login_payload,
32 proxies=proxies)
Mikhail Chernikc492a682018-08-27 22:41:17 +020033 if not login_request.ok:
34 raise AuthenticationError("Authentication to SaltMaster failed")
35
36 request = requests.post(url, headers=headers,
37 data=accept_key_payload,
38 cookies=login_request.cookies,
39 proxies=proxies)
40
41 response = request.json()['return'][0]
42 not_responded = [k for k,v in response.iteritems() if v is False]
43 if not_responded:
44 print ("WARNING: Some nodes are unavailable and removed "
45 "from response: {}".format(', '.join(not_responded))
46 )
47 for node in not_responded:
48 del response[node]
49 return response
50
51 except Exception as e:
52 print ("\033[91m\nConnection to SaltMaster "
53 "was not established.\n"
54 "Please make sure that you "
55 "provided correct credentials.\n"
56 "Error message: {}\033[0m\n".format(e.message or e)
57 )
Oleksii Zhurbae592ed12018-06-21 18:01:09 -050058 traceback.print_exc(file=sys.stdout)
59 sys.exit()
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000060
61
62def init_salt_client():
63 local = salt_remote()
64 return local
65
66
Mikhail Chernik714596e2018-08-10 21:19:07 +020067def list_to_target_string(node_list, separator, add_spaces=True):
68 if add_spaces:
69 separator = ' ' + separator.strip() + ' '
70 return separator.join(node_list)
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +000071
72
Oleksii Zhurba020fab42017-11-01 20:13:28 +000073def get_monitoring_ip(param_name):
74 local_salt_client = init_salt_client()
75 salt_output = local_salt_client.cmd(
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +030076 'salt:master',
Oleksii Zhurba020fab42017-11-01 20:13:28 +000077 'pillar.get',
78 ['_param:{}'.format(param_name)],
79 expr_form='pillar')
80 return salt_output[salt_output.keys()[0]]
81
82
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +000083def get_active_nodes(test=None):
84 config = get_configuration()
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000085 local_salt_client = init_salt_client()
86
87 skipped_nodes = config.get('skipped_nodes') or []
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +000088 if test:
89 testname = test.split('.')[0]
90 if 'skipped_nodes' in config.get(testname).keys():
91 skipped_nodes += config.get(testname)['skipped_nodes'] or []
Oleksii Zhurba3dbed242017-10-31 19:58:53 +000092 if skipped_nodes != ['']:
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +000093 print "\nNotice: {0} nodes will be skipped".format(skipped_nodes)
94 nodes = local_salt_client.cmd(
Oleksii Zhurba3dbed242017-10-31 19:58:53 +000095 '* and not ' + list_to_target_string(skipped_nodes, 'and not'),
96 'test.ping',
97 expr_form='compound')
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +000098 else:
99 nodes = local_salt_client.cmd('*', 'test.ping')
100 return nodes
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000101
102
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000103def calculate_groups():
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +0000104 config = get_configuration()
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000105 local_salt_client = init_salt_client()
Oleksii Zhurba30122e12018-03-29 14:01:50 -0500106 node_groups = {}
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000107 nodes_names = set ()
108 expr_form = ''
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500109 all_nodes = set(local_salt_client.cmd('*', 'test.ping'))
110 if 'groups' in config.keys() and 'PB_GROUPS' in os.environ.keys() and \
111 os.environ['PB_GROUPS'].lower() != 'false':
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000112 nodes_names.update(config['groups'].keys())
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500113 expr_form = 'compound'
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000114 else:
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500115 for node in all_nodes:
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000116 index = re.search('[0-9]{1,3}$', node.split('.')[0])
117 if index:
118 nodes_names.add(node.split('.')[0][:-len(index.group(0))])
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000119 else:
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000120 nodes_names.add(node)
121 expr_form = 'pcre'
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000122
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500123 gluster_nodes = local_salt_client.cmd('I@salt:control and '
124 'I@glusterfs:server',
125 'test.ping', expr_form='compound')
126 kvm_nodes = local_salt_client.cmd('I@salt:control and not '
127 'I@glusterfs:server',
128 'test.ping', expr_form='compound')
129
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000130 for node_name in nodes_names:
131 skipped_groups = config.get('skipped_groups') or []
132 if node_name in skipped_groups:
133 continue
134 if expr_form == 'pcre':
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500135 nodes = local_salt_client.cmd('{}[0-9]{{1,3}}'.format(node_name),
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000136 'test.ping',
137 expr_form=expr_form)
138 else:
139 nodes = local_salt_client.cmd(config['groups'][node_name],
140 'test.ping',
141 expr_form=expr_form)
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500142 if nodes == {}:
143 continue
144
145 node_groups[node_name]=[x for x in nodes
146 if x not in config['skipped_nodes']
147 if x not in gluster_nodes.keys()
148 if x not in kvm_nodes.keys()]
149 all_nodes = set(all_nodes - set(node_groups[node_name]))
150 if node_groups[node_name] == []:
151 del node_groups[node_name]
152 if kvm_nodes:
153 node_groups['kvm'] = kvm_nodes.keys()
154 node_groups['kvm_gluster'] = gluster_nodes.keys()
155 all_nodes = set(all_nodes - set(kvm_nodes.keys()))
156 all_nodes = set(all_nodes - set(gluster_nodes.keys()))
157 if all_nodes:
158 print ("These nodes were not collected {0}. Check config (groups section)".format(all_nodes))
Oleksii Zhurbad0ae87f2018-03-26 13:36:25 -0500159 return node_groups
Oleksii Zhurbae0dedb52018-01-16 00:55:25 +0000160
161
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +0000162def get_configuration():
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000163 """function returns configuration for environment
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000164 and for test if it's specified"""
165 global_config_file = os.path.join(
166 os.path.dirname(os.path.abspath(__file__)), "../global_config.yaml")
167 with open(global_config_file, 'r') as file:
168 global_config = yaml.load(file)
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +0000169 for param in global_config.keys():
170 if param in os.environ.keys():
171 if ',' in os.environ[param]:
Oleksii Zhurba3dbed242017-10-31 19:58:53 +0000172 global_config[param] = []
Oleksii Zhurbae0668ae2017-10-27 23:58:18 +0000173 for item in os.environ[param].split(','):
174 global_config[param].append(item)
175 else:
Oleksii Zhurba3dbed242017-10-31 19:58:53 +0000176 global_config[param] = os.environ[param]
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000177
178 return global_config