Handle SSH key distribution on auto promotion
authorHelga Velroyen <helgav@google.com>
Fri, 6 Nov 2015 10:26:08 +0000 (11:26 +0100)
committerHelga Velroyen <helgav@google.com>
Fri, 6 Nov 2015 13:02:03 +0000 (14:02 +0100)
This fixes the missing SSH key distribution in case
a node gets autopromoted to master candidate.

Signed-off-by: Helga Velroyen <helgav@google.com>
Reviewed-by: Lisa Velden <velden@google.com>

lib/cmdlib/cluster/__init__.py
lib/cmdlib/common.py
lib/cmdlib/node.py

index 51474d6..cfe5feb 100644 (file)
@@ -1667,7 +1667,12 @@ class LUClusterSetParams(LogicalUnit):
     if self.op.candidate_pool_size is not None:
       self.cluster.candidate_pool_size = self.op.candidate_pool_size
       # we need to update the pool size here, otherwise the save will fail
-      AdjustCandidatePool(self, [])
+      master_node = self.cfg.GetMasterNode()
+      potential_master_candidates = self.cfg.GetPotentialMasterCandidates()
+      modify_ssh_setup = self.cfg.GetClusterInfo().modify_ssh_setup
+      AdjustCandidatePool(
+          self, [], master_node, potential_master_candidates, feedback_fn,
+          modify_ssh_setup)
 
     if self.op.max_running_jobs is not None:
       self.cluster.max_running_jobs = self.op.max_running_jobs
index fa2bf77..1d79a3e 100644 (file)
@@ -476,9 +476,35 @@ def CheckHVParams(lu, node_uuids, hvname, hvparams):
                lu.cfg.GetNodeName(node_uuid))
 
 
-def AdjustCandidatePool(lu, exceptions):
+def AddMasterCandidateSshKey(
+    lu, master_node, node, potential_master_candidates, feedback_fn):
+  ssh_result = lu.rpc.call_node_ssh_key_add(
+    [master_node], node.uuid, node.name,
+    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
+  ssh_result[master_node].Raise(
+    "Could not update the SSH setup of node '%s' after promotion"
+    " (UUID: %s)." % (node.name, node.uuid))
+  WarnAboutFailedSshUpdates(ssh_result, master_node, feedback_fn)
+
+
+def AdjustCandidatePool(
+    lu, exceptions, master_node, potential_master_candidates, feedback_fn,
+    modify_ssh_setup):
   """Adjust the candidate pool after node operations.
 
+  @type master_node: string
+  @param master_node: name of the master node
+  @type potential_master_candidates: list of string
+  @param potential_master_candidates: list of node names of potential master
+      candidates
+  @type feedback_fn: function
+  @param feedback_fn: function emitting user-visible output
+  @type modify_ssh_setup: boolean
+  @param modify_ssh_setup: whether or not the ssh setup can be modified.
+
   """
   mod_list = lu.cfg.MaintainCandidatePool(exceptions)
   if mod_list:
@@ -487,6 +513,10 @@ def AdjustCandidatePool(lu, exceptions):
     for node in mod_list:
       lu.context.ReaddNode(node)
       AddNodeCertToCandidateCerts(lu, lu.cfg, node.uuid)
+      if modify_ssh_setup:
+        AddMasterCandidateSshKey(
+            lu, master_node, node, potential_master_candidates, feedback_fn)
+
   mc_now, mc_max, _ = lu.cfg.GetMasterCandidateStats(exceptions)
   if mc_now > mc_max:
     lu.LogInfo("Note: more nodes are candidates (%d) than desired (%d)" %
index 569fa25..c67c65d 100644 (file)
@@ -53,7 +53,7 @@ from ganeti.cmdlib.common import CheckParamsNotGlobal, \
   GetWantedNodes, MapInstanceLvsToNodes, RunPostHook, \
   FindFaultyInstanceDisks, CheckStorageTypeEnabled, GetClientCertDigest, \
   AddNodeCertToCandidateCerts, RemoveNodeCertFromCandidateCerts, \
-  EnsureKvmdOnNodes, WarnAboutFailedSshUpdates
+  EnsureKvmdOnNodes, WarnAboutFailedSshUpdates, AddMasterCandidateSshKey
 
 
 def _DecideSelfPromotion(lu, exceptions=None):
@@ -829,6 +829,9 @@ class LUNodeSetParams(LogicalUnit):
 
     # this will trigger configuration file update, if needed
     self.cfg.Update(node, feedback_fn)
+    master_node = self.cfg.GetMasterNode()
+    potential_master_candidates = self.cfg.GetPotentialMasterCandidates()
+    modify_ssh_setup = self.cfg.GetClusterInfo().modify_ssh_setup
 
     if self.new_role != self.old_role:
       new_flags = self._R2F[self.new_role]
@@ -849,7 +852,9 @@ class LUNodeSetParams(LogicalUnit):
 
       # we locked all nodes, we adjust the CP before updating this node
       if self.lock_all:
-        AdjustCandidatePool(self, [node.uuid])
+        AdjustCandidatePool(
+            self, [node.uuid], master_node, potential_master_candidates,
+            feedback_fn, modify_ssh_setup)
 
       # if node gets promoted, grant RPC priviledges
       if self.new_role == self._ROLE_CANDIDATE:
@@ -865,9 +870,7 @@ class LUNodeSetParams(LogicalUnit):
     if [self.old_role, self.new_role].count(self._ROLE_CANDIDATE) == 1:
       self.context.ReaddNode(node)
 
-      if self.cfg.GetClusterInfo().modify_ssh_setup:
-        potential_master_candidates = self.cfg.GetPotentialMasterCandidates()
-        master_node = self.cfg.GetMasterNode()
+      if modify_ssh_setup:
         if self.old_role == self._ROLE_CANDIDATE:
           master_candidate_uuids = self.cfg.GetMasterCandidateUuids()
           ssh_result = self.rpc.call_node_ssh_key_remove(
@@ -885,16 +888,8 @@ class LUNodeSetParams(LogicalUnit):
           WarnAboutFailedSshUpdates(ssh_result, master_node, feedback_fn)
 
         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,
-            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
-          ssh_result[master_node].Raise(
-            "Could not update the SSH setup of node '%s' after promotion"
-            " (UUID: %s)." % (node.name, node.uuid))
-          WarnAboutFailedSshUpdates(ssh_result, master_node, feedback_fn)
+          AddMasterCandidateSshKey(
+              self, master_node, node, potential_master_candidates, feedback_fn)
 
     return result
 
@@ -1593,7 +1588,9 @@ class LUNodeRemove(LogicalUnit):
       WarnAboutFailedSshUpdates(result, master_node, feedback_fn)
 
     # Promote nodes to master candidate as needed
-    AdjustCandidatePool(self, [self.node.uuid])
+    AdjustCandidatePool(
+        self, [self.node.uuid], master_node, potential_master_candidates,
+        feedback_fn, modify_ssh_setup)
     self.context.RemoveNode(self.cfg, self.node)
 
     # Run post hooks on the node before it's removed