When performing an upgrade of an old cluster, it is necessary to set the SSH key parameters to the exact same values earlier versions implicitly used - DSA with 1024 bits.
In the other direction, we simply do not permit downgrades if keys other than DSA are being used. Triggering a gnt-cluster renew-crypto might be time-consuming and surprising for the user, so we are simply throwing out an error message, explaining that the downgrade cannot be performed in the current state of the cluster. Signed-off-by: Hrvoje Ribicic <[email protected]> --- lib/tools/cfgupgrade.py | 50 +++++++++++++++++++++++++++++++++++++++++- test/py/cfgupgrade_unittest.py | 2 ++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/tools/cfgupgrade.py b/lib/tools/cfgupgrade.py index 43cf2c6..943b9a9 100644 --- a/lib/tools/cfgupgrade.py +++ b/lib/tools/cfgupgrade.py @@ -307,24 +307,33 @@ class CfgUpgrade(object): cluster = self.config_data.get("cluster", None) if cluster is None: raise Error("Cannot find cluster") + ipolicy = cluster.setdefault("ipolicy", None) if ipolicy: self.UpgradeIPolicy(ipolicy, constants.IPOLICY_DEFAULTS, False) ial_params = cluster.get("default_iallocator_params", None) + if not ial_params: cluster["default_iallocator_params"] = {} + if not "candidate_certs" in cluster: cluster["candidate_certs"] = {} + cluster["instance_communication_network"] = \ cluster.get("instance_communication_network", "") + cluster["install_image"] = \ cluster.get("install_image", "") + cluster["zeroing_image"] = \ cluster.get("zeroing_image", "") + cluster["compression_tools"] = \ cluster.get("compression_tools", constants.IEC_DEFAULT_TOOLS) + if "enabled_user_shutdown" not in cluster: cluster["enabled_user_shutdown"] = False + cluster["data_collectors"] = cluster.get("data_collectors", {}) for name in constants.DATA_COLLECTOR_NAMES: cluster["data_collectors"][name] = \ @@ -332,6 +341,14 @@ class CfgUpgrade(object): name, dict(active=True, interval=constants.MOND_TIME_INTERVAL * 1e6)) + # These parameters are set to pre-2.16 default values, which + # differ from post-2.16 default values + if "ssh_key_type" not in cluster: + cluster["ssh_key_type"] = constants.SSHK_DSA + + if "ssh_key_bits" not in cluster: + cluster["ssh_key_bits"] = 1024 + @OrFail("Upgrading groups") def UpgradeGroups(self): cl_ipolicy = self.config_data["cluster"].get("ipolicy") @@ -699,10 +716,41 @@ class CfgUpgrade(object): # DOWNGRADE ------------------------------------------------------------ + @OrFail("Removing SSH parameters") + def DowngradeSshKeyParams(self): + """Removes the SSH key type and bits parameters from the config. + + Also fails if these have been changed from values appropriate in lower + Ganeti versions. + + """ + # pylint: disable=E1103 + # Because config_data is a dictionary which has the get method. + cluster = self.config_data.get("cluster", None) + if cluster is None: + raise Error("Can't find the cluster entry in the configuration") + + def _FetchAndDelete(key): + val = cluster.get(key, None) + if key in cluster: + del cluster[key] + return val + + ssh_key_type = _FetchAndDelete("ssh_key_type") + _FetchAndDelete("ssh_key_bits") + + if ssh_key_type is not None and ssh_key_type != "dsa": + raise Error("The current Ganeti setup is using non-DSA SSH keys, and" + " versions below 2.16 do not support these. To downgrade," + " please perform a gnt-cluster renew-crypto, and generate" + " DSA keys that older versions can also use.") + def DowngradeAll(self): self.config_data["version"] = version.BuildVersion(DOWNGRADE_MAJOR, DOWNGRADE_MINOR, 0) - return True + + self.DowngradeSshKeyParams() + return not self.errors def _ComposePaths(self): # We need to keep filenames locally because they might be renamed between diff --git a/test/py/cfgupgrade_unittest.py b/test/py/cfgupgrade_unittest.py index 9d5d950..3f587662 100755 --- a/test/py/cfgupgrade_unittest.py +++ b/test/py/cfgupgrade_unittest.py @@ -74,6 +74,8 @@ def GetMinimalConfig(): "cpu-avg-load": { "active": True, "interval": 5000000 }, "xen-cpu-avg-load": { "active": True, "interval": 5000000 }, }, + "ssh_key_type": "dsa", + "ssh_key_bits": 1024, }, "instances": {}, "disks": {}, -- 2.6.0.rc2.230.g3dd15c0
