Recently, the SSH port information was added to ssconf file. This patch makes use of it when adding, removing, or renewing SSH keys. The main benefit of it is to reduce the signature of the backend functions and thus the RPC load.
Signed-off-by: Helga Velroyen <[email protected]> --- lib/backend.py | 23 ++++++++----------- lib/cmdlib/cluster.py | 3 +-- lib/cmdlib/node.py | 14 ++++-------- lib/server/noded.py | 13 +++++------ lib/ssh.py | 22 ------------------ test/py/ganeti.backend_unittest.py | 46 ++++++++++++++------------------------ 6 files changed, 37 insertions(+), 84 deletions(-) diff --git a/lib/backend.py b/lib/backend.py index 7c82d8d..5454aba 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -1415,7 +1415,6 @@ def _InitSshUpdateData(data, noded_cert_file, ssconf_store): def AddNodeSshKey(node_uuid, node_name, potential_master_candidates, - ssh_port_map, to_authorized_keys=False, to_public_keys=False, get_public_keys=False, @@ -1436,8 +1435,6 @@ def AddNodeSshKey(node_uuid, node_name, @param node_uuid: the UUID of the node whose key is added @type node_name: str @param node_name: the name of the node whose key is added - @type ssh_port_map: dict from str to int - @param ssh_port_map: a mapping from node names to SSH port numbers @type potential_master_candidates: list of str @param potential_master_candidates: list of node names of potential master candidates; this should match the list of uuids in the public key file @@ -1487,6 +1484,8 @@ def AddNodeSshKey(node_uuid, node_name, _InitSshUpdateData(base_data, noded_cert_file, ssconf_store) cluster_name = base_data[constants.SSHS_CLUSTER_NAME] + ssh_port_map = ssconf_store.GetSshPortMap() + # Update the target node itself logging.debug("Updating SSH key files of target node '%s'.", node_name) if get_public_keys: @@ -1566,7 +1565,6 @@ def AddNodeSshKey(node_uuid, node_name, def RemoveNodeSshKey(node_uuid, node_name, master_candidate_uuids, potential_master_candidates, - ssh_port_map, master_uuid=None, keys_to_remove=None, from_authorized_keys=False, @@ -1593,8 +1591,6 @@ def RemoveNodeSshKey(node_uuid, node_name, @type potential_master_candidates: list of str @param potential_master_candidates: list of names of potential master candidates - @type ssh_port_map: dict of str to int - @param ssh_port_map: mapping of node names to their SSH port @type keys_to_remove: dict of str to list of str @param keys_to_remove: a dictionary mapping node UUIDS to lists of SSH keys to be removed. This list is supposed to be used only if the keys are not @@ -1627,6 +1623,7 @@ def RemoveNodeSshKey(node_uuid, node_name, ssconf_store = ssconf.SimpleStore() master_node = ssconf_store.GetMasterNode() + ssh_port_map = ssconf_store.GetSshPortMap() if from_authorized_keys or from_public_keys: if keys_to_remove: @@ -1881,8 +1878,7 @@ def _ReplaceMasterKeyOnMaster(root_keyfiles): raise errors.SshUpdateError("Could not move at least one master SSH key.") -def RenewSshKeys(node_uuids, node_names, ssh_port_map, - master_candidate_uuids, +def RenewSshKeys(node_uuids, node_names, master_candidate_uuids, potential_master_candidates, pub_key_file=pathutils.SSH_PUB_KEYS, ssconf_store=None, @@ -1895,8 +1891,6 @@ def RenewSshKeys(node_uuids, node_names, ssh_port_map, @type node_names: list of str @param node_names: list of node names whose keys should be removed. This list should match the C{node_uuids} parameter - @type ssh_port_map: dict of str to int - @param ssh_port_map: map of node UUID to ssh port number @type master_candidate_uuids: list of str @param master_candidate_uuids: list of UUIDs of master candidates or master node @@ -1930,6 +1924,7 @@ def RenewSshKeys(node_uuids, node_names, ssh_port_map, master_node_name = ssconf_store.GetMasterNode() master_node_uuid = _GetMasterNodeUUID(node_uuid_name_map, master_node_name) + ssh_port_map = ssconf_store.GetSshPortMap() # List of all node errors that happened, but which did not abort the # procedure as a whole. It is important that this is a list to have a # somewhat chronological history of events. @@ -1964,7 +1959,7 @@ def RenewSshKeys(node_uuids, node_names, ssh_port_map, logging.debug("Removing SSH key of node '%s'.", node_name) node_errors = RemoveNodeSshKey( node_uuid, node_name, master_candidate_uuids, - potential_master_candidates, ssh_port_map, + potential_master_candidates, master_uuid=master_node_uuid, from_authorized_keys=master_candidate, from_public_keys=False, clear_authorized_keys=False, clear_public_keys=False) @@ -1999,7 +1994,7 @@ def RenewSshKeys(node_uuids, node_names, ssh_port_map, logging.debug("Add ssh key of node '%s'.", node_name) node_errors = AddNodeSshKey( node_uuid, node_name, potential_master_candidates, - ssh_port_map, to_authorized_keys=master_candidate, + to_authorized_keys=master_candidate, to_public_keys=potential_master_candidate, get_public_keys=True, pub_key_file=pub_key_file, ssconf_store=ssconf_store, @@ -2033,7 +2028,7 @@ def RenewSshKeys(node_uuids, node_names, ssh_port_map, logging.debug("Add new master key to all nodes.") node_errors = AddNodeSshKey( master_node_uuid, master_node_name, potential_master_candidates, - ssh_port_map, to_authorized_keys=True, to_public_keys=True, + to_authorized_keys=True, to_public_keys=True, get_public_keys=False, pub_key_file=pub_key_file, ssconf_store=ssconf_store, noded_cert_file=noded_cert_file, run_cmd_fn=run_cmd_fn) @@ -2053,7 +2048,7 @@ def RenewSshKeys(node_uuids, node_names, ssh_port_map, logging.debug("Remove the old master key from all nodes.") node_errors = RemoveNodeSshKey( master_node_uuid, master_node_name, master_candidate_uuids, - potential_master_candidates, ssh_port_map, + potential_master_candidates, keys_to_remove=old_master_keys_by_uuid, from_authorized_keys=True, from_public_keys=False, clear_authorized_keys=False, clear_public_keys=False) diff --git a/lib/cmdlib/cluster.py b/lib/cmdlib/cluster.py index 01acb75..dd758ec 100644 --- a/lib/cmdlib/cluster.py +++ b/lib/cmdlib/cluster.py @@ -175,13 +175,12 @@ class LUClusterRenewCrypto(NoHooksLU): in nodes.items() if not node_info.offline] node_names = [name for (_, name) in nodes_uuid_names] node_uuids = [uuid for (uuid, _) in nodes_uuid_names] - port_map = ssh.GetSshPortMap(node_names, self.cfg) potential_master_candidates = self.cfg.GetPotentialMasterCandidates() master_candidate_uuids = self.cfg.GetMasterCandidateUuids() result = self.rpc.call_node_ssh_keys_renew( [master_uuid], - node_uuids, node_names, port_map, + node_uuids, node_names, master_candidate_uuids, potential_master_candidates) diff --git a/lib/cmdlib/node.py b/lib/cmdlib/node.py index b6d67bc..9c2ba21 100644 --- a/lib/cmdlib/node.py +++ b/lib/cmdlib/node.py @@ -55,8 +55,6 @@ from ganeti.cmdlib.common import CheckParamsNotGlobal, \ AddNodeCertToCandidateCerts, RemoveNodeCertFromCandidateCerts, \ EnsureKvmdOnNodes, WarnAboutFailedSshUpdates -from ganeti.ssh import GetSshPortMap - def _DecideSelfPromotion(lu, exceptions=None): """Decide whether I should promote myself as a master candidate. @@ -349,7 +347,6 @@ class LUNodeAdd(LogicalUnit): """ potential_master_candidates = self.cfg.GetPotentialMasterCandidates() master_node = self.cfg.GetMasterNode() - port_map = GetSshPortMap(potential_master_candidates, self.cfg) if readd: # clear previous keys @@ -359,7 +356,6 @@ class LUNodeAdd(LogicalUnit): new_node_uuid, new_node_name, master_candidate_uuids, potential_master_candidates, - port_map, True, # from authorized keys True, # from public keys False, # clear authorized keys @@ -371,7 +367,7 @@ class LUNodeAdd(LogicalUnit): result = rpcrunner.call_node_ssh_key_add( [master_node], new_node_uuid, new_node_name, - potential_master_candidates, port_map, + potential_master_candidates, is_master_candidate, is_potential_master_candidate, is_potential_master_candidate) @@ -872,14 +868,13 @@ class LUNodeSetParams(LogicalUnit): if self.cfg.GetClusterInfo().modify_ssh_setup: potential_master_candidates = self.cfg.GetPotentialMasterCandidates() - ssh_port_map = GetSshPortMap(potential_master_candidates, self.cfg) master_node = self.cfg.GetMasterNode() if self.old_role == self._ROLE_CANDIDATE: master_candidate_uuids = self.cfg.GetMasterCandidateUuids() ssh_result = self.rpc.call_node_ssh_key_remove( [master_node], node.uuid, node.name, - master_candidate_uuids, potential_master_candidates, ssh_port_map, + master_candidate_uuids, potential_master_candidates, 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' @@ -892,7 +887,7 @@ class LUNodeSetParams(LogicalUnit): if self.new_role == self._ROLE_CANDIDATE: ssh_result = self.rpc.call_node_ssh_key_add( [master_node], node.uuid, node.name, - potential_master_candidates, ssh_port_map, + potential_master_candidates, True, # add node's key to all node's 'authorized_keys' True, # all nodes are potential master candidates False) # do not update the node's public keys @@ -1582,13 +1577,12 @@ class LUNodeRemove(LogicalUnit): potential_master_candidates = self.cfg.GetPotentialMasterCandidates() potential_master_candidate = \ self.op.node_name in potential_master_candidates - ssh_port_map = GetSshPortMap(potential_master_candidates, self.cfg) master_candidate_uuids = self.cfg.GetMasterCandidateUuids() master_node = self.cfg.GetMasterNode() result = self.rpc.call_node_ssh_key_remove( [master_node], self.node.uuid, self.op.node_name, - master_candidate_uuids, potential_master_candidates, ssh_port_map, + master_candidate_uuids, potential_master_candidates, self.node.master_candidate, # from_authorized_keys potential_master_candidate, # from_public_keys True, # clear node's 'authorized_keys' diff --git a/lib/server/noded.py b/lib/server/noded.py index 80bcaf6..27f5128 100644 --- a/lib/server/noded.py +++ b/lib/server/noded.py @@ -923,10 +923,10 @@ class NodeRequestHandler(http.server.HttpServerHandler): """Distributes a new node's SSH key if authorized. """ - (node_uuid, node_name, potential_master_candidates, ssh_port_map, + (node_uuid, node_name, potential_master_candidates, to_authorized_keys, to_public_keys, get_public_keys) = params return backend.AddNodeSshKey(node_uuid, node_name, - potential_master_candidates, ssh_port_map, + potential_master_candidates, to_authorized_keys=to_authorized_keys, to_public_keys=to_public_keys, get_public_keys=get_public_keys) @@ -936,9 +936,9 @@ class NodeRequestHandler(http.server.HttpServerHandler): """Generates a new root SSH key pair on the node. """ - (node_uuids, node_names, ssh_port_map, - master_candidate_uuids, potential_master_candidates) = params - return backend.RenewSshKeys(node_uuids, node_names, ssh_port_map, + (node_uuids, node_names, master_candidate_uuids, + potential_master_candidates) = params + return backend.RenewSshKeys(node_uuids, node_names, master_candidate_uuids, potential_master_candidates) @@ -948,13 +948,12 @@ class NodeRequestHandler(http.server.HttpServerHandler): """ (node_uuid, node_name, - master_candidate_uuids, potential_master_candidates, ssh_port_map, + master_candidate_uuids, potential_master_candidates, from_authorized_keys, from_public_keys, clear_authorized_keys, clear_public_keys) = params return backend.RemoveNodeSshKey(node_uuid, node_name, master_candidate_uuids, potential_master_candidates, - ssh_port_map, from_authorized_keys=from_authorized_keys, from_public_keys=from_public_keys, clear_authorized_keys=clear_authorized_keys, diff --git a/lib/ssh.py b/lib/ssh.py index e260450..7d34f29 100644 --- a/lib/ssh.py +++ b/lib/ssh.py @@ -1067,28 +1067,6 @@ def RunSshCmdWithStdin(cluster_name, node, basecmd, port, data, (result.cmd, result.fail_reason)) -def GetSshPortMap(nodes, cfg): - """Retrieves SSH ports of given nodes from the config. - - @param nodes: the names of nodes - @type nodes: a list of strings - @param cfg: a configuration object - @type cfg: L{ConfigWriter} - @return: a map from node names to ssh ports - @rtype: a dict from str to int - - """ - node_port_map = {} - node_groups = dict(map(lambda n: (n.name, n.group), - cfg.GetAllNodesInfo().values())) - group_port_map = cfg.GetGroupSshPorts() - for node in nodes: - group_uuid = node_groups.get(node) - ssh_port = group_port_map.get(group_uuid) - node_port_map[node] = ssh_port - return node_port_map - - def ReadRemoteSshPubKeys(pub_key_file, node, cluster_name, port, ask_key, strict_host_check): """Fetches the public DSA SSH key from a node via SSH. diff --git a/test/py/ganeti.backend_unittest.py b/test/py/ganeti.backend_unittest.py index f0e0d10..c75d5b2 100755 --- a/test/py/ganeti.backend_unittest.py +++ b/test/py/ganeti.backend_unittest.py @@ -45,7 +45,6 @@ from ganeti import errors from ganeti import hypervisor from ganeti import netutils from ganeti import objects -from ganeti import pathutils from ganeti import serializer from ganeti import ssh from ganeti import utils @@ -948,6 +947,7 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): self._ssconf_mock.GetMasterNode = mock.Mock() self._ssconf_mock.GetClusterName = mock.Mock() self._ssconf_mock.GetOnlineNodeList = mock.Mock() + self._ssconf_mock.GetSshPortMap = mock.Mock() self._run_cmd_mock = mock.Mock() self._run_cmd_mock.side_effect = self._ssh_file_manager.RunCommand @@ -1008,7 +1008,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): self._all_nodes = [] self._potential_master_candidates = [] self._master_candidate_uuids = [] - self._ssh_port_map = {} self._ssconf_mock.reset_mock() self._ssconf_mock.GetNodeList.reset_mock() @@ -1019,7 +1018,8 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): self._ssh_file_manager.InitAllNodes(15, 10, 5) self._master_node = self._ssh_file_manager.GetMasterNodeName() - self._ssh_port_map = self._ssh_file_manager.GetSshPortMap(self._SSH_PORT) + self._ssconf_mock.GetSshPortMap.return_value = \ + self._ssh_file_manager.GetSshPortMap(self._SSH_PORT) self._potential_master_candidates = \ self._ssh_file_manager.GetAllPotentialMasterCandidateNodeNames() self._master_candidate_uuids = \ @@ -1049,12 +1049,13 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): ssh.AddPublicKey(test_node_uuid, "some_old_key", key_file=self._pub_key_file) - backend._GenerateNodeSshKey(test_node_uuid, test_node_name, - self._ssh_port_map, - 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) + backend._GenerateNodeSshKey( + test_node_uuid, test_node_name, + self._ssh_file_manager.GetSshPortMap(self._SSH_PORT), + 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) calls_per_node = self._GetCallsPerNode() for node, calls in calls_per_node.items(): @@ -1069,7 +1070,8 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): ssh.AddPublicKey(name, key, key_file=self._pub_key_file) self._potential_master_candidates.append(name) - self._ssh_port_map[name] = self._SSH_PORT + self._ssconf_mock.GetSshPortMap.return_value = \ + self._ssh_file_manager.GetSshPortMap(self._SSH_PORT) def _GetNewMasterCandidate(self): """Returns the properties of a new master candidate node.""" @@ -1086,7 +1088,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.AddNodeSshKey(new_node_uuid, new_node_name, self._potential_master_candidates, - self._ssh_port_map, to_authorized_keys=is_master_candidate, to_public_keys=is_potential_master_candidate, get_public_keys=is_potential_master_candidate, @@ -1114,7 +1115,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.AddNodeSshKey(new_node_uuid, new_node_name, self._potential_master_candidates, - self._ssh_port_map, to_authorized_keys=is_master_candidate, to_public_keys=is_potential_master_candidate, get_public_keys=is_potential_master_candidate, @@ -1142,7 +1142,7 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): self.assertRaises( AssertionError, backend.AddNodeSshKey, new_node_uuid, new_node_name, - self._potential_master_candidates, self._ssh_port_map, + self._potential_master_candidates, to_authorized_keys=is_master_candidate, to_public_keys=is_potential_master_candidate, get_public_keys=is_potential_master_candidate, @@ -1165,7 +1165,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.AddNodeSshKey(node_info.uuid, node_name, self._potential_master_candidates, - self._ssh_port_map, to_authorized_keys=True, to_public_keys=False, get_public_keys=False, @@ -1186,7 +1185,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.RemoveNodeSshKey(node_uuid, node_name, self._master_candidate_uuids, self._potential_master_candidates, - self._ssh_port_map, from_authorized_keys=True, from_public_keys=True, clear_authorized_keys=True, @@ -1210,7 +1208,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.RemoveNodeSshKey(node_info.uuid, node_name, self._master_candidate_uuids, self._potential_master_candidates, - self._ssh_port_map, from_authorized_keys=False, from_public_keys=True, clear_authorized_keys=True, @@ -1234,7 +1231,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.RemoveNodeSshKey(node_info.uuid, node_name, self._master_candidate_uuids, self._potential_master_candidates, - self._ssh_port_map, from_authorized_keys=False, from_public_keys=False, clear_authorized_keys=True, @@ -1261,7 +1257,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.RemoveNodeSshKey(node_info.uuid, node_name, self._master_candidate_uuids, self._potential_master_candidates, - self._ssh_port_map, from_authorized_keys=True, from_public_keys=False, clear_authorized_keys=False, @@ -1285,7 +1280,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.RemoveNodeSshKey(node_info.uuid, node_name, self._master_candidate_uuids, self._potential_master_candidates, - self._ssh_port_map, from_authorized_keys=False, from_public_keys=True, clear_authorized_keys=False, @@ -1317,7 +1311,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.AddNodeSshKey(new_node_uuid, new_node_name, self._potential_master_candidates, - self._ssh_port_map, to_authorized_keys=is_master_candidate, to_public_keys=is_potential_master_candidate, get_public_keys=is_potential_master_candidate, @@ -1343,7 +1336,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.RemoveNodeSshKey(node_info.uuid, node_name, self._master_candidate_uuids, self._potential_master_candidates, - self._ssh_port_map, from_authorized_keys=True, from_public_keys=True, clear_authorized_keys=True, @@ -1378,7 +1370,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.AddNodeSshKey(new_node_uuid, new_node_name, self._potential_master_candidates, - self._ssh_port_map, to_authorized_keys=is_master_candidate, to_public_keys=is_potential_master_candidate, get_public_keys=is_potential_master_candidate, @@ -1412,7 +1403,7 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): self.assertRaises( errors.SshUpdateError, backend.AddNodeSshKey, new_node_uuid, - new_node_name, self._potential_master_candidates, self._ssh_port_map, + new_node_name, self._potential_master_candidates, to_authorized_keys=is_master_candidate, to_public_keys=is_potential_master_candidate, get_public_keys=is_potential_master_candidate, @@ -1453,7 +1444,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.AddNodeSshKey(new_node_uuid, new_node_name, self._potential_master_candidates, - self._ssh_port_map, to_authorized_keys=is_master_candidate, to_public_keys=is_potential_master_candidate, get_public_keys=is_potential_master_candidate, @@ -1487,7 +1477,7 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): node_errors = backend.AddNodeSshKey( new_node_uuid, new_node_name, self._potential_master_candidates, - self._ssh_port_map, to_authorized_keys=is_master_candidate, + to_authorized_keys=is_master_candidate, to_public_keys=is_potential_master_candidate, get_public_keys=is_potential_master_candidate, pub_key_file=self._pub_key_file, @@ -1523,7 +1513,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.RemoveNodeSshKey(node_info.uuid, node_name, self._master_candidate_uuids, self._potential_master_candidates, - self._ssh_port_map, from_authorized_keys=True, from_public_keys=True, clear_authorized_keys=True, @@ -1556,7 +1545,7 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): error_msgs = backend.RemoveNodeSshKey( node_info.uuid, node_name, self._master_candidate_uuids, - self._potential_master_candidates, self._ssh_port_map, + self._potential_master_candidates, from_authorized_keys=True, from_public_keys=True, clear_authorized_keys=True, clear_public_keys=True, pub_key_file=self._pub_key_file, ssconf_store=self._ssconf_mock, @@ -1583,7 +1572,6 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): backend.RemoveNodeSshKey(node_info.uuid, node_name, self._master_candidate_uuids, self._potential_master_candidates, - self._ssh_port_map, from_authorized_keys=True, from_public_keys=True, clear_authorized_keys=True, @@ -1613,7 +1601,7 @@ class TestAddRemoveGenerateNodeSshKey(testutils.GanetiTestCase): error_msgs = backend.RemoveNodeSshKey( node_info.uuid, node_name, self._master_candidate_uuids, - self._potential_master_candidates, self._ssh_port_map, + self._potential_master_candidates, from_authorized_keys=True, from_public_keys=True, clear_authorized_keys=True, clear_public_keys=True, pub_key_file=self._pub_key_file, ssconf_store=self._ssconf_mock, -- 2.4.3.573.g4eafbef
