コード例 #1
0
ファイル: test_cc_ssh.py プロジェクト: rongz609/cloud-init
 def test_handle_invalid_ssh_keys_are_skipped(
     self,
     m_write_file,
     m_nug,
     m_setup_keys,
     key_type,
     reason,
     caplog,
 ):
     cfg = {
         "ssh_keys": {
             f"{key_type}_private": f"{key_type}_private",
             f"{key_type}_public": f"{key_type}_public",
             f"{key_type}_certificate": f"{key_type}_certificate",
         },
         "ssh_deletekeys": False,
         "ssh_publish_hostkeys": {
             "enabled": False
         },
     }
     # 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("ubuntu"), LOG, None)
     assert [] == m_write_file.call_args_list
     expected_log_msgs = [
         f'Skipping {reason} ssh_keys entry: "{key_type}_private"',
         f'Skipping {reason} ssh_keys entry: "{key_type}_public"',
         f'Skipping {reason} ssh_keys entry: "{key_type}_certificate"',
     ]
     for expected_log_msg in expected_log_msgs:
         assert caplog.text.count(expected_log_msg) == 1
コード例 #2
0
ファイル: test_cc_ssh.py プロジェクト: rongz609/cloud-init
    def test_handle_default_root(
        self,
        m_path_exists,
        m_nug,
        m_glob,
        m_setup_keys,
        cfg,
        mock_get_public_ssh_keys,
        empty_opts,
    ):
        """Test handle with a default distro user."""
        keys = ["key1"]
        user = "******"
        m_glob.return_value = []  # Return no matching keys to prevent removal
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = get_cloud(distro="ubuntu", metadata={"public-keys": keys})
        if mock_get_public_ssh_keys:
            cloud.get_public_ssh_keys = mock.Mock(return_value=keys)
        cc_ssh.handle("name", cfg, cloud, LOG, None)

        if empty_opts:
            options = ""
        else:
            options = _replace_options(user)
        assert [
            mock.call(set(keys), user),
            mock.call(set(keys), "root", options=options),
        ] == m_setup_keys.call_args_list
コード例 #3
0
ファイル: test_cc_ssh.py プロジェクト: anhvoms/cloud-init
    def test_handle_publish_hostkeys_empty_blacklist(
        self, m_path_exists, m_nug, m_glob, m_setup_keys
    ):
        """Test handle with various configs for ssh_publish_hostkeys."""
        self._publish_hostkey_test_setup()
        cc_ssh.PUBLISH_HOST_KEYS = True
        keys = ["key1"]
        user = "******"
        # Return no matching keys for first glob, test keys for second.
        m_glob.side_effect = iter(
            [
                [],
                self.test_hostkey_files,
            ]
        )
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = self.tmp_cloud(distro="ubuntu", metadata={"public-keys": keys})
        cloud.datasource.publish_host_keys = mock.Mock()

        cfg = {"ssh_publish_hostkeys": {"enabled": True, "blacklist": []}}
        expected_call = [
            self.test_hostkeys[key_type]
            for key_type in cc_ssh.GENERATE_KEY_NAMES
        ]
        cc_ssh.handle("name", cfg, cloud, LOG, None)
        self.assertEqual(
            [mock.call(expected_call)],
            cloud.datasource.publish_host_keys.call_args_list,
        )
コード例 #4
0
ファイル: test_cc_ssh.py プロジェクト: anhvoms/cloud-init
    def test_handle_cfg_with_explicit_disable_root(
        self, m_path_exists, m_nug, m_glob, m_setup_keys
    ):
        """Test handle with explicit disable_root and a default distro user."""
        # This test is identical to test_handle_no_cfg_and_default_root,
        # except this uses an explicit cfg value
        cfg = {"disable_root": True}
        keys = ["key1"]
        user = "******"
        m_glob.return_value = []  # Return no matching keys to prevent removal
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = self.tmp_cloud(distro="ubuntu", metadata={"public-keys": keys})
        cc_ssh.handle("name", cfg, cloud, LOG, None)

        options = ssh_util.DISABLE_USER_OPTS.replace("$USER", user)
        options = options.replace("$DISABLE_USER", "root")
        self.assertEqual(
            [
                mock.call(set(keys), user),
                mock.call(set(keys), "root", options=options),
            ],
            m_setup_keys.call_args_list,
        )
