blob: f534aad2606c7268ec9701f8d90f68d4d10c2f59 [file] [log] [blame]
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +00001import pytest
2import json
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +03003import utils
Hanna Arhipova56eab942019-05-06 20:14:18 +03004import logging
Hanna Arhipova2d538412021-08-17 10:44:41 +03005import itertools
6from functools import lru_cache
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +03007
Hanna Arhipova2d538412021-08-17 10:44:41 +03008
9@lru_cache(maxsize=32)
10def targeted_minions(target):
11 """
12 Returns nodes associated with salt target
13 :param target: str, salt target in COMPOUND notation like I@nova:server
14 More here https://docs.saltproject.io/en/latest/topics/targeting/compound.html
15 :return: list of nodes or []
16 """
17 salt_client = pytest.local_salt_client
18 return list(salt_client.test_ping(
19 tgt=target,
20 expr_form='compound'))
21
22
23def is_deb_in_exception(inconsistency_rule, package_name, node_hostname):
24 for salt_target, excluded_packages in inconsistency_rule.items():
25 if package_name in excluded_packages \
26 and node_hostname in targeted_minions(salt_target):
Ekaterina Chernovab4806752019-07-26 16:02:18 +030027 return True
28 return False
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000029
Hanna Arhipova2d538412021-08-17 10:44:41 +030030
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -050031@pytest.mark.full
Oleksii Zhurbad0ae87f2018-03-26 13:36:25 -050032def test_check_package_versions(local_salt_client, nodes_in_group):
Ekaterina Chernovab4806752019-07-26 16:02:18 +030033 """Validate package has same versions on all the nodes.
34 Steps:
35 1) Collect packages for nodes_in_group
36 "salt -C '<group_of_nodes>' cmd.run 'lowpkg.list_pkgs'"
37 2) Exclude nodes without packages and exceptions
Ekaterina Chernova7ea97152019-07-29 17:09:12 +030038 3) Go through each package and save it with version from each node to the
Ekaterina Chernovab4806752019-07-26 16:02:18 +030039 list. Mark 'No version' if package is not found.
Hanna Arhipova2d538412021-08-17 10:44:41 +030040 If package name in the exception list or in inconsistency_rule,
41 ignore it.
Ekaterina Chernovab4806752019-07-26 16:02:18 +030042 4) Compare items in that list - they should be equal and match the amout of nodes
43
44 """
Hanna Arhipova2d538412021-08-17 10:44:41 +030045 salt = local_salt_client
46 # defines packages specific to the nodes
47 inconsistency_rule = {
48 "I@backupninja:server": [
49 "rsync", "sysstat", "xz-utils"],
50 "I@elasticsearch:server": [
51 "python-elasticsearch"],
52 # PROD-30833
53 "I@octavia:manager:controller_worker:loadbalancer_topology:SINGLE": [
54 "netfilter-persistent",
55 "gunicorn",
56 "octavia-worker",
57 "octavia-health-manager",
58 "octavia-housekeeping"]
59 }
Hanna Arhipova8fd295c2019-03-07 13:46:43 +020060 exclude_packages = utils.get_configuration().get("skipped_packages", [])
Hanna Arhipova2d538412021-08-17 10:44:41 +030061
62 group_name, nodes = nodes_in_group
63 packages_versions_by_nodes = salt.cmd(tgt="L@"+','.join(nodes),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050064 fun='lowpkg.list_pkgs',
65 expr_form='compound')
Oleksii Zhurbadad1acc2018-03-26 14:09:38 -050066 # Let's exclude cid01 and dbs01 nodes from this check
Hanna Arhipova2d538412021-08-17 10:44:41 +030067 exclude_nodes = targeted_minions("I@galera:master or I@gerrit:client")
Oleksii Zhurba599801a2019-06-04 17:26:51 -050068
Hanna Arhipova2d538412021-08-17 10:44:41 +030069 total_nodes = [i
70 for i in nodes
71 if i not in exclude_nodes]
Oleksii Zhurba5f768c52018-08-07 17:27:57 -050072 if len(total_nodes) < 2:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000073 pytest.skip("Nothing to compare - only 1 node")
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +000074
Hanna Arhipova2d538412021-08-17 10:44:41 +030075 packages_with_different_versions = dict()
76 packages_names = set(itertools.chain.from_iterable(
77 [packages_versions_by_nodes[node].keys()
78 for node in total_nodes])
79 )
80
Hanna Arhipova8fd295c2019-03-07 13:46:43 +020081 for deb in packages_names:
82 if deb in exclude_packages:
83 continue
Ekaterina Chernovab4806752019-07-26 16:02:18 +030084
Hanna Arhipova2d538412021-08-17 10:44:41 +030085 node_and_version = [
86 (node, packages_versions_by_nodes[node].get(deb, "No package"))
87 for node in total_nodes
88 if not is_deb_in_exception(inconsistency_rule, deb, node)
89 ]
90
91 if set([version for node, version in node_and_version]).__len__() > 1:
92 packages_with_different_versions[deb] = [
93 f"{node}: {version}"
94 for node, version in node_and_version]
95
Dmitriy Kruglova34a3042019-08-20 11:45:35 +020096 assert len(packages_with_different_versions) == 0, (
97 "Non-uniform package versions are installed on '{}' group of nodes:\n"
98 "{}".format(
Hanna Arhipova2d538412021-08-17 10:44:41 +030099 group_name, json.dumps(packages_with_different_versions, indent=4))
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200100 )
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000101
102
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500103@pytest.mark.full
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300104def test_packages_are_latest(local_salt_client, nodes_in_group):
105 config = utils.get_configuration()
106 skip = config.get("test_packages")["skip_test"]
Ievgeniia Zadorozhna0c306fd2019-11-12 16:03:51 +0300107 if skip.lower() == 'true':
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300108 pytest.skip("Test for the latest packages is disabled")
109 skipped_pkg = config.get("test_packages")["skipped_packages"]
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200110 group, nodes = nodes_in_group
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300111 info_salt = local_salt_client.cmd(
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200112 tgt='L@' + ','.join(nodes),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500113 param='apt list --upgradable 2>/dev/null | grep -v Listing',
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300114 expr_form='compound')
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200115 for node in nodes:
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300116 result = []
117 if info_salt[node]:
118 upg_list = info_salt[node].split('\n')
119 for i in upg_list:
120 if i.split('/')[0] not in skipped_pkg:
121 result.append(i)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200122 assert not result, (
123 "Packages are not of latest version on '{}' node:\n{}".format(
124 node, "\n".join(result))
125 )
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300126
127
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500128@pytest.mark.full
Oleksii Zhurbad0ae87f2018-03-26 13:36:25 -0500129def test_check_module_versions(local_salt_client, nodes_in_group):
Ekaterina Chernova7ea97152019-07-29 17:09:12 +0300130 # defines modules specific to the concrete nodes
Hanna Arhipova2d538412021-08-17 10:44:41 +0300131 inconsistency_rule = {"I@elasticsearch:server": ["elasticsearch"]}
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200132 exclude_modules = utils.get_configuration().get("skipped_modules", [])
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200133 group, nodes = nodes_in_group
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000134 pre_check = local_salt_client.cmd(
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200135 tgt="L@"+','.join(nodes),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500136 param='dpkg -l | grep "python-pip "',
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500137 expr_form='compound')
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300138 if list(pre_check.values()).count('') > 0:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000139 pytest.skip("pip is not installed on one or more nodes")
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500140
Hanna Arhipova2d538412021-08-17 10:44:41 +0300141 exclude_nodes = targeted_minions("I@galera:master or I@gerrit:client")
Oleksii Zhurba599801a2019-06-04 17:26:51 -0500142
143 # PROD-30833
144 gtw01 = local_salt_client.pillar_get(
145 param='_param:openstack_gateway_node01_hostname') or 'gtw01'
146 cluster_domain = local_salt_client.pillar_get(
147 param='_param:cluster_domain') or '.local'
148 gtw01 += '.' + cluster_domain
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200149 if gtw01 in nodes:
150 octavia = local_salt_client.cmd(tgt="L@" + ','.join(nodes),
Oleksii Zhurba599801a2019-06-04 17:26:51 -0500151 fun='pillar.get',
152 param='octavia:manager:enabled',
153 expr_form='compound')
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300154 gtws = [gtw for gtw in list(octavia.values()) if gtw]
Oleksii Zhurba599801a2019-06-04 17:26:51 -0500155 if len(gtws) == 1:
156 exclude_nodes.append(gtw01)
157 logging.info("gtw01 node is skipped in test_check_module_versions")
158
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300159 total_nodes = [i for i in list(pre_check.keys()) if i not in exclude_nodes]
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500160
161 if len(total_nodes) < 2:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000162 pytest.skip("Nothing to compare - only 1 node")
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200163 list_of_pip_packages = local_salt_client.cmd(
164 tgt="L@"+','.join(nodes),
165 fun='pip.freeze', expr_form='compound')
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000166
Ekaterina Chernova7ea97152019-07-29 17:09:12 +0300167 nodes_with_packages = []
Oleksii Zhurbaa32d92f2018-03-29 16:22:35 -0500168
Ekaterina Chernova7ea97152019-07-29 17:09:12 +0300169 modules_with_different_versions = []
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200170 packages_names = set()
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000171
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500172 for node in total_nodes:
Ekaterina Chernova7ea97152019-07-29 17:09:12 +0300173 nodes_with_packages.append(node)
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200174 packages_names.update([x.split("=")[0] for x in list_of_pip_packages[node]])
175 list_of_pip_packages[node] = dict([x.split("==") for x in list_of_pip_packages[node]])
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000176
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200177 for deb in packages_names:
178 if deb in exclude_modules:
179 continue
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000180 diff = []
181 row = []
Ekaterina Chernova7ea97152019-07-29 17:09:12 +0300182 for node in nodes_with_packages:
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300183 if deb in list(list_of_pip_packages[node].keys()):
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200184 diff.append(list_of_pip_packages[node][deb])
185 row.append("{}: {}".format(node, list_of_pip_packages[node][deb]))
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000186 else:
187 row.append("{}: No module".format(node))
Ekaterina Chernova7ea97152019-07-29 17:09:12 +0300188 if diff.count(diff[0]) < len(nodes_with_packages):
189 if not is_deb_in_exception(inconsistency_rule, deb, row):
190 row.sort()
191 row.insert(0, deb)
192 modules_with_different_versions.append(row)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200193 assert len(modules_with_different_versions) == 0, (
194 "Non-uniform pip modules are installed on '{}' group of nodes:\n"
195 "{}".format(
196 group, json.dumps(modules_with_different_versions, indent=4))
197 )
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200198
199
200@pytest.mark.full
201def test_restricted_updates_repo(local_salt_client):
202 restricted_repo_enabled = local_salt_client.pillar_get(
203 tgt="I@salt:master",
Hanna Arhipova1d87dbe2021-02-16 19:26:27 +0200204 param='_param:updates_mirantis_login',
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200205 expr_form='compound')
206 if not restricted_repo_enabled:
Hanna Arhipova2d538412021-08-17 10:44:41 +0300207 pytest.skip("This env doesn't require the restricted ubuntu repo")
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200208
209 repos_by_nodes=local_salt_client.cmd(
210 tgt="*",
211 param="apt-cache policy |grep updates.mirantis.com"
212 )
213
Hanna Arhipova1d87dbe2021-02-16 19:26:27 +0200214 assert all(list(repos_by_nodes.values())), \
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200215 "Next nodes don't have updates.mirantis.com in sources.list: {}".\
216 format({node for node, repo
217 in repos_by_nodes.items()
218 if not repo})