summaryrefslogtreecommitdiffstats
path: root/utils/test
diff options
context:
space:
mode:
Diffstat (limited to 'utils/test')
-rw-r--r--utils/test/__init__.py0
-rw-r--r--utils/test/cli_installer_tests.py975
-rw-r--r--utils/test/fixture.py236
-rw-r--r--utils/test/oo_config_tests.py262
4 files changed, 1473 insertions, 0 deletions
diff --git a/utils/test/__init__.py b/utils/test/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/utils/test/__init__.py
diff --git a/utils/test/cli_installer_tests.py b/utils/test/cli_installer_tests.py
new file mode 100644
index 000000000..6ba5ec1eb
--- /dev/null
+++ b/utils/test/cli_installer_tests.py
@@ -0,0 +1,975 @@
+# TODO: Temporarily disabled due to importing old code into openshift-ansible
+# repo. We will work on these over time.
+# pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name
+
+import copy
+import os
+import ConfigParser
+
+import ooinstall.cli_installer as cli
+
+from test.fixture import OOCliFixture, SAMPLE_CONFIG, build_input, read_yaml
+from mock import patch
+
+
+MOCK_FACTS = {
+ '10.0.0.1': {
+ 'common': {
+ 'ip': '10.0.0.1',
+ 'public_ip': '10.0.0.1',
+ 'hostname': 'master-private.example.com',
+ 'public_hostname': 'master.example.com'
+ }
+ },
+ '10.0.0.2': {
+ 'common': {
+ 'ip': '10.0.0.2',
+ 'public_ip': '10.0.0.2',
+ 'hostname': 'node1-private.example.com',
+ 'public_hostname': 'node1.example.com'
+ }
+ },
+ '10.0.0.3': {
+ 'common': {
+ 'ip': '10.0.0.3',
+ 'public_ip': '10.0.0.3',
+ 'hostname': 'node2-private.example.com',
+ 'public_hostname': 'node2.example.com'
+ }
+ },
+}
+
+MOCK_FACTS_QUICKHA = {
+ '10.0.0.1': {
+ 'common': {
+ 'ip': '10.0.0.1',
+ 'public_ip': '10.0.0.1',
+ 'hostname': 'master-private.example.com',
+ 'public_hostname': 'master.example.com'
+ }
+ },
+ '10.0.0.2': {
+ 'common': {
+ 'ip': '10.0.0.2',
+ 'public_ip': '10.0.0.2',
+ 'hostname': 'node1-private.example.com',
+ 'public_hostname': 'node1.example.com'
+ }
+ },
+ '10.0.0.3': {
+ 'common': {
+ 'ip': '10.0.0.3',
+ 'public_ip': '10.0.0.3',
+ 'hostname': 'node2-private.example.com',
+ 'public_hostname': 'node2.example.com'
+ }
+ },
+ '10.0.0.4': {
+ 'common': {
+ 'ip': '10.0.0.4',
+ 'public_ip': '10.0.0.4',
+ 'hostname': 'proxy-private.example.com',
+ 'public_hostname': 'proxy.example.com'
+ }
+ },
+ '10.1.0.1': {
+ 'common': {
+ 'ip': '10.1.0.1',
+ 'public_ip': '10.1.0.1',
+ 'hostname': 'storage-private.example.com',
+ 'public_hostname': 'storage.example.com'
+ }
+ },
+}
+
+# Missing connect_to on some hosts:
+BAD_CONFIG = """
+variant: %s
+ansible_ssh_user: root
+hosts:
+ - connect_to: 10.0.0.1
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ node: true
+ - connect_to: 10.0.0.3
+ ip: 10.0.0.3
+ hostname: node2-private.example.com
+ public_ip: 24.222.0.3
+ public_hostname: node2.example.com
+ node: true
+"""
+
+QUICKHA_CONFIG = """
+variant: %s
+ansible_ssh_user: root
+master_routingconfig_subdomain: example.com
+hosts:
+ - connect_to: 10.0.0.1
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.2
+ ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.3
+ ip: 10.0.0.3
+ hostname: node2-private.example.com
+ public_ip: 24.222.0.3
+ public_hostname: node2.example.com
+ node: true
+ master: true
+ - connect_to: 10.0.0.4
+ ip: 10.0.0.4
+ hostname: node3-private.example.com
+ public_ip: 24.222.0.4
+ public_hostname: node3.example.com
+ node: true
+ - connect_to: 10.0.0.5
+ ip: 10.0.0.5
+ hostname: proxy-private.example.com
+ public_ip: 24.222.0.5
+ public_hostname: proxy.example.com
+ master_lb: true
+ - connect_to: 10.1.0.1
+ ip: 10.1.0.1
+ hostname: storage-private.example.com
+ public_ip: 24.222.0.6
+ public_hostname: storage.example.com
+ storage: true
+"""
+
+QUICKHA_2_MASTER_CONFIG = """
+variant: %s
+ansible_ssh_user: root
+hosts:
+ - connect_to: 10.0.0.1
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.2
+ ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.4
+ ip: 10.0.0.4
+ hostname: node3-private.example.com
+ public_ip: 24.222.0.4
+ public_hostname: node3.example.com
+ node: true
+ - connect_to: 10.0.0.5
+ ip: 10.0.0.5
+ hostname: proxy-private.example.com
+ public_ip: 24.222.0.5
+ public_hostname: proxy.example.com
+ master_lb: true
+ - connect_to: 10.1.0.1
+ ip: 10.1.0.1
+ hostname: storage-private.example.com
+ public_ip: 24.222.0.6
+ public_hostname: storage.example.com
+ storage: true
+"""
+
+QUICKHA_CONFIG_REUSED_LB = """
+variant: %s
+ansible_ssh_user: root
+hosts:
+ - connect_to: 10.0.0.1
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.2
+ ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ master: true
+ node: true
+ master_lb: true
+ - connect_to: 10.0.0.3
+ ip: 10.0.0.3
+ hostname: node2-private.example.com
+ public_ip: 24.222.0.3
+ public_hostname: node2.example.com
+ node: true
+ master: true
+ - connect_to: 10.1.0.1
+ ip: 10.1.0.1
+ hostname: storage-private.example.com
+ public_ip: 24.222.0.6
+ public_hostname: storage.example.com
+ storage: true
+"""
+
+QUICKHA_CONFIG_NO_LB = """
+variant: %s
+ansible_ssh_user: root
+hosts:
+ - connect_to: 10.0.0.1
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.2
+ ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.3
+ ip: 10.0.0.3
+ hostname: node2-private.example.com
+ public_ip: 24.222.0.3
+ public_hostname: node2.example.com
+ node: true
+ master: true
+"""
+
+QUICKHA_CONFIG_PRECONFIGURED_LB = """
+variant: %s
+ansible_ssh_user: root
+master_routingconfig_subdomain: example.com
+hosts:
+ - connect_to: 10.0.0.1
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.2
+ ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.3
+ ip: 10.0.0.3
+ hostname: node2-private.example.com
+ public_ip: 24.222.0.3
+ public_hostname: node2.example.com
+ node: true
+ master: true
+ - connect_to: 10.0.0.4
+ ip: 10.0.0.4
+ hostname: node3-private.example.com
+ public_ip: 24.222.0.4
+ public_hostname: node3.example.com
+ node: true
+ - connect_to: proxy-private.example.com
+ hostname: proxy-private.example.com
+ public_hostname: proxy.example.com
+ master_lb: true
+ preconfigured: true
+ - connect_to: 10.1.0.1
+ ip: 10.1.0.1
+ hostname: storage-private.example.com
+ public_ip: 24.222.0.6
+ public_hostname: storage.example.com
+ storage: true
+"""
+
+class UnattendedCliTests(OOCliFixture):
+
+ def setUp(self):
+ OOCliFixture.setUp(self)
+ self.cli_args.append("-u")
+
+ # unattended with config file and all installed hosts (without --force)
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_get_hosts_to_run_on1(self, load_facts_mock, run_playbook_mock):
+ mock_facts = copy.deepcopy(MOCK_FACTS)
+ mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
+ mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
+ mock_facts['10.0.0.3']['common']['version'] = "3.0.0"
+
+ load_facts_mock.return_value = (mock_facts, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+
+ if result.exception is None or result.exit_code != 1:
+ print "Exit code: %s" % result.exit_code
+ self.fail("Unexpected CLI return")
+
+ # unattended with config file and all installed hosts (with --force)
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_get_hosts_to_run_on2(self, load_facts_mock, run_playbook_mock):
+ mock_facts = copy.deepcopy(MOCK_FACTS)
+ mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
+ mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
+ mock_facts['10.0.0.3']['common']['version'] = "3.0.0"
+ self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
+ cli_input=None,
+ exp_hosts_len=3,
+ exp_hosts_to_run_on_len=3,
+ force=True)
+
+ # unattended with config file and no installed hosts (without --force)
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_get_hosts_to_run_on3(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+ self._verify_get_hosts_to_run_on(MOCK_FACTS, load_facts_mock, run_playbook_mock,
+ cli_input=None,
+ exp_hosts_len=3,
+ exp_hosts_to_run_on_len=3,
+ force=False)
+
+ # unattended with config file and no installed hosts (with --force)
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_get_hosts_to_run_on4(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+ self._verify_get_hosts_to_run_on(MOCK_FACTS, load_facts_mock, run_playbook_mock,
+ cli_input=None,
+ exp_hosts_len=3,
+ exp_hosts_to_run_on_len=3,
+ force=True)
+
+ # unattended with config file and some installed some uninstalled hosts (without --force)
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_get_hosts_to_run_on5(self, load_facts_mock, run_playbook_mock):
+ mock_facts = copy.deepcopy(MOCK_FACTS)
+ mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
+ mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
+ self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
+ cli_input=None,
+ exp_hosts_len=3,
+ exp_hosts_to_run_on_len=2,
+ force=False)
+
+ # unattended with config file and some installed some uninstalled hosts (with --force)
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_get_hosts_to_run_on6(self, load_facts_mock, run_playbook_mock):
+ mock_facts = copy.deepcopy(MOCK_FACTS)
+ mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
+ mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
+ self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock, run_playbook_mock,
+ cli_input=None,
+ exp_hosts_len=3,
+ exp_hosts_to_run_on_len=3,
+ force=True)
+
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_cfg_full_run(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+ self.assert_result(result, 0)
+
+ load_facts_args = load_facts_mock.call_args[0]
+ self.assertEquals(os.path.join(self.work_dir, ".ansible/hosts"),
+ load_facts_args[0])
+ self.assertEquals(os.path.join(self.work_dir,
+ "playbooks/byo/openshift_facts.yml"), load_facts_args[1])
+ env_vars = load_facts_args[2]
+ self.assertEquals(os.path.join(self.work_dir,
+ '.ansible/callback_facts.yaml'),
+ env_vars['OO_INSTALL_CALLBACK_FACTS_YAML'])
+ self.assertEqual('/tmp/ansible.log', env_vars['ANSIBLE_LOG_PATH'])
+ # If user running test has rpm installed, this might be set to default:
+ self.assertTrue('ANSIBLE_CONFIG' not in env_vars or
+ env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
+
+ # Make sure we ran on the expected masters and nodes:
+ hosts = run_playbook_mock.call_args[0][0]
+ hosts_to_run_on = run_playbook_mock.call_args[0][1]
+ self.assertEquals(3, len(hosts))
+ self.assertEquals(3, len(hosts_to_run_on))
+
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_inventory_write(self, load_facts_mock, run_playbook_mock):
+
+ # Add an ssh user so we can verify it makes it to the inventory file:
+ merged_config = "%s\n%s" % (SAMPLE_CONFIG % 'openshift-enterprise',
+ "ansible_ssh_user: bob")
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), merged_config)
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+ self.assert_result(result, 0)
+
+ # Check the inventory file looks as we would expect:
+ inventory = ConfigParser.ConfigParser(allow_no_value=True)
+ inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
+ self.assertEquals('bob',
+ inventory.get('OSEv3:vars', 'ansible_ssh_user'))
+ self.assertEquals('openshift-enterprise',
+ inventory.get('OSEv3:vars', 'deployment_type'))
+
+ # Check the masters:
+ self.assertEquals(1, len(inventory.items('masters')))
+ self.assertEquals(3, len(inventory.items('nodes')))
+
+ for item in inventory.items('masters'):
+ # ansible host lines do NOT parse nicely:
+ master_line = item[0]
+ if item[1] is not None:
+ master_line = "%s=%s" % (master_line, item[1])
+ self.assertTrue('openshift_ip' in master_line)
+ self.assertTrue('openshift_public_ip' in master_line)
+ self.assertTrue('openshift_hostname' in master_line)
+ self.assertTrue('openshift_public_hostname' in master_line)
+
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_variant_version_latest_assumed(self, load_facts_mock,
+ run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+ self.assert_result(result, 0)
+
+ written_config = read_yaml(config_file)
+
+ self.assertEquals('openshift-enterprise', written_config['variant'])
+ # We didn't specify a version so the latest should have been assumed,
+ # and written to disk:
+ self.assertEquals('3.1', written_config['variant_version'])
+
+ # Make sure the correct value was passed to ansible:
+ inventory = ConfigParser.ConfigParser(allow_no_value=True)
+ inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
+ self.assertEquals('openshift-enterprise',
+ inventory.get('OSEv3:vars', 'deployment_type'))
+
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_variant_version_preserved(self, load_facts_mock,
+ run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ config = SAMPLE_CONFIG % 'openshift-enterprise'
+ config = '%s\n%s' % (config, 'variant_version: 3.0')
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), config)
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+ self.assert_result(result, 0)
+
+ written_config = read_yaml(config_file)
+
+ self.assertEquals('openshift-enterprise', written_config['variant'])
+ # Make sure our older version was preserved:
+ # and written to disk:
+ self.assertEquals('3.0', written_config['variant_version'])
+
+ inventory = ConfigParser.ConfigParser(allow_no_value=True)
+ inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
+ self.assertEquals('enterprise',
+ inventory.get('OSEv3:vars', 'deployment_type'))
+
+ @patch('ooinstall.openshift_ansible.run_ansible')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_no_ansible_config_specified(self, load_facts_mock, run_ansible_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_ansible_mock.return_value = 0
+
+ config = SAMPLE_CONFIG % 'openshift-enterprise'
+
+ self._ansible_config_test(load_facts_mock, run_ansible_mock,
+ config, None, None)
+
+ @patch('ooinstall.openshift_ansible.run_ansible')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_ansible_config_specified_cli(self, load_facts_mock, run_ansible_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_ansible_mock.return_value = 0
+
+ config = SAMPLE_CONFIG % 'openshift-enterprise'
+ ansible_config = os.path.join(self.work_dir, 'ansible.cfg')
+
+ self._ansible_config_test(load_facts_mock, run_ansible_mock,
+ config, ansible_config, ansible_config)
+
+ @patch('ooinstall.openshift_ansible.run_ansible')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_ansible_config_specified_in_installer_config(self,
+ load_facts_mock, run_ansible_mock):
+
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_ansible_mock.return_value = 0
+
+ ansible_config = os.path.join(self.work_dir, 'ansible.cfg')
+ config = SAMPLE_CONFIG % 'openshift-enterprise'
+ config = "%s\nansible_config: %s" % (config, ansible_config)
+ self._ansible_config_test(load_facts_mock, run_ansible_mock,
+ config, None, ansible_config)
+
+ #pylint: disable=too-many-arguments
+ # This method allows for drastically simpler tests to write, and the args
+ # are all useful.
+ def _ansible_config_test(self, load_facts_mock, run_ansible_mock,
+ installer_config, ansible_config_cli=None, expected_result=None):
+ """
+ Utility method for testing the ways you can specify the ansible config.
+ """
+
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_ansible_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), installer_config)
+
+ self.cli_args.extend(["-c", config_file])
+ if ansible_config_cli:
+ self.cli_args.extend(["--ansible-config", ansible_config_cli])
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli, self.cli_args)
+ self.assert_result(result, 0)
+
+ # Test the env vars for facts playbook:
+ facts_env_vars = load_facts_mock.call_args[0][2]
+ if expected_result:
+ self.assertEquals(expected_result, facts_env_vars['ANSIBLE_CONFIG'])
+ else:
+ # If user running test has rpm installed, this might be set to default:
+ self.assertTrue('ANSIBLE_CONFIG' not in facts_env_vars or
+ facts_env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
+
+ # Test the env vars for main playbook:
+ env_vars = run_ansible_mock.call_args[0][2]
+ if expected_result:
+ self.assertEquals(expected_result, env_vars['ANSIBLE_CONFIG'])
+ else:
+ # If user running test has rpm installed, this might be set to default:
+ self.assertTrue('ANSIBLE_CONFIG' not in env_vars or
+ env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG)
+
+ # unattended with bad config file and no installed hosts (without --force)
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_bad_config(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), BAD_CONFIG % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+
+ self.assertEquals(1, result.exit_code)
+ self.assertTrue("You must specify either an ip or hostname"
+ in result.output)
+
+ #unattended with three masters, one node, and haproxy
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_quick_ha_full_run(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), QUICKHA_CONFIG % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+ self.assert_result(result, 0)
+
+ # Make sure we ran on the expected masters and nodes:
+ hosts = run_playbook_mock.call_args[0][0]
+ hosts_to_run_on = run_playbook_mock.call_args[0][1]
+ self.assertEquals(6, len(hosts))
+ self.assertEquals(6, len(hosts_to_run_on))
+
+ #unattended with two masters, one node, and haproxy
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_quick_ha_only_2_masters(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), QUICKHA_2_MASTER_CONFIG % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+
+ # This is an invalid config:
+ self.assert_result(result, 1)
+ self.assertTrue("A minimum of 3 Masters are required" in result.output)
+
+ #unattended with three masters, one node, but no load balancer specified:
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_quick_ha_no_lb(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), QUICKHA_CONFIG_NO_LB % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+
+ # This is not a valid input:
+ self.assert_result(result, 1)
+ self.assertTrue('No master load balancer specified in config' in result.output)
+
+ #unattended with three masters, one node, and one of the masters reused as load balancer:
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_quick_ha_reused_lb(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), QUICKHA_CONFIG_REUSED_LB % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+
+ # This is not a valid configuration:
+ self.assert_result(result, 1)
+
+ #unattended with preconfigured lb
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_quick_ha_preconfigured_lb(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), QUICKHA_CONFIG_PRECONFIGURED_LB % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ result = self.runner.invoke(cli.cli, self.cli_args)
+ self.assert_result(result, 0)
+
+ # Make sure we ran on the expected masters and nodes:
+ hosts = run_playbook_mock.call_args[0][0]
+ hosts_to_run_on = run_playbook_mock.call_args[0][1]
+ self.assertEquals(6, len(hosts))
+ self.assertEquals(6, len(hosts_to_run_on))
+
+class AttendedCliTests(OOCliFixture):
+
+ def setUp(self):
+ OOCliFixture.setUp(self)
+ # Doesn't exist but keeps us from reading the local users config:
+ self.config_file = os.path.join(self.work_dir, 'config.yml')
+ self.cli_args.extend(["-c", self.config_file])
+
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_full_run(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ cli_input = build_input(hosts=[
+ ('10.0.0.1', True, False),
+ ('10.0.0.2', False, False),
+ ('10.0.0.3', False, False)],
+ ssh_user='root',
+ variant_num=1,
+ confirm_facts='y')
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli, self.cli_args,
+ input=cli_input)
+ self.assert_result(result, 0)
+
+ self._verify_load_facts(load_facts_mock)
+ self._verify_run_playbook(run_playbook_mock, 3, 3)
+
+ written_config = read_yaml(self.config_file)
+ self._verify_config_hosts(written_config, 3)
+
+ inventory = ConfigParser.ConfigParser(allow_no_value=True)
+ inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
+ self.assertEquals('False',
+ inventory.get('nodes', '10.0.0.1 openshift_schedulable'))
+ self.assertEquals(None,
+ inventory.get('nodes', '10.0.0.2'))
+ self.assertEquals(None,
+ inventory.get('nodes', '10.0.0.3'))
+
+ # interactive with config file and some installed some uninstalled hosts
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_add_nodes(self, load_facts_mock, run_playbook_mock):
+
+ # Modify the mock facts to return a version indicating OpenShift
+ # is already installed on our master, and the first node.
+ mock_facts = copy.deepcopy(MOCK_FACTS)
+ mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
+ mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
+
+ load_facts_mock.return_value = (mock_facts, 0)
+ run_playbook_mock.return_value = 0
+
+ cli_input = build_input(hosts=[
+ ('10.0.0.1', True, False),
+ ('10.0.0.2', False, False),
+ ],
+ add_nodes=[('10.0.0.3', False, False)],
+ ssh_user='root',
+ variant_num=1,
+ confirm_facts='y')
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli,
+ self.cli_args,
+ input=cli_input)
+ self.assert_result(result, 0)
+
+ self._verify_load_facts(load_facts_mock)
+ self._verify_run_playbook(run_playbook_mock, 3, 2)
+
+ written_config = read_yaml(self.config_file)
+ self._verify_config_hosts(written_config, 3)
+
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_fresh_install_with_config(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ config_file = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'),
+ SAMPLE_CONFIG % 'openshift-enterprise')
+ cli_input = build_input(confirm_facts='y')
+ self.cli_args.extend(["-c", config_file])
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli,
+ self.cli_args,
+ input=cli_input)
+ self.assert_result(result, 0)
+
+ self._verify_load_facts(load_facts_mock)
+ self._verify_run_playbook(run_playbook_mock, 3, 3)
+
+ written_config = read_yaml(config_file)
+ self._verify_config_hosts(written_config, 3)
+
+ #interactive with config file and all installed hosts
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_get_hosts_to_run_on(self, load_facts_mock, run_playbook_mock):
+ mock_facts = copy.deepcopy(MOCK_FACTS)
+ mock_facts['10.0.0.1']['common']['version'] = "3.0.0"
+ mock_facts['10.0.0.2']['common']['version'] = "3.0.0"
+
+ cli_input = build_input(hosts=[
+ ('10.0.0.1', True, False),
+ ],
+ add_nodes=[('10.0.0.2', False, False)],
+ ssh_user='root',
+ variant_num=1,
+ schedulable_masters_ok=True,
+ confirm_facts='y')
+
+ self._verify_get_hosts_to_run_on(mock_facts, load_facts_mock,
+ run_playbook_mock,
+ cli_input,
+ exp_hosts_len=2,
+ exp_hosts_to_run_on_len=2,
+ force=False)
+
+ #interactive multimaster: one more node than master
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_ha_dedicated_node(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
+ run_playbook_mock.return_value = 0
+
+ cli_input = build_input(hosts=[
+ ('10.0.0.1', True, False),
+ ('10.0.0.2', True, False),
+ ('10.0.0.3', True, False),
+ ('10.0.0.4', False, False)],
+ ssh_user='root',
+ variant_num=1,
+ confirm_facts='y',
+ master_lb=('10.0.0.5', False),
+ storage='10.1.0.1',)
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli, self.cli_args,
+ input=cli_input)
+ self.assert_result(result, 0)
+
+ self._verify_load_facts(load_facts_mock)
+ self._verify_run_playbook(run_playbook_mock, 6, 6)
+
+ written_config = read_yaml(self.config_file)
+ self._verify_config_hosts(written_config, 6)
+
+ inventory = ConfigParser.ConfigParser(allow_no_value=True)
+ inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
+ self.assertEquals('False',
+ inventory.get('nodes', '10.0.0.1 openshift_schedulable'))
+ self.assertEquals('False',
+ inventory.get('nodes', '10.0.0.2 openshift_schedulable'))
+ self.assertEquals('False',
+ inventory.get('nodes', '10.0.0.3 openshift_schedulable'))
+ self.assertEquals(None,
+ inventory.get('nodes', '10.0.0.4'))
+
+ self.assertTrue(inventory.has_section('etcd'))
+ self.assertEquals(3, len(inventory.items('etcd')))
+
+ #interactive multimaster: identical masters and nodes
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_ha_no_dedicated_nodes(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
+ run_playbook_mock.return_value = 0
+
+ cli_input = build_input(hosts=[
+ ('10.0.0.1', True, False),
+ ('10.0.0.2', True, False),
+ ('10.0.0.3', True, False)],
+ ssh_user='root',
+ variant_num=1,
+ confirm_facts='y',
+ master_lb=('10.0.0.5', False),
+ storage='10.1.0.1',)
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli, self.cli_args,
+ input=cli_input)
+ self.assert_result(result, 0)
+
+ self._verify_load_facts(load_facts_mock)
+ self._verify_run_playbook(run_playbook_mock, 5, 5)
+
+ written_config = read_yaml(self.config_file)
+ self._verify_config_hosts(written_config, 5)
+
+ inventory = ConfigParser.ConfigParser(allow_no_value=True)
+ inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
+ self.assertEquals('True',
+ inventory.get('nodes', '10.0.0.1 openshift_schedulable'))
+ self.assertEquals('True',
+ inventory.get('nodes', '10.0.0.2 openshift_schedulable'))
+ self.assertEquals('True',
+ inventory.get('nodes', '10.0.0.3 openshift_schedulable'))
+
+ #interactive multimaster: attempting to use a master as the load balancer should fail:
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_ha_reuse_master_as_lb(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0)
+ run_playbook_mock.return_value = 0
+
+ cli_input = build_input(hosts=[
+ ('10.0.0.1', True, False),
+ ('10.0.0.2', True, False),
+ ('10.0.0.3', False, False),
+ ('10.0.0.4', True, False)],
+ ssh_user='root',
+ variant_num=1,
+ confirm_facts='y',
+ master_lb=(['10.0.0.2', '10.0.0.5'], False),
+ storage='10.1.0.1')
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli, self.cli_args,
+ input=cli_input)
+ self.assert_result(result, 0)
+
+ #interactive all-in-one
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_all_in_one(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ cli_input = build_input(hosts=[
+ ('10.0.0.1', True, False)],
+ ssh_user='root',
+ variant_num=1,
+ confirm_facts='y')
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli, self.cli_args,
+ input=cli_input)
+ self.assert_result(result, 0)
+
+ self._verify_load_facts(load_facts_mock)
+ self._verify_run_playbook(run_playbook_mock, 1, 1)
+
+ written_config = read_yaml(self.config_file)
+ self._verify_config_hosts(written_config, 1)
+
+ inventory = ConfigParser.ConfigParser(allow_no_value=True)
+ inventory.read(os.path.join(self.work_dir, '.ansible/hosts'))
+ self.assertEquals('True',
+ inventory.get('nodes', '10.0.0.1 openshift_schedulable'))
+
+ #interactive 3.0 install confirm no HA hints
+ @patch('ooinstall.openshift_ansible.run_main_playbook')
+ @patch('ooinstall.openshift_ansible.load_system_facts')
+ def test_ha_hint(self, load_facts_mock, run_playbook_mock):
+ load_facts_mock.return_value = (MOCK_FACTS, 0)
+ run_playbook_mock.return_value = 0
+
+ cli_input = build_input(hosts=[
+ ('10.0.0.1', True, False)],
+ ssh_user='root',
+ variant_num=2,
+ confirm_facts='y')
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli, self.cli_args,
+ input=cli_input)
+ self.assert_result(result, 0)
+ self.assertTrue("NOTE: Add a total of 3 or more Masters to perform an HA installation."
+ not in result.output)
+
+# TODO: test with config file, attended add node
+# TODO: test with config file, attended new node already in config file
+# TODO: test with config file, attended new node already in config file, plus manually added nodes
+# TODO: test with config file, attended reject facts
diff --git a/utils/test/fixture.py b/utils/test/fixture.py
new file mode 100644
index 000000000..d6222dfaa
--- /dev/null
+++ b/utils/test/fixture.py
@@ -0,0 +1,236 @@
+# pylint: disable=missing-docstring
+import os
+import yaml
+
+import ooinstall.cli_installer as cli
+
+from test.oo_config_tests import OOInstallFixture
+from click.testing import CliRunner
+
+# Substitute in a product name before use:
+SAMPLE_CONFIG = """
+variant: %s
+ansible_ssh_user: root
+master_routingconfig_subdomain: example.com
+hosts:
+ - connect_to: 10.0.0.1
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - connect_to: 10.0.0.2
+ ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ node: true
+ - connect_to: 10.0.0.3
+ ip: 10.0.0.3
+ hostname: node2-private.example.com
+ public_ip: 24.222.0.3
+ public_hostname: node2.example.com
+ node: true
+"""
+
+def read_yaml(config_file_path):
+ cfg_f = open(config_file_path, 'r')
+ config = yaml.safe_load(cfg_f.read())
+ cfg_f.close()
+ return config
+
+
+class OOCliFixture(OOInstallFixture):
+
+ def setUp(self):
+ OOInstallFixture.setUp(self)
+ self.runner = CliRunner()
+
+ # Add any arguments you would like to test here, the defaults ensure
+ # we only do unattended invocations here, and using temporary files/dirs.
+ self.cli_args = ["-a", self.work_dir]
+
+ def run_cli(self):
+ return self.runner.invoke(cli.cli, self.cli_args)
+
+ def assert_result(self, result, exit_code):
+ if result.exit_code != exit_code:
+ print "Unexpected result from CLI execution"
+ print "Exit code: %s" % result.exit_code
+ print "Exception: %s" % result.exception
+ print result.exc_info
+ import traceback
+ traceback.print_exception(*result.exc_info)
+ print "Output:\n%s" % result.output
+ self.fail("Exception during CLI execution")
+
+ def _verify_load_facts(self, load_facts_mock):
+ """ Check that we ran load facts with expected inputs. """
+ load_facts_args = load_facts_mock.call_args[0]
+ self.assertEquals(os.path.join(self.work_dir, ".ansible/hosts"),
+ load_facts_args[0])
+ self.assertEquals(os.path.join(self.work_dir,
+ "playbooks/byo/openshift_facts.yml"),
+ load_facts_args[1])
+ env_vars = load_facts_args[2]
+ self.assertEquals(os.path.join(self.work_dir,
+ '.ansible/callback_facts.yaml'),
+ env_vars['OO_INSTALL_CALLBACK_FACTS_YAML'])
+ self.assertEqual('/tmp/ansible.log', env_vars['ANSIBLE_LOG_PATH'])
+
+ def _verify_run_playbook(self, run_playbook_mock, exp_hosts_len, exp_hosts_to_run_on_len):
+ """ Check that we ran playbook with expected inputs. """
+ hosts = run_playbook_mock.call_args[0][0]
+ hosts_to_run_on = run_playbook_mock.call_args[0][1]
+ self.assertEquals(exp_hosts_len, len(hosts))
+ self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))
+
+ def _verify_config_hosts(self, written_config, host_count):
+ self.assertEquals(host_count, len(written_config['hosts']))
+ for host in written_config['hosts']:
+ self.assertTrue('hostname' in host)
+ self.assertTrue('public_hostname' in host)
+ if 'preconfigured' not in host:
+ self.assertTrue('node' in host or 'storage' in host)
+ self.assertTrue('ip' in host)
+ self.assertTrue('public_ip' in host)
+
+ #pylint: disable=too-many-arguments
+ def _verify_get_hosts_to_run_on(self, mock_facts, load_facts_mock,
+ run_playbook_mock, cli_input,
+ exp_hosts_len=None, exp_hosts_to_run_on_len=None,
+ force=None):
+ """
+ Tests cli_installer.py:get_hosts_to_run_on. That method has quite a
+ few subtle branches in the logic. The goal with this method is simply
+ to handle all the messy stuff here and allow the main test cases to be
+ easily read. The basic idea is to modify mock_facts to return a
+ version indicating OpenShift is already installed on particular hosts.
+ """
+ load_facts_mock.return_value = (mock_facts, 0)
+ run_playbook_mock.return_value = 0
+
+ if cli_input:
+ self.cli_args.append("install")
+ result = self.runner.invoke(cli.cli,
+ self.cli_args,
+ input=cli_input)
+ else:
+ config_file = self.write_config(
+ os.path.join(self.work_dir,
+ 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise')
+
+ self.cli_args.extend(["-c", config_file, "install"])
+ if force:
+ self.cli_args.append("--force")
+ result = self.runner.invoke(cli.cli, self.cli_args)
+ written_config = read_yaml(config_file)
+ self._verify_config_hosts(written_config, exp_hosts_len)
+
+ self.assert_result(result, 0)
+ self._verify_load_facts(load_facts_mock)
+ self._verify_run_playbook(run_playbook_mock, exp_hosts_len, exp_hosts_to_run_on_len)
+
+ # Make sure we ran on the expected masters and nodes:
+ hosts = run_playbook_mock.call_args[0][0]
+ hosts_to_run_on = run_playbook_mock.call_args[0][1]
+ self.assertEquals(exp_hosts_len, len(hosts))
+ self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on))
+
+
+#pylint: disable=too-many-arguments,too-many-branches,too-many-statements
+def build_input(ssh_user=None, hosts=None, variant_num=None,
+ add_nodes=None, confirm_facts=None, schedulable_masters_ok=None,
+ master_lb=None, storage=None):
+ """
+ Build an input string simulating a user entering values in an interactive
+ attended install.
+
+ This is intended to give us one place to update when the CLI prompts change.
+ We should aim to keep this dependent on optional keyword arguments with
+ sensible defaults to keep things from getting too fragile.
+ """
+
+ inputs = [
+ 'y', # let's proceed
+ ]
+ if ssh_user:
+ inputs.append(ssh_user)
+
+ if variant_num:
+ inputs.append(str(variant_num)) # Choose variant + version
+
+ num_masters = 0
+ if hosts:
+ i = 0
+ for (host, is_master, is_containerized) in hosts:
+ inputs.append(host)
+ if is_master:
+ inputs.append('y')
+ num_masters += 1
+ else:
+ inputs.append('n')
+
+ if is_containerized:
+ inputs.append('container')
+ else:
+ inputs.append('rpm')
+
+ #inputs.append('rpm')
+ # We should not be prompted to add more hosts if we're currently at
+ # 2 masters, this is an invalid HA configuration, so this question
+ # will not be asked, and the user must enter the next host:
+ if num_masters != 2:
+ if i < len(hosts) - 1:
+ if num_masters >= 1:
+ inputs.append('y') # Add more hosts
+ else:
+ inputs.append('n') # Done adding hosts
+ i += 1
+
+ # You can pass a single master_lb or a list if you intend for one to get rejected:
+ if master_lb:
+ if isinstance(master_lb[0], list) or isinstance(master_lb[0], tuple):
+ inputs.extend(master_lb[0])
+ else:
+ inputs.append(master_lb[0])
+ inputs.append('y' if master_lb[1] else 'n')
+
+ if storage:
+ inputs.append(storage)
+
+ inputs.append('subdomain.example.com')
+
+ # TODO: support option 2, fresh install
+ if add_nodes:
+ if schedulable_masters_ok:
+ inputs.append('y')
+ inputs.append('1') # Add more nodes
+ i = 0
+ for (host, is_master, is_containerized) in add_nodes:
+ inputs.append(host)
+ if is_containerized:
+ inputs.append('container')
+ else:
+ inputs.append('rpm')
+ #inputs.append('rpm')
+ if i < len(add_nodes) - 1:
+ inputs.append('y') # Add more hosts
+ else:
+ inputs.append('n') # Done adding hosts
+ i += 1
+
+ if add_nodes is None:
+ total_hosts = hosts
+ else:
+ total_hosts = hosts + add_nodes
+ if total_hosts is not None and num_masters == len(total_hosts):
+ inputs.append('y')
+
+ inputs.extend([
+ confirm_facts,
+ 'y', # lets do this
+ ])
+
+ return '\n'.join(inputs)
diff --git a/utils/test/oo_config_tests.py b/utils/test/oo_config_tests.py
new file mode 100644
index 000000000..9f5f8e244
--- /dev/null
+++ b/utils/test/oo_config_tests.py
@@ -0,0 +1,262 @@
+# TODO: Temporarily disabled due to importing old code into openshift-ansible
+# repo. We will work on these over time.
+# pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name
+
+import os
+import unittest
+import tempfile
+import shutil
+import yaml
+
+from ooinstall.oo_config import OOConfig, Host, OOConfigInvalidHostError
+
+SAMPLE_CONFIG = """
+variant: openshift-enterprise
+ansible_ssh_user: root
+hosts:
+ - connect_to: master-private.example.com
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - connect_to: node1-private.example.com
+ ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ node: true
+ - connect_to: node2-private.example.com
+ ip: 10.0.0.3
+ hostname: node2-private.example.com
+ public_ip: 24.222.0.3
+ public_hostname: node2.example.com
+ node: true
+"""
+
+# Used to test automatic upgrading of config:
+LEGACY_CONFIG = """
+Description: This is the configuration file for the OpenShift Ansible-Based Installer.
+Name: OpenShift Ansible-Based Installer Configuration
+Subscription: {type: none}
+Vendor: OpenShift Community
+Version: 0.0.1
+ansible_config: /tmp/notreal/ansible.cfg
+ansible_inventory_directory: /tmp/notreal/.config/openshift/.ansible
+ansible_log_path: /tmp/ansible.log
+ansible_plugins_directory: /tmp/notreal/.python-eggs/ooinstall-3.0.0-py2.7.egg-tmp/ooinstall/ansible_plugins
+masters: [10.0.0.1]
+nodes: [10.0.0.2, 10.0.0.3]
+validated_facts:
+ 10.0.0.1: {hostname: master-private.example.com, ip: 10.0.0.1, public_hostname: master.example.com, public_ip: 24.222.0.1}
+ 10.0.0.2: {hostname: node1-private.example.com, ip: 10.0.0.2, public_hostname: node1.example.com, public_ip: 24.222.0.2}
+ 10.0.0.3: {hostname: node2-private.example.com, ip: 10.0.0.3, public_hostname: node2.example.com, public_ip: 24.222.0.3}
+"""
+
+
+CONFIG_INCOMPLETE_FACTS = """
+hosts:
+ - connect_to: 10.0.0.1
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ - connect_to: 10.0.0.2
+ ip: 10.0.0.2
+ hostname: 24.222.0.2
+ public_ip: 24.222.0.2
+ node: true
+ - connect_to: 10.0.0.3
+ ip: 10.0.0.3
+ node: true
+"""
+
+CONFIG_BAD = """
+variant: openshift-enterprise
+ansible_ssh_user: root
+hosts:
+ - connect_to: master-private.example.com
+ ip: 10.0.0.1
+ hostname: master-private.example.com
+ public_ip: 24.222.0.1
+ public_hostname: master.example.com
+ master: true
+ node: true
+ - ip: 10.0.0.2
+ hostname: node1-private.example.com
+ public_ip: 24.222.0.2
+ public_hostname: node1.example.com
+ node: true
+ - connect_to: node2-private.example.com
+ ip: 10.0.0.3
+ hostname: node2-private.example.com
+ public_ip: 24.222.0.3
+ public_hostname: node2.example.com
+ node: true
+"""
+
+class OOInstallFixture(unittest.TestCase):
+
+ def setUp(self):
+ self.tempfiles = []
+ self.work_dir = tempfile.mkdtemp(prefix='ooconfigtests')
+ self.tempfiles.append(self.work_dir)
+
+ def tearDown(self):
+ for path in self.tempfiles:
+ if os.path.isdir(path):
+ shutil.rmtree(path)
+ else:
+ os.remove(path)
+
+ def write_config(self, path, config_str):
+ """
+ Write given config to a temporary file which will be cleaned
+ up in teardown.
+ Returns full path to the file.
+ """
+ cfg_file = open(path, 'w')
+ cfg_file.write(config_str)
+ cfg_file.close()
+ return path
+
+
+class LegacyOOConfigTests(OOInstallFixture):
+
+ def setUp(self):
+ OOInstallFixture.setUp(self)
+ self.cfg_path = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), LEGACY_CONFIG)
+ self.cfg = OOConfig(self.cfg_path)
+
+ def test_load_config_memory(self):
+ self.assertEquals('openshift-enterprise', self.cfg.settings['variant'])
+ self.assertEquals('3.0', self.cfg.settings['variant_version'])
+ self.assertEquals('v1', self.cfg.settings['version'])
+
+ self.assertEquals(3, len(self.cfg.hosts))
+ h1 = self.cfg.get_host('10.0.0.1')
+ self.assertEquals('10.0.0.1', h1.ip)
+ self.assertEquals('24.222.0.1', h1.public_ip)
+ self.assertEquals('master-private.example.com', h1.hostname)
+ self.assertEquals('master.example.com', h1.public_hostname)
+
+ h2 = self.cfg.get_host('10.0.0.2')
+ self.assertEquals('10.0.0.2', h2.ip)
+ self.assertEquals('24.222.0.2', h2.public_ip)
+ self.assertEquals('node1-private.example.com', h2.hostname)
+ self.assertEquals('node1.example.com', h2.public_hostname)
+
+ h3 = self.cfg.get_host('10.0.0.3')
+ self.assertEquals('10.0.0.3', h3.ip)
+ self.assertEquals('24.222.0.3', h3.public_ip)
+ self.assertEquals('node2-private.example.com', h3.hostname)
+ self.assertEquals('node2.example.com', h3.public_hostname)
+
+ self.assertFalse('masters' in self.cfg.settings)
+ self.assertFalse('nodes' in self.cfg.settings)
+ self.assertFalse('Description' in self.cfg.settings)
+ self.assertFalse('Name' in self.cfg.settings)
+ self.assertFalse('Subscription' in self.cfg.settings)
+ self.assertFalse('Vendor' in self.cfg.settings)
+ self.assertFalse('Version' in self.cfg.settings)
+ self.assertFalse('validates_facts' in self.cfg.settings)
+
+
+class OOConfigTests(OOInstallFixture):
+
+ def test_load_config(self):
+
+ cfg_path = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), SAMPLE_CONFIG)
+ ooconfig = OOConfig(cfg_path)
+
+ self.assertEquals(3, len(ooconfig.hosts))
+ self.assertEquals("master-private.example.com", ooconfig.hosts[0].connect_to)
+ self.assertEquals("10.0.0.1", ooconfig.hosts[0].ip)
+ self.assertEquals("master-private.example.com", ooconfig.hosts[0].hostname)
+
+ self.assertEquals(["10.0.0.1", "10.0.0.2", "10.0.0.3"],
+ [host['ip'] for host in ooconfig.settings['hosts']])
+
+ self.assertEquals('openshift-enterprise', ooconfig.settings['variant'])
+ self.assertEquals('v1', ooconfig.settings['version'])
+
+ def test_load_bad_config(self):
+
+ cfg_path = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), CONFIG_BAD)
+ try:
+ OOConfig(cfg_path)
+ assert False
+ except OOConfigInvalidHostError:
+ assert True
+
+
+ def test_load_complete_facts(self):
+ cfg_path = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), SAMPLE_CONFIG)
+ ooconfig = OOConfig(cfg_path)
+ missing_host_facts = ooconfig.calc_missing_facts()
+ self.assertEquals(0, len(missing_host_facts))
+
+ # Test missing optional facts the user must confirm:
+ def test_load_host_incomplete_facts(self):
+ cfg_path = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), CONFIG_INCOMPLETE_FACTS)
+ ooconfig = OOConfig(cfg_path)
+ missing_host_facts = ooconfig.calc_missing_facts()
+ self.assertEquals(2, len(missing_host_facts))
+ self.assertEquals(1, len(missing_host_facts['10.0.0.2']))
+ self.assertEquals(3, len(missing_host_facts['10.0.0.3']))
+
+ def test_write_config(self):
+ cfg_path = self.write_config(os.path.join(self.work_dir,
+ 'ooinstall.conf'), SAMPLE_CONFIG)
+ ooconfig = OOConfig(cfg_path)
+ ooconfig.save_to_disk()
+
+ f = open(cfg_path, 'r')
+ written_config = yaml.safe_load(f.read())
+ f.close()
+
+ self.assertEquals(3, len(written_config['hosts']))
+ for h in written_config['hosts']:
+ self.assertTrue('ip' in h)
+ self.assertTrue('public_ip' in h)
+ self.assertTrue('hostname' in h)
+ self.assertTrue('public_hostname' in h)
+
+ self.assertTrue('ansible_ssh_user' in written_config)
+ self.assertTrue('variant' in written_config)
+ self.assertEquals('v1', written_config['version'])
+
+ # Some advanced settings should not get written out if they
+ # were not specified by the user:
+ self.assertFalse('ansible_inventory_directory' in written_config)
+
+
+class HostTests(OOInstallFixture):
+
+ def test_load_host_no_ip_or_hostname(self):
+ yaml_props = {
+ 'public_ip': '192.168.0.1',
+ 'public_hostname': 'a.example.com',
+ 'master': True
+ }
+ self.assertRaises(OOConfigInvalidHostError, Host, **yaml_props)
+
+ def test_load_host_no_master_or_node_specified(self):
+ yaml_props = {
+ 'ip': '192.168.0.1',
+ 'hostname': 'a.example.com',
+ 'public_ip': '192.168.0.1',
+ 'public_hostname': 'a.example.com',
+ }
+ self.assertRaises(OOConfigInvalidHostError, Host, **yaml_props)
+
+
+
+