You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

595 lines
25 KiB

  1. # Copyright 2016 Mirantis, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. import inventory
  15. from test import support
  16. import unittest
  17. from unittest import mock
  18. from collections import OrderedDict
  19. import sys
  20. path = "./contrib/inventory_builder/"
  21. if path not in sys.path:
  22. sys.path.append(path)
  23. import inventory # noqa
  24. class TestInventoryPrintHostnames(unittest.TestCase):
  25. @mock.patch('ruamel.yaml.YAML.load')
  26. def test_print_hostnames(self, load_mock):
  27. mock_io = mock.mock_open(read_data='')
  28. load_mock.return_value = OrderedDict({'all': {'hosts': {
  29. 'node1': {'ansible_host': '10.90.0.2',
  30. 'ip': '10.90.0.2',
  31. 'access_ip': '10.90.0.2'},
  32. 'node2': {'ansible_host': '10.90.0.3',
  33. 'ip': '10.90.0.3',
  34. 'access_ip': '10.90.0.3'}}}})
  35. with mock.patch('builtins.open', mock_io):
  36. with self.assertRaises(SystemExit) as cm:
  37. with support.captured_stdout() as stdout:
  38. inventory.KubesprayInventory(
  39. changed_hosts=["print_hostnames"],
  40. config_file="file")
  41. self.assertEqual("node1 node2\n", stdout.getvalue())
  42. self.assertEqual(cm.exception.code, 0)
  43. class TestInventory(unittest.TestCase):
  44. @mock.patch('inventory.sys')
  45. def setUp(self, sys_mock):
  46. sys_mock.exit = mock.Mock()
  47. super(TestInventory, self).setUp()
  48. self.data = ['10.90.3.2', '10.90.3.3', '10.90.3.4']
  49. self.inv = inventory.KubesprayInventory()
  50. def test_get_ip_from_opts(self):
  51. optstring = {'ansible_host': '10.90.3.2',
  52. 'ip': '10.90.3.2',
  53. 'access_ip': '10.90.3.2'}
  54. expected = "10.90.3.2"
  55. result = self.inv.get_ip_from_opts(optstring)
  56. self.assertEqual(expected, result)
  57. def test_get_ip_from_opts_invalid(self):
  58. optstring = "notanaddr=value something random!chars:D"
  59. self.assertRaisesRegex(ValueError, "IP parameter not found",
  60. self.inv.get_ip_from_opts, optstring)
  61. def test_ensure_required_groups(self):
  62. groups = ['group1', 'group2']
  63. self.inv.ensure_required_groups(groups)
  64. for group in groups:
  65. self.assertIn(group, self.inv.yaml_config['all']['children'])
  66. def test_get_host_id(self):
  67. hostnames = ['node99', 'no99de01', '01node01', 'node1.domain',
  68. 'node3.xyz123.aaa']
  69. expected = [99, 1, 1, 1, 3]
  70. for hostname, expected in zip(hostnames, expected):
  71. result = self.inv.get_host_id(hostname)
  72. self.assertEqual(expected, result)
  73. def test_get_host_id_invalid(self):
  74. bad_hostnames = ['node', 'no99de', '01node', 'node.111111']
  75. for hostname in bad_hostnames:
  76. self.assertRaisesRegex(ValueError, "Host name must end in an",
  77. self.inv.get_host_id, hostname)
  78. def test_build_hostnames_add_duplicate(self):
  79. changed_hosts = ['10.90.0.2']
  80. expected = OrderedDict([('node3',
  81. {'ansible_host': '10.90.0.2',
  82. 'ip': '10.90.0.2',
  83. 'access_ip': '10.90.0.2'})])
  84. self.inv.yaml_config['all']['hosts'] = expected
  85. result = self.inv.build_hostnames(changed_hosts, True)
  86. self.assertEqual(expected, result)
  87. def test_build_hostnames_add_two(self):
  88. changed_hosts = ['10.90.0.2', '10.90.0.3']
  89. expected = OrderedDict([
  90. ('node1', {'ansible_host': '10.90.0.2',
  91. 'ip': '10.90.0.2',
  92. 'access_ip': '10.90.0.2'}),
  93. ('node2', {'ansible_host': '10.90.0.3',
  94. 'ip': '10.90.0.3',
  95. 'access_ip': '10.90.0.3'})])
  96. self.inv.yaml_config['all']['hosts'] = OrderedDict()
  97. result = self.inv.build_hostnames(changed_hosts)
  98. self.assertEqual(expected, result)
  99. def test_build_hostnames_add_three(self):
  100. changed_hosts = ['10.90.0.2', '10.90.0.3', '10.90.0.4']
  101. expected = OrderedDict([
  102. ('node1', {'ansible_host': '10.90.0.2',
  103. 'ip': '10.90.0.2',
  104. 'access_ip': '10.90.0.2'}),
  105. ('node2', {'ansible_host': '10.90.0.3',
  106. 'ip': '10.90.0.3',
  107. 'access_ip': '10.90.0.3'}),
  108. ('node3', {'ansible_host': '10.90.0.4',
  109. 'ip': '10.90.0.4',
  110. 'access_ip': '10.90.0.4'})])
  111. result = self.inv.build_hostnames(changed_hosts)
  112. self.assertEqual(expected, result)
  113. def test_build_hostnames_add_one(self):
  114. changed_hosts = ['10.90.0.2']
  115. expected = OrderedDict([('node1',
  116. {'ansible_host': '10.90.0.2',
  117. 'ip': '10.90.0.2',
  118. 'access_ip': '10.90.0.2'})])
  119. result = self.inv.build_hostnames(changed_hosts)
  120. self.assertEqual(expected, result)
  121. def test_build_hostnames_delete_first(self):
  122. changed_hosts = ['-10.90.0.2']
  123. existing_hosts = OrderedDict([
  124. ('node1', {'ansible_host': '10.90.0.2',
  125. 'ip': '10.90.0.2',
  126. 'access_ip': '10.90.0.2'}),
  127. ('node2', {'ansible_host': '10.90.0.3',
  128. 'ip': '10.90.0.3',
  129. 'access_ip': '10.90.0.3'})])
  130. self.inv.yaml_config['all']['hosts'] = existing_hosts
  131. expected = OrderedDict([
  132. ('node2', {'ansible_host': '10.90.0.3',
  133. 'ip': '10.90.0.3',
  134. 'access_ip': '10.90.0.3'})])
  135. result = self.inv.build_hostnames(changed_hosts, True)
  136. self.assertEqual(expected, result)
  137. def test_build_hostnames_delete_by_hostname(self):
  138. changed_hosts = ['-node1']
  139. existing_hosts = OrderedDict([
  140. ('node1', {'ansible_host': '10.90.0.2',
  141. 'ip': '10.90.0.2',
  142. 'access_ip': '10.90.0.2'}),
  143. ('node2', {'ansible_host': '10.90.0.3',
  144. 'ip': '10.90.0.3',
  145. 'access_ip': '10.90.0.3'})])
  146. self.inv.yaml_config['all']['hosts'] = existing_hosts
  147. expected = OrderedDict([
  148. ('node2', {'ansible_host': '10.90.0.3',
  149. 'ip': '10.90.0.3',
  150. 'access_ip': '10.90.0.3'})])
  151. result = self.inv.build_hostnames(changed_hosts, True)
  152. self.assertEqual(expected, result)
  153. def test_exists_hostname_positive(self):
  154. hostname = 'node1'
  155. expected = True
  156. existing_hosts = OrderedDict([
  157. ('node1', {'ansible_host': '10.90.0.2',
  158. 'ip': '10.90.0.2',
  159. 'access_ip': '10.90.0.2'}),
  160. ('node2', {'ansible_host': '10.90.0.3',
  161. 'ip': '10.90.0.3',
  162. 'access_ip': '10.90.0.3'})])
  163. result = self.inv.exists_hostname(existing_hosts, hostname)
  164. self.assertEqual(expected, result)
  165. def test_exists_hostname_negative(self):
  166. hostname = 'node99'
  167. expected = False
  168. existing_hosts = OrderedDict([
  169. ('node1', {'ansible_host': '10.90.0.2',
  170. 'ip': '10.90.0.2',
  171. 'access_ip': '10.90.0.2'}),
  172. ('node2', {'ansible_host': '10.90.0.3',
  173. 'ip': '10.90.0.3',
  174. 'access_ip': '10.90.0.3'})])
  175. result = self.inv.exists_hostname(existing_hosts, hostname)
  176. self.assertEqual(expected, result)
  177. def test_exists_ip_positive(self):
  178. ip = '10.90.0.2'
  179. expected = True
  180. existing_hosts = OrderedDict([
  181. ('node1', {'ansible_host': '10.90.0.2',
  182. 'ip': '10.90.0.2',
  183. 'access_ip': '10.90.0.2'}),
  184. ('node2', {'ansible_host': '10.90.0.3',
  185. 'ip': '10.90.0.3',
  186. 'access_ip': '10.90.0.3'})])
  187. result = self.inv.exists_ip(existing_hosts, ip)
  188. self.assertEqual(expected, result)
  189. def test_exists_ip_negative(self):
  190. ip = '10.90.0.200'
  191. expected = False
  192. existing_hosts = OrderedDict([
  193. ('node1', {'ansible_host': '10.90.0.2',
  194. 'ip': '10.90.0.2',
  195. 'access_ip': '10.90.0.2'}),
  196. ('node2', {'ansible_host': '10.90.0.3',
  197. 'ip': '10.90.0.3',
  198. 'access_ip': '10.90.0.3'})])
  199. result = self.inv.exists_ip(existing_hosts, ip)
  200. self.assertEqual(expected, result)
  201. def test_delete_host_by_ip_positive(self):
  202. ip = '10.90.0.2'
  203. expected = OrderedDict([
  204. ('node2', {'ansible_host': '10.90.0.3',
  205. 'ip': '10.90.0.3',
  206. 'access_ip': '10.90.0.3'})])
  207. existing_hosts = OrderedDict([
  208. ('node1', {'ansible_host': '10.90.0.2',
  209. 'ip': '10.90.0.2',
  210. 'access_ip': '10.90.0.2'}),
  211. ('node2', {'ansible_host': '10.90.0.3',
  212. 'ip': '10.90.0.3',
  213. 'access_ip': '10.90.0.3'})])
  214. self.inv.delete_host_by_ip(existing_hosts, ip)
  215. self.assertEqual(expected, existing_hosts)
  216. def test_delete_host_by_ip_negative(self):
  217. ip = '10.90.0.200'
  218. existing_hosts = OrderedDict([
  219. ('node1', {'ansible_host': '10.90.0.2',
  220. 'ip': '10.90.0.2',
  221. 'access_ip': '10.90.0.2'}),
  222. ('node2', {'ansible_host': '10.90.0.3',
  223. 'ip': '10.90.0.3',
  224. 'access_ip': '10.90.0.3'})])
  225. self.assertRaisesRegex(ValueError, "Unable to find host",
  226. self.inv.delete_host_by_ip, existing_hosts, ip)
  227. def test_purge_invalid_hosts(self):
  228. proper_hostnames = ['node1', 'node2']
  229. bad_host = 'doesnotbelong2'
  230. existing_hosts = OrderedDict([
  231. ('node1', {'ansible_host': '10.90.0.2',
  232. 'ip': '10.90.0.2',
  233. 'access_ip': '10.90.0.2'}),
  234. ('node2', {'ansible_host': '10.90.0.3',
  235. 'ip': '10.90.0.3',
  236. 'access_ip': '10.90.0.3'}),
  237. ('doesnotbelong2', {'whateveropts=ilike'})])
  238. self.inv.yaml_config['all']['hosts'] = existing_hosts
  239. self.inv.purge_invalid_hosts(proper_hostnames)
  240. self.assertNotIn(
  241. bad_host, self.inv.yaml_config['all']['hosts'].keys())
  242. def test_add_host_to_group(self):
  243. group = 'etcd'
  244. host = 'node1'
  245. opts = {'ip': '10.90.0.2'}
  246. self.inv.add_host_to_group(group, host, opts)
  247. self.assertEqual(
  248. self.inv.yaml_config['all']['children'][group]['hosts'].get(host),
  249. None)
  250. def test_set_kube_control_plane(self):
  251. group = 'kube_control_plane'
  252. host = 'node1'
  253. self.inv.set_kube_control_plane([host])
  254. self.assertIn(
  255. host, self.inv.yaml_config['all']['children'][group]['hosts'])
  256. def test_set_all(self):
  257. hosts = OrderedDict([
  258. ('node1', 'opt1'),
  259. ('node2', 'opt2')])
  260. self.inv.set_all(hosts)
  261. for host, opt in hosts.items():
  262. self.assertEqual(
  263. self.inv.yaml_config['all']['hosts'].get(host), opt)
  264. def test_set_k8s_cluster(self):
  265. group = 'k8s_cluster'
  266. expected_hosts = ['kube_node', 'kube_control_plane']
  267. self.inv.set_k8s_cluster()
  268. for host in expected_hosts:
  269. self.assertIn(
  270. host,
  271. self.inv.yaml_config['all']['children'][group]['children'])
  272. def test_set_kube_node(self):
  273. group = 'kube_node'
  274. host = 'node1'
  275. self.inv.set_kube_node([host])
  276. self.assertIn(
  277. host, self.inv.yaml_config['all']['children'][group]['hosts'])
  278. def test_set_etcd(self):
  279. group = 'etcd'
  280. host = 'node1'
  281. self.inv.set_etcd([host])
  282. self.assertIn(
  283. host, self.inv.yaml_config['all']['children'][group]['hosts'])
  284. def test_scale_scenario_one(self):
  285. num_nodes = 50
  286. hosts = OrderedDict()
  287. for hostid in range(1, num_nodes+1):
  288. hosts["node" + str(hostid)] = ""
  289. self.inv.set_all(hosts)
  290. self.inv.set_etcd(list(hosts.keys())[0:3])
  291. self.inv.set_kube_control_plane(list(hosts.keys())[0:2])
  292. self.inv.set_kube_node(hosts.keys())
  293. for h in range(3):
  294. self.assertFalse(
  295. list(hosts.keys())[h] in
  296. self.inv.yaml_config['all']['children']['kube_node']['hosts'])
  297. def test_scale_scenario_two(self):
  298. num_nodes = 500
  299. hosts = OrderedDict()
  300. for hostid in range(1, num_nodes+1):
  301. hosts["node" + str(hostid)] = ""
  302. self.inv.set_all(hosts)
  303. self.inv.set_etcd(list(hosts.keys())[0:3])
  304. self.inv.set_kube_control_plane(list(hosts.keys())[3:5])
  305. self.inv.set_kube_node(hosts.keys())
  306. for h in range(5):
  307. self.assertFalse(
  308. list(hosts.keys())[h] in
  309. self.inv.yaml_config['all']['children']['kube_node']['hosts'])
  310. def test_range2ips_range(self):
  311. changed_hosts = ['10.90.0.2', '10.90.0.4-10.90.0.6', '10.90.0.8']
  312. expected = ['10.90.0.2',
  313. '10.90.0.4',
  314. '10.90.0.5',
  315. '10.90.0.6',
  316. '10.90.0.8']
  317. result = self.inv.range2ips(changed_hosts)
  318. self.assertEqual(expected, result)
  319. def test_range2ips_incorrect_range(self):
  320. host_range = ['10.90.0.4-a.9b.c.e']
  321. self.assertRaisesRegex(Exception, "Range of ip_addresses isn't valid",
  322. self.inv.range2ips, host_range)
  323. def test_build_hostnames_create_with_one_different_ips(self):
  324. changed_hosts = ['10.90.0.2,192.168.0.2']
  325. expected = OrderedDict([('node1',
  326. {'ansible_host': '192.168.0.2',
  327. 'ip': '10.90.0.2',
  328. 'access_ip': '192.168.0.2'})])
  329. result = self.inv.build_hostnames(changed_hosts)
  330. self.assertEqual(expected, result)
  331. def test_build_hostnames_create_with_two_different_ips(self):
  332. changed_hosts = ['10.90.0.2,192.168.0.2', '10.90.0.3,192.168.0.3']
  333. expected = OrderedDict([
  334. ('node1', {'ansible_host': '192.168.0.2',
  335. 'ip': '10.90.0.2',
  336. 'access_ip': '192.168.0.2'}),
  337. ('node2', {'ansible_host': '192.168.0.3',
  338. 'ip': '10.90.0.3',
  339. 'access_ip': '192.168.0.3'})])
  340. result = self.inv.build_hostnames(changed_hosts)
  341. self.assertEqual(expected, result)
  342. def test_build_hostnames_create_with_three_different_ips(self):
  343. changed_hosts = ['10.90.0.2,192.168.0.2',
  344. '10.90.0.3,192.168.0.3',
  345. '10.90.0.4,192.168.0.4']
  346. expected = OrderedDict([
  347. ('node1', {'ansible_host': '192.168.0.2',
  348. 'ip': '10.90.0.2',
  349. 'access_ip': '192.168.0.2'}),
  350. ('node2', {'ansible_host': '192.168.0.3',
  351. 'ip': '10.90.0.3',
  352. 'access_ip': '192.168.0.3'}),
  353. ('node3', {'ansible_host': '192.168.0.4',
  354. 'ip': '10.90.0.4',
  355. 'access_ip': '192.168.0.4'})])
  356. result = self.inv.build_hostnames(changed_hosts)
  357. self.assertEqual(expected, result)
  358. def test_build_hostnames_overwrite_one_with_different_ips(self):
  359. changed_hosts = ['10.90.0.2,192.168.0.2']
  360. expected = OrderedDict([('node1',
  361. {'ansible_host': '192.168.0.2',
  362. 'ip': '10.90.0.2',
  363. 'access_ip': '192.168.0.2'})])
  364. existing = OrderedDict([('node5',
  365. {'ansible_host': '192.168.0.5',
  366. 'ip': '10.90.0.5',
  367. 'access_ip': '192.168.0.5'})])
  368. self.inv.yaml_config['all']['hosts'] = existing
  369. result = self.inv.build_hostnames(changed_hosts)
  370. self.assertEqual(expected, result)
  371. def test_build_hostnames_overwrite_three_with_different_ips(self):
  372. changed_hosts = ['10.90.0.2,192.168.0.2']
  373. expected = OrderedDict([('node1',
  374. {'ansible_host': '192.168.0.2',
  375. 'ip': '10.90.0.2',
  376. 'access_ip': '192.168.0.2'})])
  377. existing = OrderedDict([
  378. ('node3', {'ansible_host': '192.168.0.3',
  379. 'ip': '10.90.0.3',
  380. 'access_ip': '192.168.0.3'}),
  381. ('node4', {'ansible_host': '192.168.0.4',
  382. 'ip': '10.90.0.4',
  383. 'access_ip': '192.168.0.4'}),
  384. ('node5', {'ansible_host': '192.168.0.5',
  385. 'ip': '10.90.0.5',
  386. 'access_ip': '192.168.0.5'})])
  387. self.inv.yaml_config['all']['hosts'] = existing
  388. result = self.inv.build_hostnames(changed_hosts)
  389. self.assertEqual(expected, result)
  390. def test_build_hostnames_different_ips_add_duplicate(self):
  391. changed_hosts = ['10.90.0.2,192.168.0.2']
  392. expected = OrderedDict([('node3',
  393. {'ansible_host': '192.168.0.2',
  394. 'ip': '10.90.0.2',
  395. 'access_ip': '192.168.0.2'})])
  396. existing = expected
  397. self.inv.yaml_config['all']['hosts'] = existing
  398. result = self.inv.build_hostnames(changed_hosts, True)
  399. self.assertEqual(expected, result)
  400. def test_build_hostnames_add_two_different_ips_into_one_existing(self):
  401. changed_hosts = ['10.90.0.3,192.168.0.3', '10.90.0.4,192.168.0.4']
  402. expected = OrderedDict([
  403. ('node2', {'ansible_host': '192.168.0.2',
  404. 'ip': '10.90.0.2',
  405. 'access_ip': '192.168.0.2'}),
  406. ('node3', {'ansible_host': '192.168.0.3',
  407. 'ip': '10.90.0.3',
  408. 'access_ip': '192.168.0.3'}),
  409. ('node4', {'ansible_host': '192.168.0.4',
  410. 'ip': '10.90.0.4',
  411. 'access_ip': '192.168.0.4'})])
  412. existing = OrderedDict([
  413. ('node2', {'ansible_host': '192.168.0.2',
  414. 'ip': '10.90.0.2',
  415. 'access_ip': '192.168.0.2'})])
  416. self.inv.yaml_config['all']['hosts'] = existing
  417. result = self.inv.build_hostnames(changed_hosts, True)
  418. self.assertEqual(expected, result)
  419. def test_build_hostnames_add_two_different_ips_into_two_existing(self):
  420. changed_hosts = ['10.90.0.4,192.168.0.4', '10.90.0.5,192.168.0.5']
  421. expected = OrderedDict([
  422. ('node2', {'ansible_host': '192.168.0.2',
  423. 'ip': '10.90.0.2',
  424. 'access_ip': '192.168.0.2'}),
  425. ('node3', {'ansible_host': '192.168.0.3',
  426. 'ip': '10.90.0.3',
  427. 'access_ip': '192.168.0.3'}),
  428. ('node4', {'ansible_host': '192.168.0.4',
  429. 'ip': '10.90.0.4',
  430. 'access_ip': '192.168.0.4'}),
  431. ('node5', {'ansible_host': '192.168.0.5',
  432. 'ip': '10.90.0.5',
  433. 'access_ip': '192.168.0.5'})])
  434. existing = OrderedDict([
  435. ('node2', {'ansible_host': '192.168.0.2',
  436. 'ip': '10.90.0.2',
  437. 'access_ip': '192.168.0.2'}),
  438. ('node3', {'ansible_host': '192.168.0.3',
  439. 'ip': '10.90.0.3',
  440. 'access_ip': '192.168.0.3'})])
  441. self.inv.yaml_config['all']['hosts'] = existing
  442. result = self.inv.build_hostnames(changed_hosts, True)
  443. self.assertEqual(expected, result)
  444. def test_build_hostnames_add_two_different_ips_into_three_existing(self):
  445. changed_hosts = ['10.90.0.5,192.168.0.5', '10.90.0.6,192.168.0.6']
  446. expected = OrderedDict([
  447. ('node2', {'ansible_host': '192.168.0.2',
  448. 'ip': '10.90.0.2',
  449. 'access_ip': '192.168.0.2'}),
  450. ('node3', {'ansible_host': '192.168.0.3',
  451. 'ip': '10.90.0.3',
  452. 'access_ip': '192.168.0.3'}),
  453. ('node4', {'ansible_host': '192.168.0.4',
  454. 'ip': '10.90.0.4',
  455. 'access_ip': '192.168.0.4'}),
  456. ('node5', {'ansible_host': '192.168.0.5',
  457. 'ip': '10.90.0.5',
  458. 'access_ip': '192.168.0.5'}),
  459. ('node6', {'ansible_host': '192.168.0.6',
  460. 'ip': '10.90.0.6',
  461. 'access_ip': '192.168.0.6'})])
  462. existing = OrderedDict([
  463. ('node2', {'ansible_host': '192.168.0.2',
  464. 'ip': '10.90.0.2',
  465. 'access_ip': '192.168.0.2'}),
  466. ('node3', {'ansible_host': '192.168.0.3',
  467. 'ip': '10.90.0.3',
  468. 'access_ip': '192.168.0.3'}),
  469. ('node4', {'ansible_host': '192.168.0.4',
  470. 'ip': '10.90.0.4',
  471. 'access_ip': '192.168.0.4'})])
  472. self.inv.yaml_config['all']['hosts'] = existing
  473. result = self.inv.build_hostnames(changed_hosts, True)
  474. self.assertEqual(expected, result)
  475. # Add two IP addresses into a config that has
  476. # three already defined IP addresses. One of the IP addresses
  477. # is a duplicate.
  478. def test_build_hostnames_add_two_duplicate_one_overlap(self):
  479. changed_hosts = ['10.90.0.4,192.168.0.4', '10.90.0.5,192.168.0.5']
  480. expected = OrderedDict([
  481. ('node2', {'ansible_host': '192.168.0.2',
  482. 'ip': '10.90.0.2',
  483. 'access_ip': '192.168.0.2'}),
  484. ('node3', {'ansible_host': '192.168.0.3',
  485. 'ip': '10.90.0.3',
  486. 'access_ip': '192.168.0.3'}),
  487. ('node4', {'ansible_host': '192.168.0.4',
  488. 'ip': '10.90.0.4',
  489. 'access_ip': '192.168.0.4'}),
  490. ('node5', {'ansible_host': '192.168.0.5',
  491. 'ip': '10.90.0.5',
  492. 'access_ip': '192.168.0.5'})])
  493. existing = OrderedDict([
  494. ('node2', {'ansible_host': '192.168.0.2',
  495. 'ip': '10.90.0.2',
  496. 'access_ip': '192.168.0.2'}),
  497. ('node3', {'ansible_host': '192.168.0.3',
  498. 'ip': '10.90.0.3',
  499. 'access_ip': '192.168.0.3'}),
  500. ('node4', {'ansible_host': '192.168.0.4',
  501. 'ip': '10.90.0.4',
  502. 'access_ip': '192.168.0.4'})])
  503. self.inv.yaml_config['all']['hosts'] = existing
  504. result = self.inv.build_hostnames(changed_hosts, True)
  505. self.assertEqual(expected, result)
  506. # Add two duplicate IP addresses into a config that has
  507. # three already defined IP addresses
  508. def test_build_hostnames_add_two_duplicate_two_overlap(self):
  509. changed_hosts = ['10.90.0.3,192.168.0.3', '10.90.0.4,192.168.0.4']
  510. expected = OrderedDict([
  511. ('node2', {'ansible_host': '192.168.0.2',
  512. 'ip': '10.90.0.2',
  513. 'access_ip': '192.168.0.2'}),
  514. ('node3', {'ansible_host': '192.168.0.3',
  515. 'ip': '10.90.0.3',
  516. 'access_ip': '192.168.0.3'}),
  517. ('node4', {'ansible_host': '192.168.0.4',
  518. 'ip': '10.90.0.4',
  519. 'access_ip': '192.168.0.4'})])
  520. existing = OrderedDict([
  521. ('node2', {'ansible_host': '192.168.0.2',
  522. 'ip': '10.90.0.2',
  523. 'access_ip': '192.168.0.2'}),
  524. ('node3', {'ansible_host': '192.168.0.3',
  525. 'ip': '10.90.0.3',
  526. 'access_ip': '192.168.0.3'}),
  527. ('node4', {'ansible_host': '192.168.0.4',
  528. 'ip': '10.90.0.4',
  529. 'access_ip': '192.168.0.4'})])
  530. self.inv.yaml_config['all']['hosts'] = existing
  531. result = self.inv.build_hostnames(changed_hosts, True)
  532. self.assertEqual(expected, result)