예제 #1
0
 def test_unchanged_value_does_nothing(
     self, m_subp, update_ssh_config, mock_uses_systemd
 ):
     """If 'unchanged', then no updates to config and no restart."""
     update_ssh_config.assert_not_called()
     cloud = get_cloud("ubuntu")
     setpass.handle_ssh_pwauth("unchanged", cloud.distro)
     assert [
         mock.call(["systemctl", "status", "ssh"], capture=True)
     ] == m_subp.call_args_list
예제 #2
0
 def test_append_random(self):
     cfg = {
         'random_seed': {
             'file': self._seed_file,
             'data': 'tiny-tim-was-here',
         }
     }
     cc_seed_random.handle('test', cfg, get_cloud('ubuntu'), LOG, [])
     contents = util.load_file(self._seed_file)
     self.assertEqual("tiny-tim-was-here", contents)
예제 #3
0
    def test_handle_ssh_keys_in_cfg(self, m_write_file, m_nug, m_setup_keys):
        """Test handle with ssh keys and certificate."""
        # Populate a config dictionary to pass to handle() as well
        # as the expected file-writing calls.
        cfg = {"ssh_keys": {}}

        expected_calls = []
        for key_type in cc_ssh.GENERATE_KEY_NAMES:
            private_name = "{}_private".format(key_type)
            public_name = "{}_public".format(key_type)
            cert_name = "{}_certificate".format(key_type)

            # Actual key contents don't have to be realistic
            private_value = "{}_PRIVATE_KEY".format(key_type)
            public_value = "{}_PUBLIC_KEY".format(key_type)
            cert_value = "{}_CERT_KEY".format(key_type)

            cfg["ssh_keys"][private_name] = private_value
            cfg["ssh_keys"][public_name] = public_value
            cfg["ssh_keys"][cert_name] = cert_value

            expected_calls.extend([
                mock.call(
                    "/etc/ssh/ssh_host_{}_key".format(key_type),
                    private_value,
                    384,
                ),
                mock.call(
                    "/etc/ssh/ssh_host_{}_key.pub".format(key_type),
                    public_value,
                    384,
                ),
                mock.call(
                    "/etc/ssh/ssh_host_{}_key-cert.pub".format(key_type),
                    cert_value,
                    384,
                ),
                mock.call(
                    "/etc/ssh/sshd_config",
                    "HostCertificate /etc/ssh/ssh_host_{}_key-cert.pub"
                    "\n".format(key_type),
                    preserve_mode=True,
                ),
            ])

        # Run the handler.
        m_nug.return_value = ([], {})
        with mock.patch(MODPATH + "ssh_util.parse_ssh_config",
                        return_value=[]):
            cc_ssh.handle("name", cfg, get_cloud(distro="ubuntu"), LOG, None)

        # Check that all expected output has been done.
        for call_ in expected_calls:
            assert call_ in m_write_file.call_args_list
예제 #4
0
 def test_append_random_metadata(self):
     cfg = {
         'random_seed': {
             'file': self._seed_file,
             'data': 'tiny-tim-was-here',
         }
     }
     c = get_cloud('ubuntu', metadata={'random_seed': '-so-was-josh'})
     cc_seed_random.handle('test', cfg, c, LOG, [])
     contents = util.load_file(self._seed_file)
     self.assertEqual('tiny-tim-was-here-so-was-josh', contents)
예제 #5
0
 def test_handler_invalid_command_set(self):
     """Commands which can't be converted to shell will raise errors."""
     invalid_config = {"runcmd": 1}
     cc = get_cloud(paths=self.paths)
     with self.assertRaises(TypeError) as cm:
         handle("cc_runcmd", invalid_config, cc, LOG, [])
     self.assertIn(
         "Failed to shellify 1 into file"
         " /var/lib/cloud/instances/iid-datasource-none/scripts/runcmd",
         str(cm.exception),
     )
