From a55474c7f8787cf192c63d63aafca10c0ef84f48 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Thu, 28 Jan 2010 18:22:03 +0100
Subject: [PATCH] Move function generating SSL certs into utils

Also add unittest.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
---
 lib/bootstrap.py              | 39 ++---------------------------------
 lib/utils.py                  | 34 ++++++++++++++++++++++++++++++
 test/ganeti.utils_unittest.py | 28 +++++++++++++++++++++++++
 tools/cfgupgrade              |  2 +-
 4 files changed, 65 insertions(+), 38 deletions(-)

diff --git a/lib/bootstrap.py b/lib/bootstrap.py
index a162897e4..1d462a39b 100644
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@ -27,7 +27,6 @@ import os
 import os.path
 import re
 import logging
-import tempfile
 import time
 
 from ganeti import rpc
@@ -66,40 +65,6 @@ def _InitSSHSetup():
   utils.AddAuthorizedKey(auth_keys, utils.ReadFile(pub_key))
 
 
-def GenerateSelfSignedSslCert(file_name, validity=(365 * 5)):
-  """Generates a self-signed SSL certificate.
-
-  @type file_name: str
-  @param file_name: Path to output file
-  @type validity: int
-  @param validity: Validity for certificate in days
-
-  """
-  (fd, tmp_file_name) = tempfile.mkstemp(dir=os.path.dirname(file_name))
-  try:
-    try:
-      # Set permissions before writing key
-      os.chmod(tmp_file_name, 0600)
-
-      result = utils.RunCmd(["openssl", "req", "-new", "-newkey", "rsa:1024",
-                             "-days", str(validity), "-nodes", "-x509",
-                             "-keyout", tmp_file_name, "-out", tmp_file_name,
-                             "-batch"])
-      if result.failed:
-        raise errors.OpExecError("Could not generate SSL certificate, command"
-                                 " %s had exitcode %s and error message %s" %
-                                 (result.cmd, result.exit_code, result.output))
-
-      # Make read-only
-      os.chmod(tmp_file_name, 0400)
-
-      os.rename(tmp_file_name, file_name)
-    finally:
-      utils.RemoveFile(tmp_file_name)
-  finally:
-    os.close(fd)
-
-
 def GenerateHmacKey(file_name):
   """Writes a new HMAC key.
 
@@ -117,11 +82,11 @@ def _InitGanetiServerSetup(master_name):
   the cluster and also generates the SSL certificate.
 
   """
-  GenerateSelfSignedSslCert(constants.SSL_CERT_FILE)
+  utils.GenerateSelfSignedSslCert(constants.SSL_CERT_FILE)
 
   # Don't overwrite existing file
   if not os.path.exists(constants.RAPI_CERT_FILE):
-    GenerateSelfSignedSslCert(constants.RAPI_CERT_FILE)
+    utils.GenerateSelfSignedSslCert(constants.RAPI_CERT_FILE)
 
   if not os.path.exists(constants.HMAC_CLUSTER_KEY):
     GenerateHmacKey(constants.HMAC_CLUSTER_KEY)
diff --git a/lib/utils.py b/lib/utils.py
index 438a12035..1a4011ee1 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -2258,6 +2258,40 @@ def Retry(fn, delay, timeout, args=None, wait_fn=time.sleep,
         wait_fn(current_delay)
 
 
+def GenerateSelfSignedSslCert(file_name, validity=(365 * 5)):
+  """Generates a self-signed SSL certificate.
+
+  @type file_name: str
+  @param file_name: Path to output file
+  @type validity: int
+  @param validity: Validity for certificate in days
+
+  """
+  (fd, tmp_file_name) = tempfile.mkstemp(dir=os.path.dirname(file_name))
+  try:
+    try:
+      # Set permissions before writing key
+      os.chmod(tmp_file_name, 0600)
+
+      result = RunCmd(["openssl", "req", "-new", "-newkey", "rsa:1024",
+                       "-days", str(validity), "-nodes", "-x509",
+                       "-keyout", tmp_file_name, "-out", tmp_file_name,
+                       "-batch"])
+      if result.failed:
+        raise errors.OpExecError("Could not generate SSL certificate, command"
+                                 " %s had exitcode %s and error message %s" %
+                                 (result.cmd, result.exit_code, result.output))
+
+      # Make read-only
+      os.chmod(tmp_file_name, 0400)
+
+      os.rename(tmp_file_name, file_name)
+    finally:
+      RemoveFile(tmp_file_name)
+  finally:
+    os.close(fd)
+
+
 class FileLock(object):
   """Utility class for file locks.
 
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index f0763550d..15ff1362e 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -1085,5 +1085,33 @@ class TestUnescapeAndSplit(unittest.TestCase):
       self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
 
 
+class TestGenerateSelfSignedSslCert(unittest.TestCase):
+  def setUp(self):
+    self.tmpdir = tempfile.mkdtemp()
+
+  def tearDown(self):
+    shutil.rmtree(self.tmpdir)
+
+  def _checkPrivateRsaKey(self, key):
+    lines = key.splitlines()
+    self.assert_("-----BEGIN RSA PRIVATE KEY-----" in lines)
+    self.assert_("-----END RSA PRIVATE KEY-----" in lines)
+
+  def _checkRsaCertificate(self, cert):
+    lines = cert.splitlines()
+    self.assert_("-----BEGIN CERTIFICATE-----" in lines)
+    self.assert_("-----END CERTIFICATE-----" in lines)
+
+  def testSingleFile(self):
+    cert1_filename = os.path.join(self.tmpdir, "cert1.pem")
+
+    utils.GenerateSelfSignedSslCert(cert1_filename, validity=1)
+
+    cert1 = utils.ReadFile(cert1_filename)
+
+    self._checkPrivateRsaKey(cert1)
+    self._checkRsaCertificate(cert1)
+
+
 if __name__ == '__main__':
   testutils.GanetiTestProgram()
diff --git a/tools/cfgupgrade b/tools/cfgupgrade
index e7be5911e..38e577c8d 100755
--- a/tools/cfgupgrade
+++ b/tools/cfgupgrade
@@ -176,7 +176,7 @@ def main():
     if not options.dry_run:
       if not os.path.exists(options.RAPI_CERT_FILE):
         logging.debug("Writing RAPI certificate to %s", options.RAPI_CERT_FILE)
-        bootstrap.GenerateSelfSignedSslCert(options.RAPI_CERT_FILE)
+        utils.GenerateSelfSignedSslCert(options.RAPI_CERT_FILE)
 
       if not os.path.exists(options.HMAC_CLUSTER_KEY):
         logging.debug("Writing HMAC key to %s", options.HMAC_CLUSTER_KEY)
-- 
GitLab