blob: dea9a2c7bc9db64042854f2aaa000ee097b79cef [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.
Hanna Arhipova035dea42021-08-19 12:24:08 +030042 4) Compare items in that list - they should be equal and match the
43 amount of nodes
Ekaterina Chernovab4806752019-07-26 16:02:18 +030044
45 """
Hanna Arhipova2d538412021-08-17 10:44:41 +030046 salt = local_salt_client
47 # defines packages specific to the nodes
48 inconsistency_rule = {
49 "I@backupninja:server": [
50 "rsync", "sysstat", "xz-utils"],
51 "I@elasticsearch:server": [
52 "python-elasticsearch"],
Taras Khlivnyak1f9375f2022-02-23 10:57:11 +020053 # PROD-30833, PROD-36718
Hanna Arhipova2d538412021-08-17 10:44:41 +030054 "I@octavia:manager:controller_worker:loadbalancer_topology:SINGLE": [
55 "netfilter-persistent",
56 "gunicorn",
57 "octavia-worker",
58 "octavia-health-manager",
Hanna Arhipovaae2e05b2021-08-18 10:47:39 +030059 "octavia-housekeeping",
Hanna Arhipovafb3bc582021-09-22 14:30:52 +030060 "python-castellan",
Hanna Arhipovaae2e05b2021-08-18 10:47:39 +030061 'python-automaton',
62 'python-setproctitle',
63 'python-glanceclient',
64 'libnss3-nssdb',
65 'python-json-pointer',
66 'debootstrap',
67 'python-cotyledon',
68 'librbd1',
69 'qemu-block-extra:amd64',
70 'python-diskimage-builder',
71 'liburcu4:amd64',
72 'python-networkx',
73 'librados2',
74 'kpartx',
75 'python-taskflow',
76 'libnss3:amd64',
77 'libibverbs1',
78 'python-itsdangerous',
79 'liblttng-ust0:amd64',
80 'python-wsme',
81 'python-werkzeug',
82 'liblttng-ust-ctl2:amd64',
83 'python-gunicorn',
84 'python-octavia',
85 'python-warlock',
86 'python-barbicanclient',
87 'iptables-persistent',
88 'python-psycopg2',
89 'octavia-common',
90 'python-flask',
91 'libpq5:amd64',
92 'python-dib-utils',
93 'python-jsonpatch',
94 'libnspr4:amd64',
95 'qemu-utils',
96 'python-pyasn1-modules',
97 'libonig2:amd64',
98 'jq',
99 'libaio1:amd64',
100 'python-kazoo',
101 'python-ipaddr',
Taras Khlivnyak1f9375f2022-02-23 10:57:11 +0200102 'libiscsi2:amd64',
103 'python-pyasn1',
104 'python3-pyasn1'
105 ]
Hanna Arhipova035dea42021-08-19 12:24:08 +0300106 }
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200107 exclude_packages = utils.get_configuration().get("skipped_packages", [])
Hanna Arhipova2d538412021-08-17 10:44:41 +0300108
109 group_name, nodes = nodes_in_group
110 packages_versions_by_nodes = salt.cmd(tgt="L@"+','.join(nodes),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500111 fun='lowpkg.list_pkgs',
112 expr_form='compound')
Oleksii Zhurbadad1acc2018-03-26 14:09:38 -0500113 # Let's exclude cid01 and dbs01 nodes from this check
Hanna Arhipova2d538412021-08-17 10:44:41 +0300114 exclude_nodes = targeted_minions("I@galera:master or I@gerrit:client")
Oleksii Zhurba599801a2019-06-04 17:26:51 -0500115
Hanna Arhipova2d538412021-08-17 10:44:41 +0300116 total_nodes = [i
117 for i in nodes
118 if i not in exclude_nodes]
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500119 if len(total_nodes) < 2:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000120 pytest.skip("Nothing to compare - only 1 node")
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000121
Hanna Arhipova2d538412021-08-17 10:44:41 +0300122 packages_with_different_versions = dict()
123 packages_names = set(itertools.chain.from_iterable(
124 [packages_versions_by_nodes[node].keys()
125 for node in total_nodes])
126 )
127
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200128 for deb in packages_names:
129 if deb in exclude_packages:
130 continue
Ekaterina Chernovab4806752019-07-26 16:02:18 +0300131
Hanna Arhipova2d538412021-08-17 10:44:41 +0300132 node_and_version = [
133 (node, packages_versions_by_nodes[node].get(deb, "No package"))
134 for node in total_nodes
135 if not is_deb_in_exception(inconsistency_rule, deb, node)
136 ]
137
138 if set([version for node, version in node_and_version]).__len__() > 1:
139 packages_with_different_versions[deb] = [
Hanna Arhipova035dea42021-08-19 12:24:08 +0300140 "{}: {}".format(node, version)
Hanna Arhipova2d538412021-08-17 10:44:41 +0300141 for node, version in node_and_version]
142
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200143 assert len(packages_with_different_versions) == 0, (
144 "Non-uniform package versions are installed on '{}' group of nodes:\n"
145 "{}".format(
Hanna Arhipova2d538412021-08-17 10:44:41 +0300146 group_name, json.dumps(packages_with_different_versions, indent=4))
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200147 )
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000148
149
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500150@pytest.mark.full
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300151def test_packages_are_latest(local_salt_client, nodes_in_group):
152 config = utils.get_configuration()
153 skip = config.get("test_packages")["skip_test"]
Ievgeniia Zadorozhna0c306fd2019-11-12 16:03:51 +0300154 if skip.lower() == 'true':
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300155 pytest.skip("Test for the latest packages is disabled")
156 skipped_pkg = config.get("test_packages")["skipped_packages"]
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200157 group, nodes = nodes_in_group
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300158 info_salt = local_salt_client.cmd(
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200159 tgt='L@' + ','.join(nodes),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500160 param='apt list --upgradable 2>/dev/null | grep -v Listing',
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300161 expr_form='compound')
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200162 for node in nodes:
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300163 result = []
164 if info_salt[node]:
165 upg_list = info_salt[node].split('\n')
166 for i in upg_list:
167 if i.split('/')[0] not in skipped_pkg:
168 result.append(i)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200169 assert not result, (
170 "Packages are not of latest version on '{}' node:\n{}".format(
171 node, "\n".join(result))
172 )
Ievgeniia Zadorozhna6baf7872019-01-25 19:09:30 +0300173
174
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500175@pytest.mark.full
Oleksii Zhurbad0ae87f2018-03-26 13:36:25 -0500176def test_check_module_versions(local_salt_client, nodes_in_group):
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300177 # defines modules specific to the nodes
178 inconsistency_rule = {
179 "I@elasticsearch:server": ["elasticsearch"],
Taras Khlivnyak1f9375f2022-02-23 10:57:11 +0200180 # PROD-30833
Hanna Arhipovaae2e05b2021-08-18 10:47:39 +0300181 "I@octavia:manager:controller_worker:loadbalancer_topology:SINGLE": [
182 'octavia',
183 'setproctitle',
184 'automaton',
185 'warlock',
186 'python-glanceclient',
187 'taskflow',
188 'diskimage-builder',
189 'pyasn1-modules',
190 'python-barbicanclient',
191 'WSME',
192 'jsonpatch',
193 'cotyledon',
194 'dib-utils',
195 'itsdangerous',
196 'kazoo',
197 'psycopg2',
198 'Flask',
199 'networkx',
200 'Werkzeug',
201 'jsonpointer',
202 'gunicorn',
Hanna Arhipovafb3bc582021-09-22 14:30:52 +0300203 'ipaddr',
Taras Khlivnyak1f9375f2022-02-23 10:57:11 +0200204 'castellan'
Hanna Arhipovafb3bc582021-09-22 14:30:52 +0300205 ]
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300206 }
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200207 exclude_modules = utils.get_configuration().get("skipped_modules", [])
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200208 group, nodes = nodes_in_group
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300209
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000210 pre_check = local_salt_client.cmd(
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300211 tgt="L@{nodes}".format(nodes=','.join(nodes)),
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500212 param='dpkg -l | grep "python-pip "',
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500213 expr_form='compound')
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300214 exclude_nodes = targeted_minions("I@galera:master or I@gerrit:client")
Ekaterina Chernovae32e3f92019-11-12 14:56:03 +0300215 if list(pre_check.values()).count('') > 0:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000216 pytest.skip("pip is not installed on one or more nodes")
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500217
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300218 total_nodes = [node
219 for node in nodes
220 if node not in exclude_nodes]
Oleksii Zhurba5f768c52018-08-07 17:27:57 -0500221 if len(total_nodes) < 2:
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000222 pytest.skip("Nothing to compare - only 1 node")
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200223 list_of_pip_packages = local_salt_client.cmd(
224 tgt="L@"+','.join(nodes),
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300225 fun='pip.list', expr_form='compound')
Oleksii Zhurbaa10927b2017-09-27 22:09:23 +0000226
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300227 modules_with_different_versions = dict()
228 packages_names = set(itertools.chain.from_iterable(
229 list_of_pip_packages.values()
230 ))
Oleksii Zhurbaa32d92f2018-03-29 16:22:35 -0500231
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300232 for package in packages_names:
233 if package in exclude_modules:
Hanna Arhipova8fd295c2019-03-07 13:46:43 +0200234 continue
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300235 node_and_version = [
236 (node, list_of_pip_packages[node].get(package, "No module"))
237 for node in total_nodes
238 if not is_deb_in_exception(inconsistency_rule, package, node)
239 ]
240
241 if set([version for node, version in node_and_version]).__len__() > 1:
242 modules_with_different_versions[package] = [
Hanna Arhipova035dea42021-08-19 12:24:08 +0300243 "{}: {}".format(node, version)
Hanna Arhipovae7ebae62021-08-17 20:29:38 +0300244 for node, version in node_and_version
245 ]
246
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200247 assert len(modules_with_different_versions) == 0, (
248 "Non-uniform pip modules are installed on '{}' group of nodes:\n"
249 "{}".format(
250 group, json.dumps(modules_with_different_versions, indent=4))
251 )
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200252
253
254@pytest.mark.full
255def test_restricted_updates_repo(local_salt_client):
256 restricted_repo_enabled = local_salt_client.pillar_get(
257 tgt="I@salt:master",
Hanna Arhipova1d87dbe2021-02-16 19:26:27 +0200258 param='_param:updates_mirantis_login',
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200259 expr_form='compound')
260 if not restricted_repo_enabled:
Hanna Arhipova2d538412021-08-17 10:44:41 +0300261 pytest.skip("This env doesn't require the restricted ubuntu repo")
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200262
263 repos_by_nodes=local_salt_client.cmd(
264 tgt="*",
265 param="apt-cache policy |grep updates.mirantis.com"
Hanna Arhipova035dea42021-08-19 12:24:08 +0300266 )
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200267
Hanna Arhipova1d87dbe2021-02-16 19:26:27 +0200268 assert all(list(repos_by_nodes.values())), \
Hanna Arhipova5a56ae62021-02-11 16:27:52 +0200269 "Next nodes don't have updates.mirantis.com in sources.list: {}".\
270 format({node for node, repo
271 in repos_by_nodes.items()
Hanna Arhipova035dea42021-08-19 12:24:08 +0300272 if not repo})