diff options
| -rw-r--r-- | utils/src/ooinstall/cli_installer.py | 20 | ||||
| -rw-r--r-- | utils/src/ooinstall/openshift_ansible.py | 3 | ||||
| -rw-r--r-- | utils/test/cli_installer_tests.py | 132 | ||||
| -rw-r--r-- | utils/test/fixture.py | 8 | 
4 files changed, 124 insertions, 39 deletions
| diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index c53ca7b18..b53545db2 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -837,8 +837,10 @@ def upgrade(ctx):  @click.command()  @click.option('--force', '-f', is_flag=True, default=False) +@click.option('--gen-inventory', is_flag=True, default=False, +              help="Generate an ansible inventory file and exit.")  @click.pass_context -def install(ctx, force): +def install(ctx, force, gen_inventory):      oo_cfg = ctx.obj['oo_cfg']      verbose = ctx.obj['verbose'] @@ -861,7 +863,6 @@ def install(ctx, force):      hosts_to_run_on, callback_facts = get_hosts_to_run_on(          oo_cfg, callback_facts, ctx.obj['unattended'], force, verbose) -    click.echo('Writing config to: %s' % oo_cfg.config_path)      # We already verified this is not the case for unattended installs, so this can      # only trigger for live CLI users: @@ -871,7 +872,18 @@ def install(ctx, force):      if len(oo_cfg.calc_missing_facts()) > 0:          confirm_hosts_facts(oo_cfg, callback_facts) +    # Write quick installer config file to disk:      oo_cfg.save_to_disk() +    # Write ansible inventory file to disk: +    inventory_file = openshift_ansible.generate_inventory(hosts_to_run_on) + +    click.echo() +    click.echo('Wrote atomic-openshift-installer config: %s' % oo_cfg.config_path) +    click.echo("Wrote ansible inventory: %s" % inventory_file) +    click.echo() + +    if gen_inventory: +        sys.exit(0)      click.echo('Ready to run installation process.')      message = """ @@ -880,8 +892,8 @@ If changes are needed please edit the config file above and re-run.      if not ctx.obj['unattended']:          confirm_continue(message) -    error = openshift_ansible.run_main_playbook(oo_cfg.hosts, -                                                   hosts_to_run_on, verbose) +    error = openshift_ansible.run_main_playbook(inventory_file, oo_cfg.hosts, +                                                hosts_to_run_on, verbose)      if error:          # The bootstrap script will print out the log location.          message = """ diff --git a/utils/src/ooinstall/openshift_ansible.py b/utils/src/ooinstall/openshift_ansible.py index 2b95702bf..edf8082fc 100644 --- a/utils/src/ooinstall/openshift_ansible.py +++ b/utils/src/ooinstall/openshift_ansible.py @@ -213,9 +213,8 @@ def default_facts(hosts, verbose=False):      return load_system_facts(inventory_file, os_facts_path, facts_env, verbose) -def run_main_playbook(hosts, hosts_to_run_on, verbose=False): +def run_main_playbook(inventory_file, hosts, hosts_to_run_on, verbose=False):      global CFG -    inventory_file = generate_inventory(hosts_to_run_on)      if len(hosts_to_run_on) != len(hosts):          main_playbook_path = os.path.join(CFG.ansible_playbook_directory,                                            'playbooks/byo/openshift-node/scaleup.yml') diff --git a/utils/test/cli_installer_tests.py b/utils/test/cli_installer_tests.py index 6ba5ec1eb..00136f0c8 100644 --- a/utils/test/cli_installer_tests.py +++ b/utils/test/cli_installer_tests.py @@ -1,6 +1,6 @@  # 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 +# pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,too-many-lines  import copy  import os @@ -417,8 +417,8 @@ class UnattendedCliTests(OOCliFixture):              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] +        hosts = run_playbook_mock.call_args[0][1] +        hosts_to_run_on = run_playbook_mock.call_args[0][2]          self.assertEquals(3, len(hosts))          self.assertEquals(3, len(hosts_to_run_on)) @@ -625,8 +625,8 @@ class UnattendedCliTests(OOCliFixture):          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] +        hosts = run_playbook_mock.call_args[0][1] +        hosts_to_run_on = run_playbook_mock.call_args[0][2]          self.assertEquals(6, len(hosts))          self.assertEquals(6, len(hosts_to_run_on)) @@ -695,8 +695,8 @@ class UnattendedCliTests(OOCliFixture):          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] +        hosts = run_playbook_mock.call_args[0][1] +        hosts_to_run_on = run_playbook_mock.call_args[0][2]          self.assertEquals(6, len(hosts))          self.assertEquals(6, len(hosts_to_run_on)) @@ -734,12 +734,12 @@ class AttendedCliTests(OOCliFixture):          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')) +        self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1', +                                 'openshift_schedulable=False') +        self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.2', +                                 'openshift_schedulable') +        self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.3', +                                 'openshift_schedulable')      # interactive with config file and some installed some uninstalled hosts      @patch('ooinstall.openshift_ansible.run_main_playbook') @@ -852,14 +852,14 @@ class AttendedCliTests(OOCliFixture):          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.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1', +                                       'openshift_schedulable=False') +        self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.2', +                                       'openshift_schedulable=False') +        self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.3', +                                       'openshift_schedulable=False') +        self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.4', +                                             'openshift_schedulable')          self.assertTrue(inventory.has_section('etcd'))          self.assertEquals(3, len(inventory.items('etcd'))) @@ -893,12 +893,49 @@ class AttendedCliTests(OOCliFixture):          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')) +        self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1', +                                       'openshift_schedulable=True') +        self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.2', +                                       'openshift_schedulable=True') +        self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.3', +                                       'openshift_schedulable=True') + +    # Checks the inventory (as a ConfigParser) for the given host, host +    # variable, and expected value. +    def assert_inventory_host_var(self, inventory, section, host, variable): +        # Config parser splits on the first "=", so we end up with: +        #   'hostname key1' -> 'val1 key2=val2 key3=val3' +        # +        # Convert to something easier to test: +        for (a, b) in inventory.items(section): +            full_line = "%s=%s" % (a, b) +            tokens = full_line.split() +            if tokens[0] == host: +                found = False +                for token in tokens: +                    if token == variable: +                        found = True +                        continue +                self.assertTrue("Unable to find %s in line: %s" % +                                (variable, full_line), found) +                return +        self.fail("unable to find host %s in inventory" % host) + +    def assert_inventory_host_var_unset(self, inventory, section, host, variable): +        # Config parser splits on the first "=", so we end up with: +        #   'hostname key1' -> 'val1 key2=val2 key3=val3' +        # +        # Convert to something easier to test: +        for (a, b) in inventory.items(section): +            full_line = "%s=%s" % (a, b) +            tokens = full_line.split() +            if tokens[0] == host: +                self.assertFalse(("%s=" % variable) in full_line, +                                 msg='%s host variable was set: %s' % +                                 (variable, full_line)) +                return +        self.fail("unable to find host %s in inventory" % host) +      #interactive multimaster: attempting to use a master as the load balancer should fail:      @patch('ooinstall.openshift_ansible.run_main_playbook') @@ -947,8 +984,8 @@ class AttendedCliTests(OOCliFixture):          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.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1', +                                       'openshift_schedulable=True')      #interactive 3.0 install confirm no HA hints      @patch('ooinstall.openshift_ansible.run_main_playbook') @@ -969,6 +1006,43 @@ class AttendedCliTests(OOCliFixture):          self.assertTrue("NOTE: Add a total of 3 or more Masters to perform an HA installation."              not in result.output) +    @patch('ooinstall.openshift_ansible.run_main_playbook') +    @patch('ooinstall.openshift_ansible.load_system_facts') +    def test_gen_inventory(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") +        self.cli_args.append("--gen-inventory") +        result = self.runner.invoke(cli.cli, self.cli_args, +            input=cli_input) +        self.assert_result(result, 0) + +        self._verify_load_facts(load_facts_mock) + +        # Make sure run playbook wasn't called: +        self.assertEquals(0, len(run_playbook_mock.mock_calls)) + +        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.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1', +                                 'openshift_schedulable=False') +        self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.2', +                                 'openshift_schedulable') +        self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.3', +                                 'openshift_schedulable') + +  # 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 diff --git a/utils/test/fixture.py b/utils/test/fixture.py index d6222dfaa..eb94418c2 100644 --- a/utils/test/fixture.py +++ b/utils/test/fixture.py @@ -81,8 +81,8 @@ class OOCliFixture(OOInstallFixture):      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] +        hosts = run_playbook_mock.call_args[0][1] +        hosts_to_run_on = run_playbook_mock.call_args[0][2]          self.assertEquals(exp_hosts_len, len(hosts))          self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on)) @@ -133,8 +133,8 @@ class OOCliFixture(OOInstallFixture):          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] +        hosts = run_playbook_mock.call_args[0][1] +        hosts_to_run_on = run_playbook_mock.call_args[0][2]          self.assertEquals(exp_hosts_len, len(hosts))          self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on)) | 
