From b03e1e47c9805332cd83dcc5cf3e68e0b3c8175a Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 13 Sep 2013 15:19:56 -0400 Subject: CfgPublicKeyCreator: properly handle case where only private key has been created Previously, only two cases were handled properly: both public and private keys had been created; or neither had been created. If the private key had been created (e.g., manually added to the repo), the public key would not be created from it. This fixes that. --- .../TestCfg/TestCfgPrivateKeyCreator.py | 19 +--- .../TestPlugins/TestCfg/TestCfgPublicKeyCreator.py | 106 ++++++++++++++++++--- 2 files changed, 93 insertions(+), 32 deletions(-) (limited to 'testsuite/Testsrc') diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py index dc4b11241..e139a592b 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py @@ -31,6 +31,7 @@ class TestCfgPrivateKeyCreator(TestCfgCreator, TestStructFile): should_monitor = False def get_obj(self, name=None, fam=None): + Bcfg2.Server.Plugins.Cfg.CfgPublicKeyCreator.CFG = Mock() return TestCfgCreator.get_obj(self, name=name) @patch("Bcfg2.Server.Plugins.Cfg.CfgCreator.handle_event") @@ -259,24 +260,6 @@ class TestCfgPrivateKeyCreator(TestCfgCreator, TestStructFile): pkc.write_data.assert_called_with("privatekey", group="foo") mock_rmtree.assert_called_with(datastore) - reset() - self.assertEqual(pkc.create_data(entry, metadata, return_pair=True), - ("ssh-rsa publickey pubkey.filename\n", - "privatekey")) - pkc.XMLMatch.assert_called_with(metadata) - pkc.get_specificity.assert_called_with(metadata, - pkc.XMLMatch.return_value) - pkc._gen_keypair.assert_called_with(metadata, - pkc.XMLMatch.return_value) - self.assertItemsEqual(mock_open.call_args_list, - [call(privkey + ".pub"), call(privkey)]) - pkc.pubkey_creator.get_filename.assert_called_with(group="foo") - pkc.pubkey_creator.write_data.assert_called_with( - "ssh-rsa publickey pubkey.filename\n", - group="foo") - pkc.write_data.assert_called_with("privatekey", group="foo") - mock_rmtree.assert_called_with(datastore) - inner() if HAS_CRYPTO: diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py index 04772cf9a..ed529253b 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py @@ -26,6 +26,7 @@ class TestCfgPublicKeyCreator(TestCfgCreator, TestStructFile): should_monitor = False def get_obj(self, name=None, fam=None): + Bcfg2.Server.Plugins.Cfg.CfgPublicKeyCreator.CFG = Mock() return TestCfgCreator.get_obj(self, name=name) @patch("Bcfg2.Server.Plugins.Cfg.CfgCreator.handle_event") @@ -37,41 +38,118 @@ class TestCfgPublicKeyCreator(TestCfgCreator, TestStructFile): mock_HandleEvent.assert_called_with(pkc, evt) mock_handle_event.assert_called_with(pkc, evt) - def test_create_data(self): + @patch("os.unlink") + @patch("os.path.exists") + @patch("tempfile.mkstemp") + @patch("os.fdopen", Mock()) + @patch("%s.open" % builtins) + def test_create_data(self, mock_open, mock_mkstemp, mock_exists, + mock_unlink): metadata = Mock() pkc = self.get_obj() pkc.cfg = Mock() + pkc.core = Mock() + pkc.cmd = Mock() + pkc.get_filename = Mock() + pkc.write_data = Mock() + pubkey = "public key data" privkey_entryset = Mock() privkey_creator = Mock() - pubkey = Mock() - privkey = Mock() - privkey_creator.create_data.return_value = (pubkey, privkey) - privkey_entryset.best_matching.return_value = privkey_creator + privkey_creator.get_specificity = Mock() + privkey_creator.get_specificity.return_value = MagicMock() pkc.cfg.entries = {"/home/foo/.ssh/id_rsa": privkey_entryset} + def reset(): + privkey_creator.reset_mock() + pkc.cmd.reset_mock() + pkc.core.reset_mock() + pkc.get_filename.reset_mock() + pkc.write_data.reset_mock() + mock_exists.reset_mock() + mock_unlink.reset_mock() + mock_mkstemp.reset_mock() + mock_open.reset_mock() + # public key doesn't end in .pub entry = lxml.etree.Element("Path", name="/home/bar/.ssh/bogus") self.assertRaises(CfgCreationError, pkc.create_data, entry, metadata) + self.assertFalse(pkc.write_data.called) + + # cannot bind private key + reset() + pkc.core.Bind.side_effect = PluginExecutionError + entry = lxml.etree.Element("Path", name="/home/foo/.ssh/id_rsa.pub") + self.assertRaises(CfgCreationError, + pkc.create_data, entry, metadata) + self.assertFalse(pkc.write_data.called) # private key not in cfg.entries + reset() + pkc.core.Bind.side_effect = None + pkc.core.Bind.return_value = "private key data" entry = lxml.etree.Element("Path", name="/home/bar/.ssh/id_rsa.pub") self.assertRaises(CfgCreationError, pkc.create_data, entry, metadata) + self.assertFalse(pkc.write_data.called) - # successful operation + # no privkey.xml defined + reset() + privkey_entryset.best_matching.side_effect = PluginExecutionError + entry = lxml.etree.Element("Path", name="/home/foo/.ssh/id_rsa.pub") + self.assertRaises(CfgCreationError, + pkc.create_data, entry, metadata) + self.assertFalse(pkc.write_data.called) + + # successful operation, create new key + reset() + pkc.cmd.run.return_value = Mock() + pkc.cmd.run.return_value.success = True + pkc.cmd.run.return_value.stdout = pubkey + mock_mkstemp.return_value = (Mock(), str(Mock())) + mock_exists.return_value = False + privkey_entryset.best_matching.side_effect = None + privkey_entryset.best_matching.return_value = privkey_creator entry = lxml.etree.Element("Path", name="/home/foo/.ssh/id_rsa.pub") self.assertEqual(pkc.create_data(entry, metadata), pubkey) + self.assertTrue(pkc.core.Bind.called) + (privkey_entry, md) = pkc.core.Bind.call_args[0] + self.assertXMLEqual(privkey_entry, + lxml.etree.Element("Path", + name="/home/foo/.ssh/id_rsa")) + self.assertEqual(md, metadata) + privkey_entryset.get_handlers.assert_called_with(metadata, CfgCreator) - privkey_entryset.best_matching.assert_called_with(metadata, - privkey_entryset.get_handlers.return_value) - self.assertXMLEqual(privkey_creator.create_data.call_args[0][0], + privkey_entryset.best_matching.assert_called_with( + metadata, + privkey_entryset.get_handlers.return_value) + mock_exists.assert_called_with(pkc.get_filename.return_value) + pkc.cmd.run.assert_called_with(["ssh-keygen", "-y", "-f", + mock_mkstemp.return_value[1]]) + self.assertEqual(pkc.write_data.call_args[0][0], pubkey) + mock_unlink.assert_called_with(mock_mkstemp.return_value[1]) + self.assertFalse(mock_open.called) + + # successful operation, no need to create new key + reset() + mock_exists.return_value = True + mock_open.return_value = Mock() + mock_open.return_value.read.return_value = pubkey + pkc.cmd.run.return_value.stdout = None + self.assertEqual(pkc.create_data(entry, metadata), pubkey) + self.assertTrue(pkc.core.Bind.called) + (privkey_entry, md) = pkc.core.Bind.call_args[0] + self.assertXMLEqual(privkey_entry, lxml.etree.Element("Path", name="/home/foo/.ssh/id_rsa")) - self.assertEqual(privkey_creator.create_data.call_args[0][1], metadata) + self.assertEqual(md, metadata) - # no privkey.xml - privkey_entryset.best_matching.side_effect = PluginExecutionError - self.assertRaises(CfgCreationError, - pkc.create_data, entry, metadata) + privkey_entryset.get_handlers.assert_called_with(metadata, CfgCreator) + privkey_entryset.best_matching.assert_called_with( + metadata, + privkey_entryset.get_handlers.return_value) + mock_exists.assert_called_with(pkc.get_filename.return_value) + mock_open.assert_called_with(pkc.get_filename.return_value) + self.assertFalse(mock_mkstemp.called) + self.assertFalse(pkc.write_data.called) -- cgit v1.2.3-1-g7c22