예제 #6
0
 def test_handler_invalid_command_set(self):
     """Commands which can't be converted to shell will raise errors."""
     invalid_config = {"bootcmd": 1}
     cc = get_cloud()
     with self.assertRaises(TypeError) as context_manager:
         handle("cc_bootcmd", invalid_config, cc, LOG, [])
     self.assertIn("Failed to shellify bootcmd", self.logs.getvalue())
     self.assertEqual(
         "Input to shellify was type 'int'. Expected list or tuple.",
         str(context_manager.exception),
     )
예제 #7
0
 def test_unavailable_seed_command_and_required_raises_error(self):
     c = get_cloud("ubuntu")
     self.whichdata = {}
     cfg = {
         "random_seed": {
             "command": ["THIS_NO_COMMAND"],
             "command_required": True,
         }
     }
     self.assertRaises(ValueError, cc_seed_random.handle, "test", cfg, c,
                       LOG, [])
예제 #8
0
 def test_locale_rhel_defaults_en_us_utf8(self):
     """Test cc_locale gets en_US.UTF-8 from distro get_locale fallback"""
     cfg = {}
     cc = get_cloud('rhel')
     update_sysconfig = 'cloudinit.distros.rhel_util.update_sysconfig_file'
     with mock.patch.object(cc.distro, 'uses_systemd') as m_use_sd:
         m_use_sd.return_value = True
         with mock.patch(update_sysconfig) as m_update_syscfg:
             cc_locale.handle('cc_locale', cfg, cc, LOG, [])
             m_update_syscfg.assert_called_with('/etc/locale.conf',
                                                {'LANG': 'en_US.UTF-8'})
예제 #9
0
 def test_locale_rhel_defaults_en_us_utf8(self):
     """Test cc_locale gets en_US.UTF-8 from distro get_locale fallback"""
     cfg = {}
     cc = get_cloud("rhel")
     update_sysconfig = "cloudinit.distros.rhel_util.update_sysconfig_file"
     with mock.patch.object(cc.distro, "uses_systemd") as m_use_sd:
         m_use_sd.return_value = True
         with mock.patch(update_sysconfig) as m_update_syscfg:
             cc_locale.handle("cc_locale", cfg, cc, LOG, [])
             m_update_syscfg.assert_called_with("/etc/locale.conf",
                                                {"LANG": "en_US.UTF-8"})
예제 #10
0
 def test_lxd_install(self, mock_subp, m_maybe_clean):
     cc = get_cloud()
     cc.distro = mock.MagicMock()
     mock_subp.which.return_value = None
     cc_lxd.handle('cc_lxd', self.lxd_cfg, cc, self.logger, [])
     self.assertNotIn('WARN', self.logs.getvalue())
     self.assertTrue(cc.distro.install_packages.called)
     cc_lxd.handle('cc_lxd', self.lxd_cfg, cc, self.logger, [])
     self.assertFalse(m_maybe_clean.called)
     install_pkg = cc.distro.install_packages.call_args_list[0][0][0]
     self.assertEqual(sorted(install_pkg), ['lxd', 'zfsutils-linux'])
예제 #11
0
 def test_append_random_unknown_encoding(self):
     data = self._compress(b"tiny-toe")
     cfg = {
         'random_seed': {
             'file': self._seed_file,
             'data': data,
             'encoding': 'special_encoding',
         }
     }
     self.assertRaises(IOError, cc_seed_random.handle, 'test', cfg,
                       get_cloud('ubuntu'), LOG, [])
예제 #12
0
    def test_file_in_environment_for_command(self):
        c = get_cloud('ubuntu')
        self.whichdata = {'foo': 'foo'}
        cfg = {'random_seed': {'command_required': True, 'command': ['foo'],
                               'file': self._seed_file}}
        cc_seed_random.handle('test', cfg, c, LOG, [])

        # this just instists that the first time subp was called,
        # RANDOM_SEED_FILE was in the environment set up correctly
        subp_env = [f['env'] for f in self.subp_called]
        self.assertEqual(subp_env[0].get('RANDOM_SEED_FILE'), self._seed_file)
