There is a bug in the current implementation of backend.RenewCrypto. Before re-generating keys, it checks if the current key of each node is in the Ganeti public key file. This was intended as a security feature, but actually does not work like that. The Ganeti public key file does only contain the keys of the potential master candidates. In case of a key-renewal, all nodes' keys are renewed and that includes the normal nodes (which are not potential master candidates). This patch removes these checks to make sure renewal does not fail if a cluster contains normal nodes.
Note: since potential master candidates are not fully implemented yet, this did not show up on actual clusters. The unit test which is implemented in a later patch of this series revealed this flaw. Signed-off-by: Helga Velroyen <[email protected]> --- lib/backend.py | 24 +++--------------------- test/py/ganeti.backend_unittest.py | 3 +-- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/lib/backend.py b/lib/backend.py index 68880f3..ceaefca 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -2004,8 +2004,7 @@ def RemoveSshKeyFromPublicKeyFile(node_name, ssh.RemovePublicKey(node_name, key_file=pub_key_file) -def _GenerateNodeSshKey(node_uuid, node_name, ssh_port_map, ssh_key_type, - ssh_key_bits, pub_key_file=pathutils.SSH_PUB_KEYS, +def _GenerateNodeSshKey(node_name, ssh_port_map, ssh_key_type, ssh_key_bits, ssconf_store=None, noded_cert_file=pathutils.NODED_CERT_FILE, run_cmd_fn=ssh.RunSshCmdWithStdin, @@ -2014,8 +2013,6 @@ def _GenerateNodeSshKey(node_uuid, node_name, ssh_port_map, ssh_key_type, ssh_update_verbose=False): """Generates the root SSH key pair on the node. - @type node_uuid: str - @param node_uuid: UUID of the node whose key is removed @type node_name: str @param node_name: name of the node whose key is remove @type ssh_port_map: dict of str to int @@ -2029,12 +2026,6 @@ def _GenerateNodeSshKey(node_uuid, node_name, ssh_port_map, ssh_key_type, if not ssconf_store: ssconf_store = ssconf.SimpleStore() - keys_by_uuid = ssh.QueryPubKeyFile([node_uuid], key_file=pub_key_file) - if not keys_by_uuid or node_uuid not in keys_by_uuid: - raise errors.SshUpdateError("Node %s (UUID: %s) whose key is requested to" - " be regenerated is not registered in the" - " public keys file." % (node_name, node_uuid)) - data = {} _InitSshUpdateData(data, noded_cert_file, ssconf_store) cluster_name = data[constants.SSHS_CLUSTER_NAME] @@ -2193,13 +2184,6 @@ def RenewSshKeys(node_uuids, node_names, master_candidate_uuids, node_list.append((node_uuid, node_name, master_candidate, potential_master_candidate)) - keys_by_uuid = ssh.QueryPubKeyFile([node_uuid], - key_file=ganeti_pub_keys_file) - if not keys_by_uuid: - raise errors.SshUpdateError("No public key of node %s (UUID %s) found," - " not generating a new key." - % (node_name, node_uuid)) - if master_candidate: logging.debug("Fetching old SSH key from node '%s'.", node_name) old_pub_key = ssh.ReadRemoteSshPubKeys(old_pub_keyfile, @@ -2240,8 +2224,7 @@ def RenewSshKeys(node_uuids, node_names, master_candidate_uuids, in node_list: logging.debug("Generating new SSH key for node '%s'.", node_name) - _GenerateNodeSshKey(node_uuid, node_name, ssh_port_map, new_key_type, - new_key_bits, pub_key_file=ganeti_pub_keys_file, + _GenerateNodeSshKey(node_name, ssh_port_map, new_key_type, new_key_bits, ssconf_store=ssconf_store, noded_cert_file=noded_cert_file, run_cmd_fn=run_cmd_fn, @@ -2288,9 +2271,8 @@ def RenewSshKeys(node_uuids, node_names, master_candidate_uuids, # Generate a new master key with a suffix, don't touch the old one for now logging.debug("Generate new ssh key of master.") - _GenerateNodeSshKey(master_node_uuid, master_node_name, ssh_port_map, + _GenerateNodeSshKey(master_node_name, ssh_port_map, new_key_type, new_key_bits, - pub_key_file=ganeti_pub_keys_file, ssconf_store=ssconf_store, noded_cert_file=noded_cert_file, run_cmd_fn=run_cmd_fn, diff --git a/test/py/ganeti.backend_unittest.py b/test/py/ganeti.backend_unittest.py index b6af71f..a30ec67 100755 --- a/test/py/ganeti.backend_unittest.py +++ b/test/py/ganeti.backend_unittest.py @@ -1062,10 +1062,9 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): key_file=self._pub_key_file) backend._GenerateNodeSshKey( - test_node_uuid, test_node_name, + test_node_name, self._ssh_file_manager.GetSshPortMap(self._SSH_PORT), "rsa", 2048, - pub_key_file=self._pub_key_file, ssconf_store=self._ssconf_mock, noded_cert_file=self.noded_cert_file, run_cmd_fn=self._run_cmd_mock) -- 2.6.0.rc2.230.g3dd15c0
