cli_installer_tests.py 38 KB

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