예제 #13
0
 def test_append_random_metadata(self):
     cfg = {
         "random_seed": {
             "file": self._seed_file,
             "data": "tiny-tim-was-here",
         }
     }
     c = get_cloud("ubuntu", metadata={"random_seed": "-so-was-josh"})
     cc_seed_random.handle("test", cfg, c, LOG, [])
     contents = util.load_file(self._seed_file)
     self.assertEqual("tiny-tim-was-here-so-was-josh", contents)
예제 #14
0
 def test_handler_write_valid_runcmd_schema_to_file(self):
     """Valid runcmd schema is written to a runcmd shell script."""
     valid_config = {'runcmd': [['ls', '/']]}
     cc = get_cloud(paths=self.paths)
     handle('cc_runcmd', valid_config, cc, LOG, [])
     runcmd_file = os.path.join(
         self.new_root,
         'var/lib/cloud/instances/iid-datasource-none/scripts/runcmd')
     self.assertEqual("#!/bin/sh\n'ls' '/'\n", util.load_file(runcmd_file))
     file_stat = os.stat(runcmd_file)
     self.assertEqual(0o700, stat.S_IMODE(file_stat.st_mode))
예제 #15
0
 def test_append_random_b64(self):
     data = util.b64e("kit-kat")
     cfg = {
         "random_seed": {
             "file": self._seed_file,
             "data": data,
             "encoding": "b64",
         }
     }
     cc_seed_random.handle("test", cfg, get_cloud("ubuntu"), LOG, [])
     contents = util.load_file(self._seed_file)
     self.assertEqual("kit-kat", contents)
예제 #16
0
    def test_empty_trusted_list(self):
        """Test that no certificate are written if 'trusted' list is empty."""
        config = {"ca-certs": {"trusted": []}}

        for distro_name in cc_ca_certs.distros:
            self._mock_init()
            cloud = get_cloud(distro_name)
            cc_ca_certs.handle(self.name, config, cloud, self.log, self.args)

            self.assertEqual(self.mock_add.call_count, 0)
            self.assertEqual(self.mock_update.call_count, 1)
            self.assertEqual(self.mock_remove.call_count, 0)
예제 #17
0
    def test_no_remove_defaults_if_false(self):
        """Test remove_defaults is not called when config value is False."""
        config = {"ca-certs": {"remove-defaults": False}}

        for distro_name in cc_ca_certs.distros:
            self._mock_init()
            cloud = get_cloud(distro_name)
            cc_ca_certs.handle(self.name, config, cloud, self.log, self.args)

            self.assertEqual(self.mock_add.call_count, 0)
            self.assertEqual(self.mock_update.call_count, 1)
            self.assertEqual(self.mock_remove.call_count, 0)
예제 #18
0
    def test_remove_default_ca_certs(self):
        """Test remove_defaults works as expected."""
        config = {"ca-certs": {"remove-defaults": True}}

        for distro_name in cc_ca_certs.distros:
            self._mock_init()
            cloud = get_cloud(distro_name)
            cc_ca_certs.handle(self.name, config, cloud, self.log, self.args)

            self.assertEqual(self.mock_add.call_count, 0)
            self.assertEqual(self.mock_update.call_count, 1)
            self.assertEqual(self.mock_remove.call_count, 1)
예제 #19
0
 def test_append_random_gz(self):
     data = self._compress(b"big-toe")
     cfg = {
         'random_seed': {
             'file': self._seed_file,
             'data': data,
             'encoding': 'gz',
         }
     }
     cc_seed_random.handle('test', cfg, get_cloud('ubuntu'), LOG, [])
     contents = util.load_file(self._seed_file)
     self.assertEqual("big-toe", contents)