コード例 #5
0
ファイル: test_cc_ssh.py プロジェクト: anhvoms/cloud-init
    def test_handle_publish_hostkeys_config_disable(
        self, m_path_exists, m_nug, m_glob, m_setup_keys
    ):
        """Test handle with various configs for ssh_publish_hostkeys."""
        self._publish_hostkey_test_setup()
        cc_ssh.PUBLISH_HOST_KEYS = True
        keys = ["key1"]
        user = "******"
        # Return no matching keys for first glob, test keys for second.
        m_glob.side_effect = iter(
            [
                [],
                self.test_hostkey_files,
            ]
        )
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = self.tmp_cloud(distro="ubuntu", metadata={"public-keys": keys})
        cloud.datasource.publish_host_keys = mock.Mock()

        cfg = {"ssh_publish_hostkeys": {"enabled": False}}
        cc_ssh.handle("name", cfg, cloud, LOG, None)
        self.assertFalse(cloud.datasource.publish_host_keys.call_args_list)
        cloud.datasource.publish_host_keys.assert_not_called()
コード例 #6
0
ファイル: test_cc_ssh.py プロジェクト: anhvoms/cloud-init
    def test_dont_allow_public_ssh_keys(
        self, m_path_exists, m_nug, m_glob, m_setup_keys
    ):
        """Test allow_public_ssh_keys=False ignores ssh public keys from
        platform.
        """
        cfg = {"allow_public_ssh_keys": False}
        keys = ["key1"]
        user = "******"
        m_glob.return_value = []  # Return no matching keys to prevent removal
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = self.tmp_cloud(distro="ubuntu", metadata={"public-keys": keys})
        cc_ssh.handle("name", cfg, cloud, LOG, None)

        options = ssh_util.DISABLE_USER_OPTS.replace("$USER", user)
        options = options.replace("$DISABLE_USER", "root")
        self.assertEqual(
            [
                mock.call(set(), user),
                mock.call(set(), "root", options=options),
            ],
            m_setup_keys.call_args_list,
        )
コード例 #7
0
ファイル: test_cc_ssh.py プロジェクト: anhvoms/cloud-init
 def test_handle_no_cfg(self, m_path_exists, m_nug, m_glob, m_setup_keys):
     """Test handle with no config ignores generating existing keyfiles."""
     cfg = {}
     keys = ["key1"]
     m_glob.return_value = []  # Return no matching keys to prevent removal
     # Mock os.path.exits to True to short-circuit the key writing logic
     m_path_exists.return_value = True
     m_nug.return_value = ([], {})
     cc_ssh.PUBLISH_HOST_KEYS = False
     cloud = self.tmp_cloud(distro="ubuntu", metadata={"public-keys": keys})
     cc_ssh.handle("name", cfg, cloud, LOG, None)
     options = ssh_util.DISABLE_USER_OPTS.replace("$USER", "NONE")
     options = options.replace("$DISABLE_USER", "root")
     m_glob.assert_called_once_with("/etc/ssh/ssh_host_*key*")
     self.assertIn(
         [
             mock.call("/etc/ssh/ssh_host_rsa_key"),
             mock.call("/etc/ssh/ssh_host_dsa_key"),
             mock.call("/etc/ssh/ssh_host_ecdsa_key"),
             mock.call("/etc/ssh/ssh_host_ed25519_key"),
         ],
         m_path_exists.call_args_list,
     )
     self.assertEqual(
         [mock.call(set(keys), "root", options=options)],
         m_setup_keys.call_args_list,
     )
