LGTM

On Wed, Jul 30, 2014 at 11:31 AM, 'Helga Velroyen' via ganeti-devel <
ganeti-devel@googlegroups.com> wrote:

> On adding a new node, a new public/private SSH key pair
> will be generated. The public key pair needs (possibly)
> to be added to the 'ganeti_pub_keys' file and the
> 'authorized_keys' file of other cluster nodes. This patch
> provides the mechanism to fetch the new node's public
> SSH key via ssh. Node that at this point, no new
> public/private key pair is generated yet. This will come
> in a later patch of this series as we first want to have
> all infrastructure in place.
>
> Signed-off-by: Helga Velroyen <hel...@google.com>
> ---
>  lib/client/gnt_node.py | 51
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
>
> diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py
> index d77d031..264c07b 100644
> --- a/lib/client/gnt_node.py
> +++ b/lib/client/gnt_node.py
> @@ -40,6 +40,7 @@ from ganeti import netutils
>  from ganeti import pathutils
>  from ganeti import ssh
>  from ganeti import compat
> +from ganeti import ssconf
>
>  from ganeti import confd
>  from ganeti.confd import client as confd_client
> @@ -183,6 +184,47 @@ def _ReadSshKeys(keyfiles, _tostderr_fn=ToStderr):
>    return result
>
>
> +def _ReadRemoteSshPubKeys(keyfiles, node, cluster_name, port, ask_key,
> +                          strict_host_check, _tosterr_fn=ToStderr):
> +  """Fetches the public SSH keys from a node via SSH.
> +
> +  @type keyfiles: dict from string to (string, string) tuples
> +  @param keyfiles: a dictionary mapping the type of key (e.g. rsa, dsa)
> to a
> +    tuple consisting of the file name of the private and public key
> +
> +  """
> +  family = ssconf.SimpleStore().GetPrimaryIPFamily()
> +  ssh_runner = ssh.SshRunner(cluster_name,
> +                             ipv6=(family == netutils.IP6Address.family))
> +
> +  failed_results = {}
> +  fetched_keys = {}
> +  for (kind, (_, public_key_file)) in keyfiles.items():
> +    cmd = ["cat", public_key_file]
> +    ssh_cmd = ssh_runner.BuildCmd(node, constants.SSH_LOGIN_USER,
> +                                  utils.ShellQuoteArgs(cmd),
> +                                  batch=False, ask_key=ask_key,
> quiet=False,
> +                                  strict_host_check=strict_host_check,
> +                                  use_cluster_key=False,
> +                                  port=port)
> +
> +    result = utils.RunCmd(ssh_cmd)
> +    if result.failed:
> +      failed_results[kind] = (result.cmd, result.fail_reason)
> +    else:
> +      fetched_keys[kind] = result.stdout
> +
> +  if len(fetched_keys.keys()) < 1:
> +    error_msg = "Could not fetch any public SSH key."
> +    for (kind, (cmd, fail_reason)) in failed_results.items():
> +      error_msg += "Could not fetch the public '%s' SSH key from node
> '%s':" \
> +                   " ran command '%s', failure reason: '%s'. " % \
> +                   (kind, node, cmd, fail_reason)
> +    raise errors.OpPrereqError(error_msg)
> +
> +  return fetched_keys
> +
> +
>  def _SetupSSH(options, cluster_name, node, ssh_port, cl):
>    """Configures a destination node's SSH daemon.
>
> @@ -232,6 +274,15 @@ def _SetupSSH(options, cluster_name, node, ssh_port,
> cl):
>                              options.ssh_key_check, options.ssh_key_check,
>                              ssh_port, data)
>
> +  fetched_keys = _ReadRemoteSshPubKeys(root_keyfiles, node, cluster_name,
> +                                       ssh_port, options.ssh_key_check,
> +                                       options.ssh_key_check)
> +  for pub_key in fetched_keys.values():
> +    # Unfortunately, we have to add the key with the node name rather than
> +    # the node's UUID here, because at this point, we do not have a UUID
> yet.
> +    # The entry will be corrected in noded later.
> +    ssh.AddPublicKey(node, pub_key)
> +
>
>  @UsesRPC
>  def AddNode(opts, args):
> --
> 2.0.0.526.g5318336
>
>

Reply via email to