예제 #20
0
 def test_append_random_b64(self):
     data = util.b64e('kit-kat')
     cfg = {
         'random_seed': {
             'file': self._seed_file,
             'data': data,
             'encoding': 'b64',
         }
     }
     cc_seed_random.handle('test', cfg, get_cloud('ubuntu'), LOG, [])
     contents = util.load_file(self._seed_file)
     self.assertEqual("kit-kat", contents)
예제 #21
0
 def test_handler_restarts_landscape_client(self, m_subp):
     """handler restarts lansdscape-client after install."""
     mycloud = get_cloud('ubuntu')
     cfg = {'landscape': {'client': {}}}
     wrap_and_call('cloudinit.config.cc_landscape',
                   {'LSC_CLIENT_CFG_FILE': {
                       'new': self.conf
                   }}, cc_landscape.handle, 'notimportant', cfg, mycloud,
                   LOG, None)
     self.assertEqual(
         [mock.call(['service', 'landscape-client', 'restart'])],
         m_subp.subp.call_args_list)
예제 #22
0
 def test_append_random_gzip(self):
     data = self._compress(b"tiny-toe")
     cfg = {
         "random_seed": {
             "file": self._seed_file,
             "data": data,
             "encoding": "gzip",
         }
     }
     cc_seed_random.handle("test", cfg, get_cloud("ubuntu"), LOG, [])
     contents = util.load_file(self._seed_file)
     self.assertEqual("tiny-toe", contents)
예제 #23
0
    def test_single_trusted(self):
        """Test that a single cert gets passed to add_ca_certs."""
        config = {"ca-certs": {"trusted": ["CERT1"]}}

        for distro_name in cc_ca_certs.distros:
            self._mock_init()
            cloud = get_cloud(distro_name)
            conf = cc_ca_certs._distro_ca_certs_configs(distro_name)
            cc_ca_certs.handle(self.name, config, cloud, self.log, self.args)

            self.mock_add.assert_called_once_with(conf, ['CERT1'])
            self.assertEqual(self.mock_update.call_count, 1)
            self.assertEqual(self.mock_remove.call_count, 0)
예제 #24
0
 def test_locale_update_config_if_different_than_default(self):
     """Test cc_locale writes updates conf if different than default"""
     locale_conf = os.path.join(self.new_root, "etc/default/locale")
     util.write_file(locale_conf, 'LANG="en_US.UTF-8"\n')
     cfg = {'locale': 'C.UTF-8'}
     cc = get_cloud('ubuntu')
     with mock.patch('cloudinit.distros.debian.subp.subp') as m_subp:
         with mock.patch('cloudinit.distros.debian.LOCALE_CONF_FN',
                         locale_conf):
             cc_locale.handle('cc_locale', cfg, cc, LOG, [])
             m_subp.assert_called_with(['update-locale',
                                        '--locale-file=%s' % locale_conf,
                                        'LANG=C.UTF-8'], capture=False)
예제 #25
0
    def test_mcollective_install(self, mock_util, mock_subp):
        cc = get_cloud()
        cc.distro = t_help.mock.MagicMock()
        mock_util.load_file.return_value = b""
        mycfg = {'mcollective': {'conf': {'loglevel': 'debug'}}}
        cc_mcollective.handle('cc_mcollective', mycfg, cc, LOG, [])
        self.assertTrue(cc.distro.install_packages.called)
        install_pkg = cc.distro.install_packages.call_args_list[0][0][0]
        self.assertEqual(install_pkg, ('mcollective',))

        self.assertTrue(mock_subp.subp.called)
        self.assertEqual(mock_subp.subp.call_args_list[0][0][0],
                         ['service', 'mcollective', 'restart'])
