if node_status_list is None:
return ["No node list to check against the pub_key_file received."]
- my_status_list = [(my_uuid, name, mc, pot_mc) for (my_uuid, name, mc, pot_mc)
+ my_status_list = [(my_uuid, name, mc, pot_mc, online) for
+ (my_uuid, name, mc, pot_mc, online)
in node_status_list if name == my_name]
if len(my_status_list) == 0:
return ["Cannot find node information for node '%s'." % my_name]
- (my_uuid, _, _, potential_master_candidate) = \
+ (my_uuid, _, _, potential_master_candidate, online) = \
my_status_list[0]
result = []
" [--no-ssh-key-check]' to fix this." % pub_key_file)
return result
- pot_mc_uuids = [uuid for (uuid, _, _, _) in node_status_list]
+ pot_mc_uuids = [uuid for (uuid, _, _, _, _) in node_status_list]
+ offline_nodes = [uuid for (uuid, _, _, _, online) in node_status_list
+ if not online]
pub_keys = ssh.QueryPubKeyFile(None)
if potential_master_candidate:
# Check that the set of potential master candidates matches the
# public key file
- pub_uuids_set = set(pub_keys.keys())
- pot_mc_uuids_set = set(pot_mc_uuids)
+ pub_uuids_set = set(pub_keys.keys()) - set(offline_nodes)
+ pot_mc_uuids_set = set(pot_mc_uuids) - set(offline_nodes)
missing_uuids = set([])
if pub_uuids_set != pot_mc_uuids_set:
unknown_uuids = pub_uuids_set - pot_mc_uuids_set
# Check that all master candidate keys are in the authorized_keys file
(auth_key_file, _) = \
ssh.GetAllUserFiles(constants.SSH_LOGIN_USER, mkdir=False, dircheck=False)
- for (uuid, name, mc, _) in node_status_list:
+ for (uuid, name, mc, _, online) in node_status_list:
+ if not online:
+ continue
if uuid in missing_uuids:
continue
if mc:
pub_key_file=pathutils.SSH_PUB_KEYS,
ssconf_store=None,
noded_cert_file=pathutils.NODED_CERT_FILE,
+ readd=False,
run_cmd_fn=ssh.RunSshCmdWithStdin):
"""Removes the node's SSH keys from the key files and distributes those.
should be cleared on the node whose keys are removed
@type clear_public_keys: boolean
@param clear_public_keys: whether to clear the node's C{ganeti_pub_key} file
+ @type readd: boolean
+ @param readd: whether this is called during a readd operation.
@rtype: list of string
@returns: list of feedback messages
keys = keys_to_remove
else:
keys = ssh.QueryPubKeyFile([node_uuid], key_file=pub_key_file)
- if not keys or node_uuid not in keys:
+ if (not keys or node_uuid not in keys) and not readd:
raise errors.SshUpdateError("Node '%s' not found in the list of public"
" SSH keys. It seems someone tries to"
" remove a key from outside the cluster!"
if node_name == master_node and not keys_to_remove:
raise errors.SshUpdateError("Cannot remove the master node's keys.")
- if keys[node_uuid]:
+ if node_uuid in keys:
base_data = {}
_InitSshUpdateData(base_data, noded_cert_file, ssconf_store)
cluster_name = base_data[constants.SSHS_CLUSTER_NAME]
potential_master_candidates = self.cfg.GetPotentialMasterCandidates()
node_status = [
(uuid, node_info.name, node_info.master_candidate,
- node_info.name in potential_master_candidates)
+ node_info.name in potential_master_candidates, not node_info.offline)
for (uuid, node_info) in all_nodes_info.items()]
return node_status
True, # from authorized keys
True, # from public keys
False, # clear authorized keys
- True) # clear public keys
+ True, # clear public keys
+ True) # it's a readd
remove_result[master_node].Raise(
"Could not remove SSH keys of node %s before readding,"
" (UUID: %s)." % (new_node_name, new_node_uuid))
True, # remove node's key from all nodes' authorized_keys file
False, # currently, all nodes are potential master candidates
False, # do not clear node's 'authorized_keys'
- False) # do not clear node's 'ganeti_pub_keys'
+ False, # do not clear node's 'ganeti_pub_keys'
+ False) # no readd
ssh_result[master_node].Raise(
"Could not adjust the SSH setup after demoting node '%s'"
" (UUID: %s)." % (node.name, node.uuid))
self.node.master_candidate, # from_authorized_keys
potential_master_candidate, # from_public_keys
True, # clear node's 'authorized_keys'
- True) # clear node's 'ganeti_public_keys'
+ True, # clear node's 'ganeti_public_keys'
+ False) # no readd
result[master_node].Raise(
"Could not remove the SSH key of node '%s' (UUID: %s)." %
(self.op.node_name, self.node.uuid))
("clear_authorized_keys", None,
"If the 'authorized_keys' file of the node should be cleared."),
("clear_public_keys", None,
- "If the 'ganeti_pub_keys' file of the node should be cleared.")],
+ "If the 'ganeti_pub_keys' file of the node should be cleared."),
+ ("readd", None,
+ "Whether this is a readd operation.")],
None, None, "Remove a node's SSH key from the other nodes' key files."),
("node_ssh_keys_renew", MULTI, None, constants.RPC_TMO_SLOW, [
("node_uuids", None, "UUIDs of the nodes whose key is renewed"),
(node_uuid, node_name,
master_candidate_uuids, potential_master_candidates,
from_authorized_keys, from_public_keys, clear_authorized_keys,
- clear_public_keys) = params
+ clear_public_keys, readd) = params
return backend.RemoveNodeSshKey(node_uuid, node_name,
master_candidate_uuids,
potential_master_candidates,
from_authorized_keys=from_authorized_keys,
from_public_keys=from_public_keys,
clear_authorized_keys=clear_authorized_keys,
- clear_public_keys=clear_public_keys)
+ clear_public_keys=clear_public_keys,
+ readd=readd)
# cluster --------------------------
_NODE3_KEYS = ["key31"]
_NODE_STATUS_LIST = [
- (_NODE1_UUID, _NODE1_NAME, True, True),
- (_NODE2_UUID, _NODE2_NAME, False, True),
- (_NODE3_UUID, _NODE3_NAME, False, False),
+ (_NODE1_UUID, _NODE1_NAME, True, True, True),
+ (_NODE2_UUID, _NODE2_NAME, False, True, True),
+ (_NODE3_UUID, _NODE3_NAME, False, False, True),
]
_PUB_KEY_RESULT = {