So far the generation of client certificates was only
called from ssl_update.py used in when calling 'gnt-cluster
renew-crypto'. This patch moves the function from
ssl_update.py to tools/common.py, because it will also
be needed by prepare_node_join.py when adding nodes
(see next patch in the series).

Signed-off-by: Helga Velroyen <[email protected]>
---
 lib/tools/common.py                         | 30 +++++++++++
 lib/tools/ssl_update.py                     | 31 +----------
 test/py/ganeti.tools.common_unittest.py     | 82 ++++++++++++++++++++++++++++
 test/py/ganeti.tools.ssl_update_unittest.py | 84 -----------------------------
 4 files changed, 113 insertions(+), 114 deletions(-)
 create mode 100755 test/py/ganeti.tools.common_unittest.py
 delete mode 100755 test/py/ganeti.tools.ssl_update_unittest.py

diff --git a/lib/tools/common.py b/lib/tools/common.py
index 2b39308..547c072 100644
--- a/lib/tools/common.py
+++ b/lib/tools/common.py
@@ -33,9 +33,12 @@
 
 import logging
 import OpenSSL
+import os
+import time
 from cStringIO import StringIO
 
 from ganeti import constants
+from ganeti import pathutils
 from ganeti import utils
 from ganeti import serializer
 from ganeti import ssconf
@@ -138,3 +141,30 @@ def LoadData(raw, data_check):
 
   """
   return serializer.LoadAndVerifyJson(raw, data_check)
+
+
+def GenerateClientCertificate(
+    data, error_fn, client_cert=pathutils.NODED_CLIENT_CERT_FILE,
+    signing_cert=pathutils.NODED_CERT_FILE):
+  """Regenerates the client certificate of the node.
+
+  @type data: string
+  @param data: the JSON-formated input data
+
+  """
+  if not os.path.exists(signing_cert):
+    raise error_fn("The signing certificate '%s' cannot be found."
+                   % signing_cert)
+
+  # TODO: This sets the serial number to the number of seconds
+  # since epoch. This is technically not a correct serial number
+  # (in the way SSL is supposed to be used), but it serves us well
+  # enough for now, as we don't have any infrastructure for keeping
+  # track of the number of signed certificates yet.
+  serial_no = int(time.time())
+
+  # The hostname of the node is provided with the input data.
+  hostname = data.get(constants.NDS_NODE_NAME)
+
+  utils.GenerateSignedSslCert(client_cert, serial_no, signing_cert,
+                              common_name=hostname)
diff --git a/lib/tools/ssl_update.py b/lib/tools/ssl_update.py
index 3764e2d..4d17d9d 100644
--- a/lib/tools/ssl_update.py
+++ b/lib/tools/ssl_update.py
@@ -36,14 +36,12 @@ import os.path
 import optparse
 import sys
 import logging
-import time
 
 from ganeti import cli
 from ganeti import constants
 from ganeti import errors
 from ganeti import utils
 from ganeti import ht
-from ganeti import pathutils
 from ganeti.tools import common
 
 
@@ -77,33 +75,6 @@ def ParseOptions():
   return common.VerifyOptions(parser, opts, args)
 
 
-def RegenerateClientCertificate(
-    data, client_cert=pathutils.NODED_CLIENT_CERT_FILE,
-    signing_cert=pathutils.NODED_CERT_FILE):
-  """Regenerates the client certificate of the node.
-
-  @type data: string
-  @param data: the JSON-formated input data
-
-  """
-  if not os.path.exists(signing_cert):
-    raise SslSetupError("The signing certificate '%s' cannot be found."
-                        % signing_cert)
-
-  # TODO: This sets the serial number to the number of seconds
-  # since epoch. This is technically not a correct serial number
-  # (in the way SSL is supposed to be used), but it serves us well
-  # enough for now, as we don't have any infrastructure for keeping
-  # track of the number of signed certificates yet.
-  serial_no = int(time.time())
-
-  # The hostname of the node is provided with the input data.
-  hostname = data.get(constants.NDS_NODE_NAME)
-
-  utils.GenerateSignedSslCert(client_cert, serial_no, signing_cert,
-                              common_name=hostname)
-
-
 def Main():
   """Main routine.
 
@@ -121,7 +92,7 @@ def Main():
     # is the same as on this node.
     common.VerifyCertificate(data, SslSetupError)
 
-    RegenerateClientCertificate(data)
+    common.GenerateClientCertificate(data, SslSetupError)
 
   except Exception, err: # pylint: disable=W0703
     logging.debug("Caught unhandled exception", exc_info=True)