예제 #26
0
    def test_handler_schema_validation_warns_non_array_type(self):
        """Schema validation warns of non-array type for bootcmd key.

        Schema validation is not strict, so bootcmd attempts to shellify the
        invalid content.
        """
        invalid_config = {'bootcmd': 1}
        cc = get_cloud()
        with self.assertRaises(TypeError):
            handle('cc_bootcmd', invalid_config, cc, LOG, [])
        self.assertIn('Invalid config:\nbootcmd: 1 is not of type \'array\'',
                      self.logs.getvalue())
        self.assertIn('Failed to shellify', self.logs.getvalue())
    def test_apt_v3_source_list_ubuntu_snappy(self):
        """test_apt_v3_source_list_ubuntu_snappy - without custom sources or
        parms"""
        cfg = {'apt': {}}
        mycloud = get_cloud()

        with mock.patch.object(util, 'write_file') as mock_writefile:
            with mock.patch.object(util, 'system_is_snappy',
                                   return_value=True) as mock_issnappy:
                cc_apt_configure.handle("test", cfg, mycloud, LOG, None)

        self.assertEqual(0, mock_writefile.call_count)
        self.assertEqual(1, mock_issnappy.call_count)
예제 #28
0
    def test_correct_order_for_remove_then_add(self):
        """Test remove_defaults is not called when config value is False."""
        config = {"ca-certs": {"remove-defaults": True, "trusted": ["CERT1"]}}

        for distro_name in cc_ca_certs.distros:
            self._mock_init()
            cloud = get_cloud(distro_name)
            conf = cc_ca_certs._distro_ca_certs_configs(distro_name)
            cc_ca_certs.handle(self.name, config, cloud, self.log, self.args)

            self.mock_add.assert_called_once_with(conf, ['CERT1'])
            self.assertEqual(self.mock_update.call_count, 1)
            self.assertEqual(self.mock_remove.call_count, 1)
예제 #29
0
 def test_valid_value_changes_updates_ssh(self, m_subp, mock_uses_systemd):
     """If value is a valid changed value, then update will be called."""
     cloud = get_cloud("ubuntu")
     upname = MODPATH + "update_ssh_config"
     optname = "PasswordAuthentication"
     for n, value in enumerate(util.FALSE_STRINGS + util.TRUE_STRINGS, 1):
         optval = "yes" if value in util.TRUE_STRINGS else "no"
         with mock.patch(upname, return_value=False) as m_update:
             setpass.handle_ssh_pwauth(value, cloud.distro)
             assert (
                 mock.call({optname: optval}) == m_update.call_args_list[-1]
             )
             assert m_subp.call_count == n
예제 #30
0
    def apt_source_list(self, distro, mirror, mirrorcheck=None):
        """apt_source_list
        Test rendering of a source.list from template for a given distro
        """
        if mirrorcheck is None:
            mirrorcheck = mirror

        if isinstance(mirror, list):
            cfg = {"apt_mirror_search": mirror}
        else:
            cfg = {"apt_mirror": mirror}

        mycloud = get_cloud(distro)

        with mock.patch.object(util, "write_file") as mockwf:
            with mock.patch.object(
                util, "load_file", return_value="faketmpl"
            ) as mocklf:
                with mock.patch.object(
                    os.path, "isfile", return_value=True
                ) as mockisfile:
                    with mock.patch.object(
                        templater, "render_string", return_value="fake"
                    ) as mockrnd:
                        with mock.patch.object(util, "rename"):
                            cc_apt_configure.handle(
                                "test", cfg, mycloud, LOG, None
                            )

        mockisfile.assert_any_call(
            "/etc/cloud/templates/sources.list.%s.tmpl" % distro
        )
        mocklf.assert_any_call(
            "/etc/cloud/templates/sources.list.%s.tmpl" % distro
        )
        mockrnd.assert_called_once_with(
            "faketmpl",
            {
                "RELEASE": "fakerelease",
                "PRIMARY": mirrorcheck,
                "MIRROR": mirrorcheck,
                "SECURITY": mirrorcheck,
                "codename": "fakerelease",
                "primary": mirrorcheck,
                "mirror": mirrorcheck,
                "security": mirrorcheck,
            },
        )
        mockwf.assert_called_once_with(
            "/etc/apt/sources.list", "fake", mode=0o644
        )