Commit d2050bd1 authored by Helga Velroyen's avatar Helga Velroyen

Handle SSL setup when downgrading

This patch will handle the downgrade of the SSL setup
from 2.12 to 2.11. Essentially, all client.pem and
ssconf_master_candidates_certs files will be deleted.
This will kick the cluster in a pre-2.11 mode wrt to
SSL and result in a nagging message to re-run
'gnt-cluster renew-crypto' when as output of 'gnt-cluster
verify'.
Signed-off-by: default avatarHelga Velroyen <helgav@google.com>
Reviewed-by: default avatarPetr Pudlak <pudlak@google.com>
parent d657fadc
......@@ -1071,6 +1071,7 @@ def _RenewCrypto(new_cluster_cert, new_rapi_cert, # pylint: disable=R0911
constants.NDS_NODE_DAEMON_CERTIFICATE:
utils.ReadFile(pathutils.NODED_CERT_FILE),
constants.NDS_NODE_NAME: node_name,
constants.NDS_ACTION: constants.CRYPTO_ACTION_CREATE,
}
bootstrap.RunNodeSetupCmd(
......@@ -2068,6 +2069,38 @@ def _VersionSpecificDowngrade():
@return: True upon success
"""
ToStdout("Performing version-specific downgrade tasks.")
nodes = ssconf.SimpleStore().GetOnlineNodeList()
cluster_name = ssconf.SimpleStore().GetClusterName()
ssh_ports = ssconf.SimpleStore().GetSshPortMap()
for node in nodes:
data = {
constants.NDS_CLUSTER_NAME: cluster_name,
constants.NDS_NODE_DAEMON_CERTIFICATE:
utils.ReadFile(pathutils.NODED_CERT_FILE),
constants.NDS_NODE_NAME: node,
constants.NDS_ACTION: constants.CRYPTO_ACTION_DELETE,
}
try:
bootstrap.RunNodeSetupCmd(
cluster_name,
node,
pathutils.SSL_UPDATE,
True, # debug
True, # verbose,
True, # use cluster key
False, # ask key
True, # strict host check
ssh_ports[node],
data)
except Exception as e: # pylint: disable=W0703
# As downgrading can fail if a node is temporarily unreachable
# only output the error, but do not abort the entire operation.
ToStderr("Downgrading SSL setup of node '%s' failed: %s." %
(node, e))
return True
......
......@@ -42,6 +42,7 @@ 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
......@@ -49,6 +50,7 @@ _DATA_CHECK = ht.TStrictDict(False, True, {
constants.NDS_CLUSTER_NAME: ht.TNonEmptyString,
constants.NDS_NODE_DAEMON_CERTIFICATE: ht.TNonEmptyString,
constants.NDS_NODE_NAME: ht.TNonEmptyString,
constants.NDS_ACTION: ht.TNonEmptyString,
})
......@@ -75,6 +77,37 @@ def ParseOptions():
return common.VerifyOptions(parser, opts, args)
def DeleteClientCertificate():
"""Deleting the client certificate. This is necessary for downgrades."""
if os.path.exists(pathutils.NODED_CLIENT_CERT_FILE):
os.remove(pathutils.NODED_CLIENT_CERT_FILE)
else:
logging.debug("Trying to delete the client certificate '%s' which did not"
" exist.", pathutils.NODED_CLIENT_CERT_FILE)
def ClearMasterCandidateSsconfList():
"""Clear the ssconf list of master candidate certs.
This is necessary when deleting the client certificates for a downgrade,
because otherwise the master cannot distribute the configuration to the
nodes via RPC during a downgrade anymore.
"""
ssconf_file = os.path.join(
pathutils.DATA_DIR,
"%s%s" % (constants.SSCONF_FILEPREFIX,
constants.SS_MASTER_CANDIDATES_CERTS))
if os.path.exists:
os.remove(ssconf_file)
else:
logging.debug("Trying to delete the ssconf file '%s' which does not"
" exist.", ssconf_file)
# pylint: disable=E1103
# This pyling message complains about 'data' as 'bool' not having a get
# member, but obviously the type is wrongly inferred.
def Main():
"""Main routine.
......@@ -92,7 +125,17 @@ def Main():
# is the same as on this node.
common.VerifyCertificate(data, SslSetupError)
common.GenerateClientCertificate(data, SslSetupError)
action = data.get(constants.NDS_ACTION)
if not action:
raise SslSetupError("No Action specified.")
if action == constants.CRYPTO_ACTION_CREATE:
common.GenerateClientCertificate(data, SslSetupError)
elif action == constants.CRYPTO_ACTION_DELETE:
DeleteClientCertificate()
ClearMasterCandidateSsconfList()
else:
raise SslSetupError("Unsupported action: %s." % action)
except Exception, err: # pylint: disable=W0703
logging.debug("Caught unhandled exception", exc_info=True)
......
......@@ -4385,8 +4385,17 @@ cryptoTypes = ConstantUtils.mkSet [cryptoTypeSslDigest]
cryptoActionGet :: String
cryptoActionGet = "get"
cryptoActionCreate :: String
cryptoActionCreate = "create"
cryptoActionDelete :: String
cryptoActionDelete = "delete"
cryptoActions :: FrozenSet String
cryptoActions = ConstantUtils.mkSet [cryptoActionGet]
cryptoActions =
ConstantUtils.mkSet [ cryptoActionCreate
, cryptoActionGet
, cryptoActionDelete]
-- Key word for master candidate cert list for bootstrapping.
......@@ -4486,6 +4495,9 @@ ndsStartNodeDaemon = "start_node_daemon"
ndsNodeName :: String
ndsNodeName = "node_name"
ndsAction :: String
ndsAction = "action"
-- * VCluster related constants
vClusterEtcHosts :: String
......
......@@ -524,6 +524,11 @@ def DowngradeCluster(config_data):
if "max_tracked_jobs" in cluster:
del cluster["max_tracked_jobs"]
if "candidate_certs" in cluster:
# Clear the candidate certs to make people run 'gnt-cluster renew-crypto'
# after a downgrade from 2.12 to 2.11.
cluster["candidate_certs"] = {}
def DowngradeGroups(config_data):
for group in config_data["nodegroups"].values():
......
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