コード例 #8
0
ファイル: test_ssh.py プロジェクト: bsmr/canonical-cloud-init
    def test_handle_publish_hostkeys_config_enable(self, m_path_exists, m_nug,
                                                   m_glob, m_setup_keys):
        """Test handle with various configs for ssh_publish_hostkeys."""
        self._publish_hostkey_test_setup()
        cc_ssh.PUBLISH_HOST_KEYS = False
        keys = ["key1"]
        user = "******"
        # Return no matching keys for first glob, test keys for second.
        m_glob.side_effect = iter([
            [],
            self.test_hostkey_files,
        ])
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = self.tmp_cloud(distro='ubuntu', metadata={'public-keys': keys})
        cloud.datasource.publish_host_keys = mock.Mock()

        cfg = {'ssh_publish_hostkeys': {'enabled': True}}
        expected_call = [
            self.test_hostkeys[key_type]
            for key_type in ['ecdsa', 'ed25519', 'rsa']
        ]
        cc_ssh.handle("name", cfg, cloud, LOG, None)
        self.assertEqual([mock.call(expected_call)],
                         cloud.datasource.publish_host_keys.call_args_list)
コード例 #9
0
ファイル: test_cc_ssh.py プロジェクト: anhvoms/cloud-init
    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, self.tmp_cloud(distro="ubuntu"), LOG, None
            )

        # Check that all expected output has been done.
        for call_ in expected_calls:
            self.assertIn(call_, m_write_file.call_args_list)
コード例 #10
0
ファイル: test_ssh.py プロジェクト: bsmr/canonical-cloud-init
    def test_handle_cfg_without_disable_root(self, m_path_exists, m_nug,
                                             m_glob, m_setup_keys):
        """Test handle with disable_root == False."""
        # When disable_root == False, the ssh redirect for root is skipped
        cfg = {"disable_root": False}
        keys = ["key1"]
        user = "******"
        m_glob.return_value = []  # Return no matching keys to prevent removal
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = self.tmp_cloud(distro='ubuntu', metadata={'public-keys': keys})
        cloud.get_public_ssh_keys = mock.Mock(return_value=keys)
        cc_ssh.handle("name", cfg, cloud, LOG, None)

        self.assertEqual([
            mock.call(set(keys), user),
            mock.call(set(keys), "root", options="")
        ], m_setup_keys.call_args_list)
コード例 #11
0
ファイル: test_ssh.py プロジェクト: bsmr/canonical-cloud-init
    def test_handle_no_cfg_and_default_root(self, m_path_exists, m_nug, m_glob,
                                            m_setup_keys):
        """Test handle with no config and a default distro user."""
        cfg = {}
        keys = ["key1"]
        user = "******"
        m_glob.return_value = []  # Return no matching keys to prevent removal
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = self.tmp_cloud(distro='ubuntu', metadata={'public-keys': keys})
        cc_ssh.handle("name", cfg, cloud, LOG, None)

        options = ssh_util.DISABLE_USER_OPTS.replace("$USER", user)
        options = options.replace("$DISABLE_USER", "root")
        self.assertEqual([
            mock.call(set(keys), user),
            mock.call(set(keys), "root", options=options)
        ], m_setup_keys.call_args_list)
コード例 #12
0
ファイル: test_cc_ssh.py プロジェクト: rongz609/cloud-init
    def test_handle_publish_hostkeys(
        self,
        m_path_exists,
        m_nug,
        m_glob,
        m_setup_keys,
        publish_hostkey_test_setup,
        cfg,
        expected_key_types,
    ):
        """Test handle with various configs for ssh_publish_hostkeys."""
        test_hostkeys, test_hostkey_files = publish_hostkey_test_setup
        cc_ssh.PUBLISH_HOST_KEYS = True
        keys = ["key1"]
        user = "******"
        # Return no matching keys for first glob, test keys for second.
        m_glob.side_effect = iter([
            [],
            test_hostkey_files,
        ])
        # Mock os.path.exits to True to short-circuit the key writing logic
        m_path_exists.return_value = True
        m_nug.return_value = ({user: {"default": user}}, {})
        cloud = get_cloud(distro="ubuntu", metadata={"public-keys": keys})
        cloud.datasource.publish_host_keys = mock.Mock()

        expected_calls = []
        if expected_key_types is not None:
            expected_calls = [
                mock.call([
                    test_hostkeys[key_type] for key_type in expected_key_types
                ])
            ]
        cc_ssh.handle("name", cfg, cloud, LOG, None)
        assert (expected_calls ==
                cloud.datasource.publish_host_keys.call_args_list)