diff --git a/test/py/ganeti.tools.common_unittest.py 
b/test/py/ganeti.tools.common_unittest.py
new file mode 100755
index 0000000..1652088
--- /dev/null
+++ b/test/py/ganeti.tools.common_unittest.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+#
+
+# Copyright (C) 2015 Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+"""Script for testing ganeti.tools.ssl_update"""
+
+import unittest
+import shutil
+import tempfile
+import os.path
+import OpenSSL
+import time
+
+from ganeti import constants
+from ganeti import utils
+from ganeti.tools import common
+
+import testutils
+
+
+class TestGenerateClientCert(unittest.TestCase):
+
+  def setUp(self):
+    self.tmpdir = tempfile.mkdtemp()
+
+    self.client_cert = os.path.join(self.tmpdir, "client.pem")
+
+    self.server_cert = os.path.join(self.tmpdir, "server.pem")
+    some_serial_no = int(time.time())
+    utils.GenerateSelfSignedSslCert(self.server_cert, some_serial_no)
+
+  def tearDown(self):
+    shutil.rmtree(self.tmpdir)
+
+  def testRegnerateClientCertificate(self):
+    my_node_name = "mynode.example.com"
+    data = {constants.NDS_CLUSTER_NAME: "winnie_poohs_cluster",
+            constants.NDS_NODE_DAEMON_CERTIFICATE: "some_cert",
+            constants.NDS_NODE_NAME: my_node_name}
+
+    common.GenerateClientCertificate(data, Exception,
+                                     client_cert=self.client_cert,
+                                     signing_cert=self.server_cert)
+
+    client_cert_pem = utils.ReadFile(self.client_cert)
+    server_cert_pem = utils.ReadFile(self.server_cert)
+    client_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
+                                                  client_cert_pem)
+    signing_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
+                                                   server_cert_pem)
+    self.assertEqual(client_cert.get_issuer().CN, 
signing_cert.get_subject().CN)
+    self.assertEqual(client_cert.get_subject().CN, my_node_name)
+
+
+if __name__ == "__main__":
+  testutils.GanetiTestProgram()
diff --git a/test/py/ganeti.tools.ssl_update_unittest.py 
b/test/py/ganeti.tools.ssl_update_unittest.py
deleted file mode 100755
index e4b3ad9..0000000
--- a/test/py/ganeti.tools.ssl_update_unittest.py
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/python
-#
-
-# Copyright (C) 2015 Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# 1. Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-"""Script for testing ganeti.tools.ssl_update"""
-
-import unittest
-import shutil
-import tempfile
-import os.path
-import OpenSSL
-import time
-
-from ganeti import errors
-from ganeti import constants
-from ganeti import serializer
-from ganeti import pathutils
-from ganeti import compat
-from ganeti import utils
-from ganeti.tools import ssl_update
-
-import testutils
-
-
-class TestGenerateClientCert(unittest.TestCase):
-  def setUp(self):
-    self.tmpdir = tempfile.mkdtemp()
-
-    self.client_cert = os.path.join(self.tmpdir, "client.pem")
-
-    self.server_cert = os.path.join(self.tmpdir, "server.pem")
-    some_serial_no = int(time.time())
-    utils.GenerateSelfSignedSslCert(self.server_cert, some_serial_no)
-
-  def tearDown(self):
-    shutil.rmtree(self.tmpdir)
-
-  def testRegnerateClientCertificate(self):
-    my_node_name = "mynode.example.com"
-    data = {constants.NDS_CLUSTER_NAME: "winnie_poohs_cluster",
-            constants.NDS_NODE_DAEMON_CERTIFICATE: "some_cert",
-            constants.NDS_NODE_NAME: my_node_name}
-
-    ssl_update.RegenerateClientCertificate(data, client_cert=self.client_cert,
-                                           signing_cert=self.server_cert)
-
-    client_cert_pem = utils.ReadFile(self.client_cert)
-    server_cert_pem = utils.ReadFile(self.server_cert)
-    client_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
-                                                  client_cert_pem)
-    signing_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
-                                                   server_cert_pem)
-    self.assertEqual(client_cert.get_issuer().CN, 
signing_cert.get_subject().CN)
-    self.assertEqual(client_cert.get_subject().CN, my_node_name)
-
-
-if __name__ == "__main__":
-  testutils.GanetiTestProgram()
-- 
2.4.3.573.g4eafbef

Reply via email to