On Thu, Mar 05, 2015 at 11:11:00PM +0100, 'Helga Velroyen' via ganeti-devel
wrote:
When the recreation of the master's SSL client certificate
fails, LURenewCrypto did not conclude very graciously.
This patch adds unit tests for this case and improves
the error handling.
Signed-off-by: Helga Velroyen <[email protected]>
---
lib/cmdlib/cluster.py | 29 ++++++++++++++++++++++-------
test/py/cmdlib/cluster_unittest.py | 26 ++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/lib/cmdlib/cluster.py b/lib/cmdlib/cluster.py
index 7959ff0..3762489 100644
--- a/lib/cmdlib/cluster.py
+++ b/lib/cmdlib/cluster.py
@@ -129,13 +129,28 @@ class LUClusterRenewCrypto(NoHooksLU):
except IOError:
logging.info("No old certificate available.")
- # Technically it should not be necessary to set the cert
- # paths. However, due to a bug in the mock library, we
- # have to do this to be able to test the function properly.
- _UpdateMasterClientCert(
- self, master_uuid, cluster, feedback_fn,
- client_cert=pathutils.NODED_CLIENT_CERT_FILE,
- client_cert_tmp=pathutils.NODED_CLIENT_CERT_FILE_TMP)
+ try:
+ # Technically it should not be necessary to set the cert
+ # paths. However, due to a bug in the mock library, we
+ # have to do this to be able to test the function properly.
+ _UpdateMasterClientCert(
+ self, master_uuid, cluster, feedback_fn,
+ client_cert=pathutils.NODED_CLIENT_CERT_FILE,
+ client_cert_tmp=pathutils.NODED_CLIENT_CERT_FILE_TMP)
+ except errors.OpExecError as e:
+ feedback_fn("Could not renew the master's client SSL certificate."
+ " Cleaning up. Error: %s." % e)
+ # Cleaning up temporary certificates
+ utils.RemoveNodeFromCandidateCerts("%s-SERVER" % master_uuid,
+ cluster.candidate_certs)
+ utils.RemoveNodeFromCandidateCerts("%s-OLDMASTER" % master_uuid,
+ cluster.candidate_certs)
+ return
+ finally:
+ try:
+ utils.RemoveFile(pathutils.NODED_CLIENT_CERT_FILE_TMP)
+ except IOError:
+ pass
nodes = self.cfg.GetAllNodesInfo()
for (node_uuid, node_info) in nodes.items():
diff --git a/test/py/cmdlib/cluster_unittest.py
b/test/py/cmdlib/cluster_unittest.py
index e3ea305..87fd9c7 100644
--- a/test/py/cmdlib/cluster_unittest.py
+++ b/test/py/cmdlib/cluster_unittest.py
@@ -2325,6 +2325,32 @@ class TestLUClusterRenewCrypto(CmdlibTestCase):
expected_digest = self._GetFakeDigest(node_uuid)
self.assertEqual(expected_digest, cluster.candidate_certs[node_uuid])
+ @patchPathutils("cluster")
+ def testMasterFails(self, pathutils):
+
+ # patch pathutils to point to temporary files
+ pathutils.NODED_CERT_FILE = self._node_cert
+ pathutils.NODED_CLIENT_CERT_FILE = self._client_node_cert
+ pathutils.NODED_CLIENT_CERT_FILE_TMP = \
+ self._client_node_cert_tmp
+
+ # make sure the RPC calls are successful for all nodes
shouldn't that be 'failing' instead of 'successful'?
+ master_uuid = self.cfg.GetMasterNode()
+ self.rpc.call_node_crypto_tokens.return_value = self.RpcResultsBuilder() \
+ .CreateFailedNodeResult(master_uuid)
+
+ op = opcodes.OpClusterRenewCrypto()
+ self.ExecOpCode(op)
+
+ # Check if the correct certificates exist and don't exist on the master
+ self.assertTrue(os.path.exists(pathutils.NODED_CERT_FILE))
+ self.assertTrue(os.path.exists(pathutils.NODED_CLIENT_CERT_FILE))
+ self.assertFalse(os.path.exists(pathutils.NODED_CLIENT_CERT_FILE_TMP))
+
+ # Check if we correctly have no candidate certificates
+ cluster = self.cfg.GetClusterInfo()
+ self.assertFalse(cluster.candidate_certs)
+
if __name__ == "__main__":
testutils.GanetiTestProgram()
--
2.2.0.rc0.207.ga3a616c
Rest LGTM