Commit c9b48ec6 authored by Helga Velroyen's avatar Helga Velroyen

Init: create the master's client cert in bootstrap

This patch extends bootstrap.py to not only create
the cluster certificate but also the master node's
client certificate.
Signed-off-by: default avatarHelga Velroyen <helgav@google.com>
Reviewed-by: default avatarKlaus Aehlig <aehlig@google.com>
parent 59e3e139
......@@ -104,10 +104,12 @@ def GenerateHmacKey(file_name):
# pylint: disable=R0913
def GenerateClusterCrypto(new_cluster_cert, new_rapi_cert, new_spice_cert,
new_confd_hmac_key, new_cds,
new_confd_hmac_key, new_cds, new_client_cert,
master_name,
rapi_cert_pem=None, spice_cert_pem=None,
spice_cacert_pem=None, cds=None,
nodecert_file=pathutils.NODED_CERT_FILE,
clientcert_file=pathutils.NODED_CLIENT_CERT_FILE,
rapicert_file=pathutils.RAPI_CERT_FILE,
spicecert_file=pathutils.SPICE_CERT_FILE,
spicecacert_file=pathutils.SPICE_CACERT_FILE,
......@@ -125,6 +127,10 @@ def GenerateClusterCrypto(new_cluster_cert, new_rapi_cert, new_spice_cert,
@param new_confd_hmac_key: Whether to generate a new HMAC key
@type new_cds: bool
@param new_cds: Whether to generate a new cluster domain secret
@type new_client_cert: bool
@param new_client_cert: Whether to generate a new client certificate
@type master_name: string
@param master_name: FQDN of the master node
@type rapi_cert_pem: string
@param rapi_cert_pem: New RAPI certificate in PEM format
@type spice_cert_pem: string
......@@ -152,6 +158,12 @@ def GenerateClusterCrypto(new_cluster_cert, new_rapi_cert, new_spice_cert,
new_cluster_cert, nodecert_file, 1,
"Generating new cluster certificate at %s" % nodecert_file)
# If the cluster certificate was renewed, the client cert has to be
# renewed and resigned.
if new_cluster_cert or new_client_cert:
utils.GenerateNewClientSslCert(clientcert_file, nodecert_file,
master_name)
# confd HMAC key
if new_confd_hmac_key or not os.path.exists(hmackey_file):
logging.debug("Writing new confd HMAC key to %s", hmackey_file)
......@@ -213,7 +225,7 @@ def _InitGanetiServerSetup(master_name):
"""
# Generate cluster secrets
GenerateClusterCrypto(True, False, False, False, False)
GenerateClusterCrypto(True, False, False, False, False, False, master_name)
result = utils.RunCmd([pathutils.DAEMON_UTIL, "start", constants.NODED])
if result.failed:
......
......@@ -1018,12 +1018,15 @@ def _RenewCrypto(new_cluster_cert, new_rapi_cert, # pylint: disable=R0911
def _RenewCryptoInner(ctx):
ctx.feedback_fn("Updating certificates and keys")
# Note: the node certificate will be generated in the LU
master_name = ssconf.SimpleStore().GetMasterNode()
bootstrap.GenerateClusterCrypto(new_cluster_cert,
new_rapi_cert,
new_spice_cert,
new_confd_hmac_key,
new_cds,
True, # new client certificate for master
master_name,
rapi_cert_pem=rapi_cert_pem,
spice_cert_pem=spice_cert_pem,
spice_cacert_pem=spice_cacert_pem,
......
......@@ -390,8 +390,6 @@ class LUClusterPostInit(LogicalUnit):
self.master_ndparams.get(constants.ND_OVS_LINK, None))
result.Raise("Could not successully configure Open vSwitch")
_UpdateMasterClientCert(self, self.cfg, self.master_uuid)
return True
......
......@@ -35,6 +35,7 @@ import logging
import OpenSSL
import os
import uuid as uuid_module
import time
from ganeti.utils import io
from ganeti.utils import x509
......@@ -60,7 +61,7 @@ def GetCertificateDigest(cert_filename=pathutils.NODED_CLIENT_CERT_FILE):
def GenerateNewSslCert(new_cert, cert_filename, serial_no, log_msg,
uid=-1, gid=-1):
"""Creates a new SSL certificate and backups the old one.
"""Creates a new server SSL certificate and backups the old one.
@type new_cert: boolean
@param new_cert: whether a new certificate should be created
......@@ -85,6 +86,23 @@ def GenerateNewSslCert(new_cert, cert_filename, serial_no, log_msg,
x509.GenerateSelfSignedSslCert(cert_filename, serial_no, uid=uid, gid=gid)
def GenerateNewClientSslCert(cert_filename, signing_cert_filename,
hostname):
"""Creates a new server SSL certificate and backups the old one.
@type cert_filename: string
@param cert_filename: filename of the certificate file
@type signing_cert_filename: string
@param signing_cert_filename: name of the certificate to be used for signing
@type hostname: string
@param hostname: name of the machine whose cert is created
"""
serial_no = int(time.time())
x509.GenerateSignedSslCert(cert_filename, serial_no, signing_cert_filename,
common_name=hostname)
def VerifyCertificate(filename):
"""Verifies a SSL certificate.
......
......@@ -784,8 +784,15 @@ def main():
backup=True)
if not options.dry_run:
# This creates the cluster certificate if it does not exist yet.
# In this case, we do not automatically create a client certificate
# as well, because if the cluster certificate did not exist before,
# no client certificate will exist on any node yet. In this case
# all client certificate should be renewed by 'gnt-cluster
# renew-crypto --new-node-certificates'. This will be enforced
# by a nagging warning in 'gnt-cluster verify'.
bootstrap.GenerateClusterCrypto(
False, False, False, False, False,
False, False, False, False, False, False, None,
nodecert_file=options.SERVER_PEM_PATH,
rapicert_file=options.RAPI_CERT_FILE,
spicecert_file=options.SPICE_CERT_FILE,
......
......@@ -51,7 +51,7 @@ def main():
version = utils.version.ParseVersion(versionstring)
if utils.version.IsBefore(version, 2, 11, 0):
if utils.version.IsBefore(version, 2, 12, 5):
result = utils.RunCmd(["gnt-cluster", "renew-crypto",
"--new-node-certificates", "-f"])
if result.failed:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment