cli_installer_tests.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940
  1. # TODO: Temporarily disabled due to importing old code into openshift-ansible
  2. # repo. We will work on these over time.
  3. # pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name
  4. import copy
  5. import os
  6. import ConfigParser
  7. import ooinstall.cli_installer as cli
  8. from test.fixture import OOCliFixture, SAMPLE_CONFIG, build_input, read_yaml
  9. from mock import patch
  10. MOCK_FACTS = {
  11. '10.0.0.1': {
  12. 'common': {
  13. 'ip': '10.0.0.1',
  14. 'public_ip': '10.0.0.1',
  15. 'hostname': 'master-private.example.com',
  16. 'public_hostname': 'master.example.com'
  17. }
  18. },
  19. '10.0.0.2': {
  20. 'common': {
  21. 'ip': '10.0.0.2',
  22. 'public_ip': '10.0.0.2',
  23. 'hostname': 'node1-private.example.com',
  24. 'public_hostname': 'node1.example.com'
  25. }
  26. },
  27. '10.0.0.3': {
  28. 'common': {
  29. 'ip': '10.0.0.3',
  30. 'public_ip': '10.0.0.3',
  31. 'hostname': 'node2-private.example.com',
  32. 'public_hostname': 'node2.example.com'
  33. }
  34. },
  35. }
  36. MOCK_FACTS_QUICKHA = {
  37. '10.0.0.1': {
  38. 'common': {
  39. 'ip': '10.0.0.1',
  40. 'public_ip': '10.0.0.1',
  41. 'hostname': 'master-private.example.com',
  42. 'public_hostname': 'master.example.com'
  43. }
  44. },
  45. '10.0.0.2': {
  46. 'common': {
  47. 'ip': '10.0.0.2',
  48. 'public_ip': '10.0.0.2',
  49. 'hostname': 'node1-private.example.com',
  50. 'public_hostname': 'node1.example.com'
  51. }
  52. },
  53. '10.0.0.3': {
  54. 'common': {
  55. 'ip': '10.0.0.3',
  56. 'public_ip': '10.0.0.3',
  57. 'hostname': 'node2-private.example.com',
  58. 'public_hostname': 'node2.example.com'
  59. }
  60. },
  61. '10.0.0.4': {
  62. 'common': {
  63. 'ip': '10.0.0.4',
  64. 'public_ip': '10.0.0.4',
  65. 'hostname': 'proxy-private.example.com',
  66. 'public_hostname': 'proxy.example.com'
  67. }
  68. },
  69. }
  70. # Missing connect_to on some hosts:
  71. BAD_CONFIG = """
  72. variant: %s
  73. ansible_ssh_user: root
  74. hosts:
  75. - connect_to: 10.0.0.1
  76. ip: 10.0.0.1
  77. hostname: master-private.example.com
  78. public_ip: 24.222.0.1
  79. public_hostname: master.example.com
  80. master: true
  81. node: true
  82. - ip: 10.0.0.2
  83. hostname: node1-private.example.com
  84. public_ip: 24.222.0.2
  85. public_hostname: node1.example.com
  86. node: true
  87. - connect_to: 10.0.0.3
  88. ip: 10.0.0.3
  89. hostname: node2-private.example.com
  90. public_ip: 24.222.0.3
  91. public_hostname: node2.example.com
  92. node: true
  93. """
  94. QUICKHA_CONFIG = """
  95. variant: %s
  96. ansible_ssh_user: root
  97. master_routingconfig_subdomain: example.com
  98. hosts:
  99. - connect_to: 10.0.0.1
  100. ip: 10.0.0.1
  101. hostname: master-private.example.com
  102. public_ip: 24.222.0.1
  103. public_hostname: master.example.com
  104. master: true
  105. node: true
  106. - connect_to: 10.0.0.2
  107. ip: 10.0.0.2
  108. hostname: node1-private.example.com
  109. public_ip: 24.222.0.2
  110. public_hostname: node1.example.com
  111. master: true
  112. node: true
  113. - connect_to: 10.0.0.3
  114. ip: 10.0.0.3
  115. hostname: node2-private.example.com
  116. public_ip: 24.222.0.3
  117. public_hostname: node2.example.com
  118. node: true
  119. master: true
  120. - connect_to: 10.0.0.4
  121. ip: 10.0.0.4
  122. hostname: node3-private.example.com
  123. public_ip: 24.222.0.4
  124. public_hostname: node3.example.com
  125. node: true
  126. - connect_to: 10.0.0.5
  127. ip: 10.0.0.5
  128. hostname: proxy-private.example.com
  129. public_ip: 24.222.0.5
  130. public_hostname: proxy.example.com
  131. master_lb: true
  132. """
  133. QUICKHA_2_MASTER_CONFIG = """
  134. variant: %s
  135. ansible_ssh_user: root
  136. hosts:
  137. - connect_to: 10.0.0.1
  138. ip: 10.0.0.1
  139. hostname: master-private.example.com
  140. public_ip: 24.222.0.1
  141. public_hostname: master.example.com
  142. master: true
  143. node: true
  144. - connect_to: 10.0.0.2
  145. ip: 10.0.0.2
  146. hostname: node1-private.example.com
  147. public_ip: 24.222.0.2
  148. public_hostname: node1.example.com
  149. master: true
  150. node: true
  151. - connect_to: 10.0.0.4
  152. ip: 10.0.0.4
  153. hostname: node3-private.example.com
  154. public_ip: 24.222.0.4
  155. public_hostname: node3.example.com
  156. node: true
  157. - connect_to: 10.0.0.5
  158. ip: 10.0.0.5
  159. hostname: proxy-private.example.com
  160. public_ip: 24.222.0.5
  161. public_hostname: proxy.example.com
  162. master_lb: true
  163. """
  164. QUICKHA_CONFIG_REUSED_LB = """
  165. variant: %s
  166. ansible_ssh_user: root
  167. hosts:
  168. - connect_to: 10.0.0.1
  169. ip: 10.0.0.1
  170. hostname: master-private.example.com
  171. public_ip: 24.222.0.1
  172. public_hostname: master.example.com
  173. master: true
  174. node: true
  175. - connect_to: 10.0.0.2
  176. ip: 10.0.0.2
  177. hostname: node1-private.example.com
  178. public_ip: 24.222.0.2
  179. public_hostname: node1.example.com
  180. master: true
  181. node: true
  182. master_lb: true
  183. - connect_to: 10.0.0.3
  184. ip: 10.0.0.3
  185. hostname: node2-private.example.com
  186. public_ip: 24.222.0.3
  187. public_hostname: node2.example.com
  188. node: true
  189. master: true
  190. """
  191. QUICKHA_CONFIG_NO_LB = """
  192. variant: %s
  193. ansible_ssh_user: root
  194. hosts:
  195. - connect_to: 10.0.0.1
  196. ip: 10.0.0.1
  197. hostname: master-private.example.com
  198. public_ip: 24.222.0.1
  199. public_hostname: master.example.com
  200. master: true
  201. node: true
  202. - connect_to: 10.0.0.2
  203. ip: 10.0.0.2
  204. hostname: node1-private.example.com
  205. public_ip: 24.222.0.2
  206. public_hostname: node1.example.com
  207. master: true
  208. node: true
  209. - connect_to: 10.0.0.3
  210. ip: 10.0.0.3
  211. hostname: node2-private.example.com
  212. public_ip: 24.222.0.3
  213. public_hostname: node2.example.com
  214. node: true
  215. master: true
  216. """
  217. QUICKHA_CONFIG_PRECONFIGURED_LB = """
  218. variant: %s
  219. ansible_ssh_user: root
  220. master_routingconfig_subdomain: example.com
  221. hosts:
  222. - connect_to: 10.0.0.1
  223. ip: 10.0.0.1
  224. hostname: master-private.example.com
  225. public_ip: 24.222.0.1
  226. public_hostname: master.example.com
  227. master: true
  228. node: true
  229. - connect_to: 10.0.0.2
  230. ip: 10.0.0.2
  231. hostname: node1-private.example.com
  232. public_ip: 24.222.0.2
  233. public_hostname: node1.example.com
  234. master: true
  235. node: true
  236. - connect_to: 10.0.0.3
  237. ip: 10.0.0.3
  238. hostname: node2-private.example.com
  239. public_ip: 24.222.0.3
  240. public_hostname: node2.example.com
  241. node: true
  242. master: true
  243. - connect_to: 10.0.0.4
  244. ip: 10.0.0.4
  245. hostname: node3-private.example.com
  246. public_ip: 24.222.0.4
  247. public_hostname: node3.example.com
  248. node: true
  249. - connect_to: proxy-private.example.com
  250. hostname: proxy-private.example.com
  251. public_hostname: proxy.example.com
  252. master_lb: true
  253. preconfigured: true
  254. """
  255. class UnattendedCliTests(OOCliFixture):
  256. def setUp(self):
  257. OOCliFixture.setUp(self)
  258. self.cli_args.append("-u")
  259. # unattended with config file and all installed hosts (without --force)
  260. @patch('ooinstall.openshift_ansible.run_main_playbook')
  261. @patch('ooinstall.openshift_ansible.load_system_facts')
  262. def test_get_hosts_to_run_on1(self, load_facts_mock, run_playbook_mock):
  263. mock_facts = copy.deepcopy(MOCK_FACTS)
  264. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  265. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  266. mock_facts['10.0.0.3']['common']['version'] = "3.0.0"
  267. load_facts_mock.return_value = (mock_facts, 0)
  268. run_playbook_mock.return_value = 0
  269. config_file = self.write_config(os.path.join(self.work_dir,
  270. 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
  271. self.cli_args.extend(["-c", config_file, "install"])
  272. result = self.runner.invoke(cli.cli, self.cli_args)
  273. if result.exception is None or result.exit_code != 1:
  274. print "Exit code: %s" % result.exit_code
  275. self.fail("Unexpected CLI return")
  276. # unattended with config file and all installed hosts (with --force)
  277. @patch('ooinstall.openshift_ansible.run_main_playbook')
  278. @patch('ooinstall.openshift_ansible.load_system_facts')
  279. def test_get_hosts_to_run_on2(self, load_facts_mock, run_playbook_mock):
  280. mock_facts = copy.deepcopy(MOCK_FACTS)
  281. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  282. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  283. mock_facts['10.0.0.3']['common']['version'] = "3.0.0"
  284. self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
  285. cli_input=None,
  286. exp_hosts_len=3,
  287. exp_hosts_to_run_on_len=3,
  288. force=True)
  289. # unattended with config file and no installed hosts (without --force)
  290. @patch('ooinstall.openshift_ansible.run_main_playbook')
  291. @patch('ooinstall.openshift_ansible.load_system_facts')
  292. def test_get_hosts_to_run_on3(self, load_facts_mock, run_playbook_mock):
  293. load_facts_mock.return_value = (MOCK_FACTS, 0)
  294. run_playbook_mock.return_value = 0
  295. self._verify_get_hosts_to_run_on(MOCK_FACTS, load_facts_mock, run_playbook_mock,
  296. cli_input=None,
  297. exp_hosts_len=3,
  298. exp_hosts_to_run_on_len=3,
  299. force=False)
  300. # unattended with config file and no installed hosts (with --force)
  301. @patch('ooinstall.openshift_ansible.run_main_playbook')
  302. @patch('ooinstall.openshift_ansible.load_system_facts')
  303. def test_get_hosts_to_run_on4(self, load_facts_mock, run_playbook_mock):
  304. load_facts_mock.return_value = (MOCK_FACTS, 0)
  305. run_playbook_mock.return_value = 0
  306. self._verify_get_hosts_to_run_on(MOCK_FACTS, load_facts_mock, run_playbook_mock,
  307. cli_input=None,
  308. exp_hosts_len=3,
  309. exp_hosts_to_run_on_len=3,
  310. force=True)
  311. # unattended with config file and some installed some uninstalled hosts (without --force)
  312. @patch('ooinstall.openshift_ansible.run_main_playbook')
  313. @patch('ooinstall.openshift_ansible.load_system_facts')
  314. def test_get_hosts_to_run_on5(self, load_facts_mock, run_playbook_mock):
  315. mock_facts = copy.deepcopy(MOCK_FACTS)
  316. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  317. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  318. self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
  319. cli_input=None,
  320. exp_hosts_len=3,
  321. exp_hosts_to_run_on_len=2,
  322. force=False)
  323. # unattended with config file and some installed some uninstalled hosts (with --force)
  324. @patch('ooinstall.openshift_ansible.run_main_playbook')
  325. @patch('ooinstall.openshift_ansible.load_system_facts')
  326. def test_get_hosts_to_run_on6(self, load_facts_mock, run_playbook_mock):
  327. mock_facts = copy.deepcopy(MOCK_FACTS)
  328. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  329. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  330. self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
  331. cli_input=None,
  332. exp_hosts_len=3,
  333. exp_hosts_to_run_on_len=3,
  334. force=True)
  335. @patch('ooinstall.openshift_ansible.run_main_playbook')
  336. @patch('ooinstall.openshift_ansible.load_system_facts')
  337. def test_cfg_full_run(self, load_facts_mock, run_playbook_mock):
  338. load_facts_mock.return_value = (MOCK_FACTS, 0)
  339. run_playbook_mock.return_value = 0
  340. config_file = self.write_config(os.path.join(self.work_dir,
  341. 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
  342. self.cli_args.extend(["-c", config_file, "install"])
  343. result = self.runner.invoke(cli.cli, self.cli_args)
  344. self.assert_result(result, 0)
  345. load_facts_args = load_facts_mock.call_args[0]
  346. self.assertEquals(os.path.join(self.work_dir, ".ansible/hosts"),
  347. load_facts_args[0])
  348. self.assertEquals(os.path.join(self.work_dir,
  349. "playbooks/byo/openshift_facts.yml"), load_facts_args[1])
  350. env_vars = load_facts_args[2]
  351. self.assertEquals(os.path.join(self.work_dir,
  352. '.ansible/callback_facts.yaml'),
  353. env_vars['OO_INSTALL_CALLBACK_FACTS_YAML'])
  354. self.assertEqual('/tmp/ansible.log', env_vars['ANSIBLE_LOG_PATH'])
  355. # If user running test has rpm installed, this might be set to default:
  356. self.assertTrue('ANSIBLE_CONFIG' not in env_vars or
  357. env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
  358. # Make sure we ran on the expected masters and nodes:
  359. hosts = run_playbook_mock.call_args[0][0]
  360. hosts_to_run_on = run_playbook_mock.call_args[0][1]
  361. self.assertEquals(3, len(hosts))
  362. self.assertEquals(3, len(hosts_to_run_on))
  363. @patch('ooinstall.openshift_ansible.run_main_playbook')
  364. @patch('ooinstall.openshift_ansible.load_system_facts')
  365. def test_inventory_write(self, load_facts_mock, run_playbook_mock):
  366. # Add an ssh user so we can verify it makes it to the inventory file:
  367. merged_config = "%s\n%s" % (SAMPLE_CONFIG % 'openshift-enterprise',
  368. "ansible_ssh_user: bob")
  369. load_facts_mock.return_value = (MOCK_FACTS, 0)
  370. run_playbook_mock.return_value = 0
  371. config_file = self.write_config(os.path.join(self.work_dir,
  372. 'ooinstall.conf'), merged_config)
  373. self.cli_args.extend(["-c", config_file, "install"])
  374. result = self.runner.invoke(cli.cli, self.cli_args)
  375. self.assert_result(result, 0)
  376. # Check the inventory file looks as we would expect:
  377. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  378. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  379. self.assertEquals('bob',
  380. inventory.get('OSEv3:vars', 'ansible_ssh_user'))
  381. self.assertEquals('openshift-enterprise',
  382. inventory.get('OSEv3:vars', 'deployment_type'))
  383. # Check the masters:
  384. self.assertEquals(1, len(inventory.items('masters')))
  385. self.assertEquals(3, len(inventory.items('nodes')))
  386. for item in inventory.items('masters'):
  387. # ansible host lines do NOT parse nicely:
  388. master_line = item[0]
  389. if item[1] is not None:
  390. master_line = "%s=%s" % (master_line, item[1])
  391. self.assertTrue('openshift_ip' in master_line)
  392. self.assertTrue('openshift_public_ip' in master_line)
  393. self.assertTrue('openshift_hostname' in master_line)
  394. self.assertTrue('openshift_public_hostname' in master_line)
  395. @patch('ooinstall.openshift_ansible.run_main_playbook')
  396. @patch('ooinstall.openshift_ansible.load_system_facts')
  397. def test_variant_version_latest_assumed(self, load_facts_mock,
  398. run_playbook_mock):
  399. load_facts_mock.return_value = (MOCK_FACTS, 0)
  400. run_playbook_mock.return_value = 0
  401. config_file = self.write_config(os.path.join(self.work_dir,
  402. 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
  403. self.cli_args.extend(["-c", config_file, "install"])
  404. result = self.runner.invoke(cli.cli, self.cli_args)
  405. self.assert_result(result, 0)
  406. written_config = read_yaml(config_file)
  407. self.assertEquals('openshift-enterprise', written_config['variant'])
  408. # We didn't specify a version so the latest should have been assumed,
  409. # and written to disk:
  410. self.assertEquals('3.1', written_config['variant_version'])
  411. # Make sure the correct value was passed to ansible:
  412. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  413. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  414. self.assertEquals('openshift-enterprise',
  415. inventory.get('OSEv3:vars', 'deployment_type'))
  416. @patch('ooinstall.openshift_ansible.run_main_playbook')
  417. @patch('ooinstall.openshift_ansible.load_system_facts')
  418. def test_variant_version_preserved(self, load_facts_mock,
  419. run_playbook_mock):
  420. load_facts_mock.return_value = (MOCK_FACTS, 0)
  421. run_playbook_mock.return_value = 0
  422. config = SAMPLE_CONFIG % 'openshift-enterprise'
  423. config = '%s\n%s' % (config, 'variant_version: 3.0')
  424. config_file = self.write_config(os.path.join(self.work_dir,
  425. 'ooinstall.conf'), config)
  426. self.cli_args.extend(["-c", config_file, "install"])
  427. result = self.runner.invoke(cli.cli, self.cli_args)
  428. self.assert_result(result, 0)
  429. written_config = read_yaml(config_file)
  430. self.assertEquals('openshift-enterprise', written_config['variant'])
  431. # Make sure our older version was preserved:
  432. # and written to disk:
  433. self.assertEquals('3.0', written_config['variant_version'])
  434. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  435. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  436. self.assertEquals('enterprise',
  437. inventory.get('OSEv3:vars', 'deployment_type'))
  438. @patch('ooinstall.openshift_ansible.run_ansible')
  439. @patch('ooinstall.openshift_ansible.load_system_facts')
  440. def test_no_ansible_config_specified(self, load_facts_mock, run_ansible_mock):
  441. load_facts_mock.return_value = (MOCK_FACTS, 0)
  442. run_ansible_mock.return_value = 0
  443. config = SAMPLE_CONFIG % 'openshift-enterprise'
  444. self._ansible_config_test(load_facts_mock, run_ansible_mock,
  445. config, None, None)
  446. @patch('ooinstall.openshift_ansible.run_ansible')
  447. @patch('ooinstall.openshift_ansible.load_system_facts')
  448. def test_ansible_config_specified_cli(self, load_facts_mock, run_ansible_mock):
  449. load_facts_mock.return_value = (MOCK_FACTS, 0)
  450. run_ansible_mock.return_value = 0
  451. config = SAMPLE_CONFIG % 'openshift-enterprise'
  452. ansible_config = os.path.join(self.work_dir, 'ansible.cfg')
  453. self._ansible_config_test(load_facts_mock, run_ansible_mock,
  454. config, ansible_config, ansible_config)
  455. @patch('ooinstall.openshift_ansible.run_ansible')
  456. @patch('ooinstall.openshift_ansible.load_system_facts')
  457. def test_ansible_config_specified_in_installer_config(self,
  458. load_facts_mock, run_ansible_mock):
  459. load_facts_mock.return_value = (MOCK_FACTS, 0)
  460. run_ansible_mock.return_value = 0
  461. ansible_config = os.path.join(self.work_dir, 'ansible.cfg')
  462. config = SAMPLE_CONFIG % 'openshift-enterprise'
  463. config = "%s\nansible_config: %s" % (config, ansible_config)
  464. self._ansible_config_test(load_facts_mock, run_ansible_mock,
  465. config, None, ansible_config)
  466. #pylint: disable=too-many-arguments
  467. # This method allows for drastically simpler tests to write, and the args
  468. # are all useful.
  469. def _ansible_config_test(self, load_facts_mock, run_ansible_mock,
  470. installer_config, ansible_config_cli=None, expected_result=None):
  471. """
  472. Utility method for testing the ways you can specify the ansible config.
  473. """
  474. load_facts_mock.return_value = (MOCK_FACTS, 0)
  475. run_ansible_mock.return_value = 0
  476. config_file = self.write_config(os.path.join(self.work_dir,
  477. 'ooinstall.conf'), installer_config)
  478. self.cli_args.extend(["-c", config_file])
  479. if ansible_config_cli:
  480. self.cli_args.extend(["--ansible-config", ansible_config_cli])
  481. self.cli_args.append("install")
  482. result = self.runner.invoke(cli.cli, self.cli_args)
  483. self.assert_result(result, 0)
  484. # Test the env vars for facts playbook:
  485. facts_env_vars = load_facts_mock.call_args[0][2]
  486. if expected_result:
  487. self.assertEquals(expected_result, facts_env_vars['ANSIBLE_CONFIG'])
  488. else:
  489. # If user running test has rpm installed, this might be set to default:
  490. self.assertTrue('ANSIBLE_CONFIG' not in facts_env_vars or
  491. facts_env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
  492. # Test the env vars for main playbook:
  493. env_vars = run_ansible_mock.call_args[0][2]
  494. if expected_result:
  495. self.assertEquals(expected_result, env_vars['ANSIBLE_CONFIG'])
  496. else:
  497. # If user running test has rpm installed, this might be set to default:
  498. self.assertTrue('ANSIBLE_CONFIG' not in env_vars or
  499. env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
  500. # unattended with bad config file and no installed hosts (without --force)
  501. @patch('ooinstall.openshift_ansible.run_main_playbook')
  502. @patch('ooinstall.openshift_ansible.load_system_facts')
  503. def test_bad_config(self, load_facts_mock, run_playbook_mock):
  504. load_facts_mock.return_value = (MOCK_FACTS, 0)
  505. run_playbook_mock.return_value = 0
  506. config_file = self.write_config(os.path.join(self.work_dir,
  507. 'ooinstall.conf'), BAD_CONFIG % 'openshift-enterprise')
  508. self.cli_args.extend(["-c", config_file, "install"])
  509. result = self.runner.invoke(cli.cli, self.cli_args)
  510. self.assertEquals(1, result.exit_code)
  511. self.assertTrue("You must specify either an ip or hostname"
  512. in result.output)
  513. #unattended with three masters, one node, and haproxy
  514. @patch('ooinstall.openshift_ansible.run_main_playbook')
  515. @patch('ooinstall.openshift_ansible.load_system_facts')
  516. def test_quick_ha_full_run(self, load_facts_mock, run_playbook_mock):
  517. load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
  518. run_playbook_mock.return_value = 0
  519. config_file = self.write_config(os.path.join(self.work_dir,
  520. 'ooinstall.conf'), QUICKHA_CONFIG % 'openshift-enterprise')
  521. self.cli_args.extend(["-c", config_file, "install"])
  522. result = self.runner.invoke(cli.cli, self.cli_args)
  523. self.assert_result(result, 0)
  524. # Make sure we ran on the expected masters and nodes:
  525. hosts = run_playbook_mock.call_args[0][0]
  526. hosts_to_run_on = run_playbook_mock.call_args[0][1]
  527. self.assertEquals(5, len(hosts))
  528. self.assertEquals(5, len(hosts_to_run_on))
  529. #unattended with two masters, one node, and haproxy
  530. @patch('ooinstall.openshift_ansible.run_main_playbook')
  531. @patch('ooinstall.openshift_ansible.load_system_facts')
  532. def test_quick_ha_only_2_masters(self, load_facts_mock, run_playbook_mock):
  533. load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
  534. run_playbook_mock.return_value = 0
  535. config_file = self.write_config(os.path.join(self.work_dir,
  536. 'ooinstall.conf'), QUICKHA_2_MASTER_CONFIG % 'openshift-enterprise')
  537. self.cli_args.extend(["-c", config_file, "install"])
  538. result = self.runner.invoke(cli.cli, self.cli_args)
  539. # This is an invalid config:
  540. self.assert_result(result, 1)
  541. self.assertTrue("A minimum of 3 Masters are required" in result.output)
  542. #unattended with three masters, one node, but no load balancer specified:
  543. @patch('ooinstall.openshift_ansible.run_main_playbook')
  544. @patch('ooinstall.openshift_ansible.load_system_facts')
  545. def test_quick_ha_no_lb(self, load_facts_mock, run_playbook_mock):
  546. load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
  547. run_playbook_mock.return_value = 0
  548. config_file = self.write_config(os.path.join(self.work_dir,
  549. 'ooinstall.conf'), QUICKHA_CONFIG_NO_LB % 'openshift-enterprise')
  550. self.cli_args.extend(["-c", config_file, "install"])
  551. result = self.runner.invoke(cli.cli, self.cli_args)
  552. # This is not a valid input:
  553. self.assert_result(result, 1)
  554. self.assertTrue('No master load balancer specified in config' in result.output)
  555. #unattended with three masters, one node, and one of the masters reused as load balancer:
  556. @patch('ooinstall.openshift_ansible.run_main_playbook')
  557. @patch('ooinstall.openshift_ansible.load_system_facts')
  558. def test_quick_ha_reused_lb(self, load_facts_mock, run_playbook_mock):
  559. load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
  560. run_playbook_mock.return_value = 0
  561. config_file = self.write_config(os.path.join(self.work_dir,
  562. 'ooinstall.conf'), QUICKHA_CONFIG_REUSED_LB % 'openshift-enterprise')
  563. self.cli_args.extend(["-c", config_file, "install"])
  564. result = self.runner.invoke(cli.cli, self.cli_args)
  565. # This is not a valid configuration:
  566. self.assert_result(result, 1)
  567. #unattended with preconfigured lb
  568. @patch('ooinstall.openshift_ansible.run_main_playbook')
  569. @patch('ooinstall.openshift_ansible.load_system_facts')
  570. def test_quick_ha_preconfigured_lb(self, load_facts_mock, run_playbook_mock):
  571. load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
  572. run_playbook_mock.return_value = 0
  573. config_file = self.write_config(os.path.join(self.work_dir,
  574. 'ooinstall.conf'), QUICKHA_CONFIG_PRECONFIGURED_LB % 'openshift-enterprise')
  575. self.cli_args.extend(["-c", config_file, "install"])
  576. result = self.runner.invoke(cli.cli, self.cli_args)
  577. self.assert_result(result, 0)
  578. # Make sure we ran on the expected masters and nodes:
  579. hosts = run_playbook_mock.call_args[0][0]
  580. hosts_to_run_on = run_playbook_mock.call_args[0][1]
  581. self.assertEquals(5, len(hosts))
  582. self.assertEquals(5, len(hosts_to_run_on))
  583. class AttendedCliTests(OOCliFixture):
  584. def setUp(self):
  585. OOCliFixture.setUp(self)
  586. # Doesn't exist but keeps us from reading the local users config:
  587. self.config_file = os.path.join(self.work_dir, 'config.yml')
  588. self.cli_args.extend(["-c", self.config_file])
  589. @patch('ooinstall.openshift_ansible.run_main_playbook')
  590. @patch('ooinstall.openshift_ansible.load_system_facts')
  591. def test_full_run(self, load_facts_mock, run_playbook_mock):
  592. load_facts_mock.return_value = (MOCK_FACTS, 0)
  593. run_playbook_mock.return_value = 0
  594. cli_input = build_input(hosts=[
  595. ('10.0.0.1', True, False),
  596. ('10.0.0.2', False, False),
  597. ('10.0.0.3', False, False)],
  598. ssh_user='root',
  599. variant_num=1,
  600. confirm_facts='y')
  601. self.cli_args.append("install")
  602. result = self.runner.invoke(cli.cli, self.cli_args,
  603. input=cli_input)
  604. self.assert_result(result, 0)
  605. self._verify_load_facts(load_facts_mock)
  606. self._verify_run_playbook(run_playbook_mock, 3, 3)
  607. written_config = read_yaml(self.config_file)
  608. self._verify_config_hosts(written_config, 3)
  609. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  610. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  611. self.assertEquals('False',
  612. inventory.get('nodes', '10.0.0.1 openshift_schedulable'))
  613. self.assertEquals(None,
  614. inventory.get('nodes', '10.0.0.2'))
  615. self.assertEquals(None,
  616. inventory.get('nodes', '10.0.0.3'))
  617. # interactive with config file and some installed some uninstalled hosts
  618. @patch('ooinstall.openshift_ansible.run_main_playbook')
  619. @patch('ooinstall.openshift_ansible.load_system_facts')
  620. def test_add_nodes(self, load_facts_mock, run_playbook_mock):
  621. # Modify the mock facts to return a version indicating OpenShift
  622. # is already installed on our master, and the first node.
  623. mock_facts = copy.deepcopy(MOCK_FACTS)
  624. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  625. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  626. load_facts_mock.return_value = (mock_facts, 0)
  627. run_playbook_mock.return_value = 0
  628. cli_input = build_input(hosts=[
  629. ('10.0.0.1', True, False),
  630. ('10.0.0.2', False, False),
  631. ],
  632. add_nodes=[('10.0.0.3', False, False)],
  633. ssh_user='root',
  634. variant_num=1,
  635. confirm_facts='y')
  636. self.cli_args.append("install")
  637. result = self.runner.invoke(cli.cli,
  638. self.cli_args,
  639. input=cli_input)
  640. self.assert_result(result, 0)
  641. self._verify_load_facts(load_facts_mock)
  642. self._verify_run_playbook(run_playbook_mock, 3, 2)
  643. written_config = read_yaml(self.config_file)
  644. self._verify_config_hosts(written_config, 3)
  645. @patch('ooinstall.openshift_ansible.run_main_playbook')
  646. @patch('ooinstall.openshift_ansible.load_system_facts')
  647. def test_fresh_install_with_config(self, load_facts_mock, run_playbook_mock):
  648. load_facts_mock.return_value = (MOCK_FACTS, 0)
  649. run_playbook_mock.return_value = 0
  650. config_file = self.write_config(os.path.join(self.work_dir,
  651. 'ooinstall.conf'),
  652. SAMPLE_CONFIG % 'openshift-enterprise')
  653. cli_input = build_input(confirm_facts='y')
  654. self.cli_args.extend(["-c", config_file])
  655. self.cli_args.append("install")
  656. result = self.runner.invoke(cli.cli,
  657. self.cli_args,
  658. input=cli_input)
  659. self.assert_result(result, 0)
  660. self._verify_load_facts(load_facts_mock)
  661. self._verify_run_playbook(run_playbook_mock, 3, 3)
  662. written_config = read_yaml(config_file)
  663. self._verify_config_hosts(written_config, 3)
  664. #interactive with config file and all installed hosts
  665. @patch('ooinstall.openshift_ansible.run_main_playbook')
  666. @patch('ooinstall.openshift_ansible.load_system_facts')
  667. def test_get_hosts_to_run_on(self, load_facts_mock, run_playbook_mock):
  668. mock_facts = copy.deepcopy(MOCK_FACTS)
  669. mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
  670. mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
  671. cli_input = build_input(hosts=[
  672. ('10.0.0.1', True, False),
  673. ],
  674. add_nodes=[('10.0.0.2', False, False)],
  675. ssh_user='root',
  676. variant_num=1,
  677. schedulable_masters_ok=True,
  678. confirm_facts='y')
  679. self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock,
  680. run_playbook_mock,
  681. cli_input,
  682. exp_hosts_len=2,
  683. exp_hosts_to_run_on_len=2,
  684. force=False)
  685. #interactive multimaster: one more node than master
  686. @patch('ooinstall.openshift_ansible.run_main_playbook')
  687. @patch('ooinstall.openshift_ansible.load_system_facts')
  688. def test_ha_dedicated_node(self, load_facts_mock, run_playbook_mock):
  689. load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
  690. run_playbook_mock.return_value = 0
  691. cli_input = build_input(hosts=[
  692. ('10.0.0.1', True, False),
  693. ('10.0.0.2', True, False),
  694. ('10.0.0.3', True, False),
  695. ('10.0.0.4', False, False)],
  696. ssh_user='root',
  697. variant_num=1,
  698. confirm_facts='y',
  699. master_lb=('10.0.0.5', False))
  700. self.cli_args.append("install")
  701. result = self.runner.invoke(cli.cli, self.cli_args,
  702. input=cli_input)
  703. self.assert_result(result, 0)
  704. self._verify_load_facts(load_facts_mock)
  705. self._verify_run_playbook(run_playbook_mock, 5, 5)
  706. written_config = read_yaml(self.config_file)
  707. self._verify_config_hosts(written_config, 5)
  708. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  709. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  710. self.assertEquals('False',
  711. inventory.get('nodes', '10.0.0.1 openshift_schedulable'))
  712. self.assertEquals('False',
  713. inventory.get('nodes', '10.0.0.2 openshift_schedulable'))
  714. self.assertEquals('False',
  715. inventory.get('nodes', '10.0.0.3 openshift_schedulable'))
  716. self.assertEquals(None,
  717. inventory.get('nodes', '10.0.0.4'))
  718. self.assertTrue(inventory.has_section('etcd'))
  719. self.assertEquals(3, len(inventory.items('etcd')))
  720. #interactive multimaster: identical masters and nodes
  721. @patch('ooinstall.openshift_ansible.run_main_playbook')
  722. @patch('ooinstall.openshift_ansible.load_system_facts')
  723. def test_ha_no_dedicated_nodes(self, load_facts_mock, run_playbook_mock):
  724. load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
  725. run_playbook_mock.return_value = 0
  726. cli_input = build_input(hosts=[
  727. ('10.0.0.1', True, False),
  728. ('10.0.0.2', True, False),
  729. ('10.0.0.3', True, False)],
  730. ssh_user='root',
  731. variant_num=1,
  732. confirm_facts='y',
  733. master_lb=('10.0.0.5', False))
  734. self.cli_args.append("install")
  735. result = self.runner.invoke(cli.cli, self.cli_args,
  736. input=cli_input)
  737. self.assert_result(result, 0)
  738. self._verify_load_facts(load_facts_mock)
  739. self._verify_run_playbook(run_playbook_mock, 4, 4)
  740. written_config = read_yaml(self.config_file)
  741. self._verify_config_hosts(written_config, 4)
  742. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  743. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  744. self.assertEquals('True',
  745. inventory.get('nodes', '10.0.0.1 openshift_schedulable'))
  746. self.assertEquals('True',
  747. inventory.get('nodes', '10.0.0.2 openshift_schedulable'))
  748. self.assertEquals('True',
  749. inventory.get('nodes', '10.0.0.3 openshift_schedulable'))
  750. #interactive multimaster: attempting to use a master as the load balancer should fail:
  751. @patch('ooinstall.openshift_ansible.run_main_playbook')
  752. @patch('ooinstall.openshift_ansible.load_system_facts')
  753. def test_ha_reuse_master_as_lb(self, load_facts_mock, run_playbook_mock):
  754. load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
  755. run_playbook_mock.return_value = 0
  756. cli_input = build_input(hosts=[
  757. ('10.0.0.1', True, False),
  758. ('10.0.0.2', True, False),
  759. ('10.0.0.3', False, False),
  760. ('10.0.0.4', True, False)],
  761. ssh_user='root',
  762. variant_num=1,
  763. confirm_facts='y',
  764. master_lb=(['10.0.0.2', '10.0.0.5'], False))
  765. self.cli_args.append("install")
  766. result = self.runner.invoke(cli.cli, self.cli_args,
  767. input=cli_input)
  768. self.assert_result(result, 0)
  769. #interactive all-in-one
  770. @patch('ooinstall.openshift_ansible.run_main_playbook')
  771. @patch('ooinstall.openshift_ansible.load_system_facts')
  772. def test_all_in_one(self, load_facts_mock, run_playbook_mock):
  773. load_facts_mock.return_value = (MOCK_FACTS, 0)
  774. run_playbook_mock.return_value = 0
  775. cli_input = build_input(hosts=[
  776. ('10.0.0.1', True, False)],
  777. ssh_user='root',
  778. variant_num=1,
  779. confirm_facts='y')
  780. self.cli_args.append("install")
  781. result = self.runner.invoke(cli.cli, self.cli_args,
  782. input=cli_input)
  783. self.assert_result(result, 0)
  784. self._verify_load_facts(load_facts_mock)
  785. self._verify_run_playbook(run_playbook_mock, 1, 1)
  786. written_config = read_yaml(self.config_file)
  787. self._verify_config_hosts(written_config, 1)
  788. inventory = ConfigParser.ConfigParser(allow_no_value=True)
  789. inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
  790. self.assertEquals('True',
  791. inventory.get('nodes', '10.0.0.1 openshift_schedulable'))
  792. #interactive 3.0 install confirm no HA hints
  793. @patch('ooinstall.openshift_ansible.run_main_playbook')
  794. @patch('ooinstall.openshift_ansible.load_system_facts')
  795. def test_ha_hint(self, load_facts_mock, run_playbook_mock):
  796. load_facts_mock.return_value = (MOCK_FACTS, 0)
  797. run_playbook_mock.return_value = 0
  798. cli_input = build_input(hosts=[
  799. ('10.0.0.1', True, False)],
  800. ssh_user='root',
  801. variant_num=2,
  802. confirm_facts='y')
  803. self.cli_args.append("install")
  804. result = self.runner.invoke(cli.cli, self.cli_args,
  805. input=cli_input)
  806. self.assert_result(result, 0)
  807. self.assertTrue("NOTE: Add a total of 3 or more Masters to perform an HA installation."
  808. not in result.output)
  809. # TODO: test with config file, attended add node
  810. # TODO: test with config file, attended new node already in config file
  811. # TODO: test with config file, attended new node already in config file, plus manually added nodes
  812. # TODO: test with config file, attended reject facts