Package ganeti :: Module ssh
[hide private]
[frames] | no frames]

Module ssh

source code

Module encapsulating ssh functionality.

Classes [hide private]
  SshRunner
Wrapper for SSH commands.
Functions [hide private]
tuple; (string, string, string)
GetUserFiles(user, mkdir=False, dircheck=True, kind=constants.SSHK_DSA, _homedir_fn=None)
Return the paths of a user's SSH files.
source code
tuple; (string, dict with string as key, tuple of (string, string) as value)
GetAllUserFiles(user, mkdir=False, dircheck=True, _homedir_fn=None)
Wrapper over GetUserFiles to retrieve files for all SSH key types.
source code
tuple
_SplitSshKey(key)
Splits a line for SSH's authorized_keys file.
source code
 
AddAuthorizedKeys(file_obj, keys)
Adds a list of SSH public key to an authorized_keys file.
source code
 
HasAuthorizedKey(file_obj, key)
Check if a particular key is in the 'authorized_keys' file.
source code
 
CheckForMultipleKeys(file_obj, node_names)
Check if there is at most one key per host in 'authorized_keys' file.
source code
 
AddAuthorizedKey(file_obj, key)
Adds an SSH public key to an authorized_keys file.
source code
 
RemoveAuthorizedKeys(file_name, keys)
Removes public SSH keys from an authorized_keys file.
source code
 
RemoveAuthorizedKey(file_name, key)
Removes an SSH public key from an authorized_keys file.
source code
(boolean, string)
_AddPublicKeyProcessLine(new_uuid, new_key, line_uuid, line_key, found)
Processes one line of the public key file when adding a key.
source code
string
_AddPublicKeyElse(new_uuid, new_key)
Adds a new SSH key to the key file if it did not exist already.
source code
(boolean, string)
_RemovePublicKeyProcessLine(target_uuid, _target_key, line_uuid, line_key, found)
Processes a line in the public key file when aiming for removing a key.
source code
string
_RemovePublicKeyElse(target_uuid, _target_key)
Logs when we tried to remove a key that does not exist.
source code
(boolean, string)
_ReplaceNameByUuidProcessLine(node_name, _key, line_identifier, line_key, found, node_uuid=None)
Replaces a node's name with its UUID on a matching line in the key file.
source code
string
_ReplaceNameByUuidElse(node_uuid, node_name, _key)
Logs a debug message when we try to replace a key that is not there.
source code
tuple (string, string)
_ParseKeyLine(line, error_fn)
Parses a line of the public key file.
source code
 
_ManipulatePubKeyFile(target_identifier, target_key, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError, process_line_fn=None, process_else_fn=None)
Manipulates the list of public SSH keys of the cluster.
source code
 
AddPublicKey(new_uuid, new_key, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError)
Adds a new key to the list of public keys.
source code
 
RemovePublicKey(target_uuid, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError)
Removes a key from the list of public keys.
source code
 
ReplaceNameByUuid(node_uuid, node_name, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError)
Replaces a host name with the node's corresponding UUID.
source code
 
ClearPubKeyFile(key_file=pathutils.SSH_PUB_KEYS, mode=0600)
Resets the content of the public key file.
source code
 
OverridePubKeyFile(key_map, key_file=pathutils.SSH_PUB_KEYS)
Overrides the public key file with a list of given keys.
source code
dict mapping strings to list of strings
QueryPubKeyFile(target_uuids, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError)
Retrieves a map of keys for the requested node UUIDs.
source code
 
InitSSHSetup(key_type, key_bits, error_fn=errors.OpPrereqError, _homedir_fn=None, _suffix="")
Setup the SSH configuration for the node.
source code
 
InitPubKeyFile(master_uuid, key_type, key_file=pathutils.SSH_PUB_KEYS)
Creates the public key file and adds the master node's SSH key.
source code
 
WriteKnownHostsFile(cfg, file_name)
Writes the cluster-wide equally known_hosts file.
source code
list of strings
_EnsureCorrectGanetiVersion(cmd)
Ensured the correct Ganeti version before running a command via SSH.
source code
 
RunSshCmdWithStdin(cluster_name, node, basecmd, port, data, debug=False, verbose=False, use_cluster_key=False, ask_key=False, strict_host_check=False, ensure_version=False)
Runs a command on a remote machine via SSH and provides input in stdin.
source code
 
ReadRemoteSshPubKey(pub_key_file, node, cluster_name, port, ask_key, strict_host_check)
Fetches a public SSH key from a node via SSH.
source code
tuple of (string, string)
GetSshKeyFilenames(key_type, suffix="")
Get filenames of the SSH key pair of the given type.
source code
string
GetSshPubKeyFilename(key_type, suffix="")
Get filename of the public SSH key of the given type.
source code
 
_ComputeKeyFilePathWithSuffix(key_filepath, suffix)
Converts the given key filename to a key filename with a suffix.
source code
 
ReplaceSshKeys(src_key_type, dest_key_type, src_key_suffix="", dest_key_suffix="")
Replaces an SSH key pair by another SSH key pair.
source code
list of string
ReadLocalSshPubKeys(key_types, suffix="")
Reads the local root user SSH key.
source code
positive int
DetermineKeyBits(key_type, key_bits, old_key_type, old_key_bits)
Checks the key bits to be used for a given key type, or provides defaults.
source code
Variables [hide private]
  KeyBitInfo = namedtuple('KeyBitInfo', ['default', 'validation_...
  SSH_KEY_VALID_BITS = {constants.SSHK_DSA: KeyBitInfo(1024, lam...

Imports: logging, os, shutil, tempfile, namedtuple, partial, utils, errors, constants, netutils, pathutils, vcluster, compat, serializer, ssconf


Function Details [hide private]

GetUserFiles(user, mkdir=False, dircheck=True, kind=constants.SSHK_DSA, _homedir_fn=None)

source code 

Return the paths of a user's SSH files.

Parameters:
  • user (string) - Username
  • mkdir (bool) - Whether to create ".ssh" directory if it doesn't exist
  • dircheck (bool) - Whether to check if ".ssh" directory exists
  • kind (string) - One of constants.SSHK_ALL
Returns: tuple; (string, string, string)
Tuple containing three file system paths; the private SSH key file, the public SSH key file and the user's authorized_keys file
Raises:
  • errors.OpExecError - When home directory of the user can not be determined
  • errors.OpExecError - Regardless of the mkdir parameters, this exception is raised if ~$user/.ssh is not a directory and dircheck is set to True

GetAllUserFiles(user, mkdir=False, dircheck=True, _homedir_fn=None)

source code 

Wrapper over GetUserFiles to retrieve files for all SSH key types.

See GetUserFiles for details.

Returns: tuple; (string, dict with string as key, tuple of (string, string) as value)

_SplitSshKey(key)

source code 

Splits a line for SSH's authorized_keys file.

If the line has no options (e.g. no command="..."), only the significant parts, the key type and its hash, are used. Otherwise the whole line is used (split at whitespace).

Parameters:
  • key (string) - Key line
Returns: tuple

AddAuthorizedKeys(file_obj, keys)

source code 

Adds a list of SSH public key to an authorized_keys file.

Parameters:
  • file_obj (str or file handle) - path to authorized_keys file
  • keys (list of str) - list of strings containing keys

HasAuthorizedKey(file_obj, key)

source code 

Check if a particular key is in the 'authorized_keys' file.

Parameters:
  • file_obj (str or file handle) - path to authorized_keys file
  • key (str) - string containing key

CheckForMultipleKeys(file_obj, node_names)

source code 

Check if there is at most one key per host in 'authorized_keys' file.

Parameters:
  • file_obj (str or file handle) - path to authorized_keys file
  • node_names (list of str) - list of names of nodes of the cluster
Returns:
a dictionary with hostnames which occur more than once

AddAuthorizedKey(file_obj, key)

source code 

Adds an SSH public key to an authorized_keys file.

Parameters:
  • file_obj (str or file handle) - path to authorized_keys file
  • key (str) - string containing key

RemoveAuthorizedKeys(file_name, keys)

source code 

Removes public SSH keys from an authorized_keys file.

Parameters:
  • file_name (str) - path to authorized_keys file
  • keys (list of str) - list of strings containing keys

RemoveAuthorizedKey(file_name, key)

source code 

Removes an SSH public key from an authorized_keys file.

Parameters:
  • file_name (str) - path to authorized_keys file
  • key (str) - string containing key

_AddPublicKeyProcessLine(new_uuid, new_key, line_uuid, line_key, found)

source code 

Processes one line of the public key file when adding a key.

This is a sub function that can be called within the _ManipulatePublicKeyFile function. It processes one line of the public key file, checks if this line contains the key to add already and if so, notes the occurrence in the return value.

Parameters:
  • new_uuid (string) - the node UUID of the node whose key is added
  • new_key (string) - the SSH key to be added
  • line_key - the SSH key of the node whose line in the public key file is processed in this function call
  • found (boolean) - whether or not the (UUID, key) pair of the node whose key is being added was found in the public key file already.
  • line_uuid (the UUID of the node whose line in the public key file is processed in this function call)
Returns: (boolean, string)
a possibly updated value of found and the processed line

_AddPublicKeyElse(new_uuid, new_key)

source code 

Adds a new SSH key to the key file if it did not exist already.

This is an auxiliary function for _ManipulatePublicKeyFile which is carried out when a new key is added to the public key file and after processing the whole file, we found out that the key does not exist in the file yet but needs to be appended at the end.

Parameters:
  • new_uuid (string) - the UUID of the node whose key is added
  • new_key (string) - the SSH key to be added
Returns: string
a new line to be added to the file

_RemovePublicKeyProcessLine(target_uuid, _target_key, line_uuid, line_key, found)

source code 

Processes a line in the public key file when aiming for removing a key.

This is an auxiliary function for _ManipulatePublicKeyFile when we are removing a key from the public key file. This particular function only checks if the current line contains the UUID of the node in question and writes the line to the temporary file otherwise.

Parameters:
  • target_uuid (string) - UUID of the node whose key is being removed
  • _target_key (string) - SSH key of the node (not used)
  • line_uuid (string) - UUID of the node whose line is processed in this call
  • line_key (string) - SSH key of the nodes whose line is processed in this call
  • found (boolean) - whether or not the UUID was already found.
Returns: (boolean, string)
a tuple, indicating if the target line was found and the processed line; the line is 'None', if the original line is removed

_RemovePublicKeyElse(target_uuid, _target_key)

source code 

Logs when we tried to remove a key that does not exist.

This is an auxiliary function for _ManipulatePublicKeyFile which is run after we have processed the complete public key file and did not find the key to be removed.

Parameters:
  • target_uuid (string) - the UUID of the node whose key was supposed to be removed
  • _target_key (string) - the key of the node which was supposed to be removed (not used)
Returns: string
in this case, always None

_ReplaceNameByUuidProcessLine(node_name, _key, line_identifier, line_key, found, node_uuid=None)

source code 

Replaces a node's name with its UUID on a matching line in the key file.

This is an auxiliary function for _ManipulatePublicKeyFile which processes a line of the ganeti public key file. If the line in question matches the node's name, the name will be replaced by the node's UUID.

Parameters:
  • node_name (string) - name of the node to be replaced by the UUID
  • _key (string) - SSH key of the node (not used)
  • line_identifier (string) - an identifier of a node in a line of the public key file. This can be either a node name or a node UUID, depending on if it got replaced already or not.
  • line_key (string) - SSH key of the node whose line is processed
  • found (boolean) - whether or not the line matches the node's name
  • node_uuid (string) - the node's UUID which will replace the node name
Returns: (boolean, string)
a tuple indicating whether the target line was found and the processed line

_ReplaceNameByUuidElse(node_uuid, node_name, _key)

source code 

Logs a debug message when we try to replace a key that is not there.

This is an implementation of the auxiliary process_else_fn function for the _ManipulatePubKeyFile function when we use it to replace a line in the public key file that is indexed by the node's name instead of the node's UUID.

Parameters:
  • node_uuid (string) - the node's UUID
  • node_name (string) - the node's UUID
  • _key (string (not used)) - the node's SSH key (not used)
Returns: string
in this case, always None

_ParseKeyLine(line, error_fn)

source code 

Parses a line of the public key file.

Parameters:
  • line (string) - line of the public key file
  • error_fn (function) - function to process error messages
Returns: tuple (string, string)
a tuple containing the UUID of the node and a string containing the SSH key and possible more parameters for the key

_ManipulatePubKeyFile(target_identifier, target_key, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError, process_line_fn=None, process_else_fn=None)

source code 

Manipulates the list of public SSH keys of the cluster.

This is a general function to manipulate the public key file. It needs two auxiliary functions process_line_fn and process_else_fn to work. Generally, the public key file is processed as follows: 1) The function processes each line of the original ganeti public key file, applies the process_line_fn function on it, which returns a possibly manipulated line and an indicator whether the line in question was found. If a line is returned, it is added to a list of lines for later writing to the file. 2) If all lines are processed and the 'found' variable is False, the seconds auxiliary function process_else_fn is called to possibly add more lines to the list of lines. 3) Finally, the list of lines is assembled to a string and written atomically to the public key file, thereby overriding it.

If the public key file does not exist, we create it. This is necessary for a smooth transition after an upgrade.

Parameters:
  • target_identifier (str) - identifier of the node whose key is added; in most cases this is the node's UUID, but in some it is the node's host name
  • target_key (str) - string containing a public SSH key (a complete line possibly including more parameters than just the key)
  • key_file (str) - filename of the file of public node keys (optional parameter for testing)
  • error_fn (function) - Function that returns an exception, used to customize exception types depending on the calling context
  • process_line_fn (function) - function to process one line of the public key file
  • process_else_fn (function) - function to be called if no line of the key file matches the target uuid

AddPublicKey(new_uuid, new_key, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError)

source code 

Adds a new key to the list of public keys.

See Also: _ManipulatePubKeyFile for parameter descriptions.

RemovePublicKey(target_uuid, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError)

source code 

Removes a key from the list of public keys.

See Also: _ManipulatePubKeyFile for parameter descriptions.

ReplaceNameByUuid(node_uuid, node_name, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError)

source code 

Replaces a host name with the node's corresponding UUID.

When a node is added to the cluster, we don't know it's UUID yet. So first its SSH key gets added to the public key file and in a second step, the node's name gets replaced with the node's UUID as soon as we know the UUID.

Parameters:
  • node_uuid (string) - the node's UUID to replace the node's name
  • node_name (string) - the node's name to be replaced by the node's UUID

See Also: _ManipulatePubKeyFile for the other parameter descriptions.

OverridePubKeyFile(key_map, key_file=pathutils.SSH_PUB_KEYS)

source code 

Overrides the public key file with a list of given keys.

Parameters:
  • key_map (dict from str to list of str) - dictionary mapping uuids to lists of SSH keys

QueryPubKeyFile(target_uuids, key_file=pathutils.SSH_PUB_KEYS, error_fn=errors.ProgrammerError)

source code 

Retrieves a map of keys for the requested node UUIDs.

Parameters:
  • target_uuids (str or list of str) - UUID of the node to retrieve the key for or a list of UUIDs of nodes to retrieve the keys for
  • key_file (str) - filename of the file of public node keys (optional parameter for testing)
  • error_fn (function) - Function that returns an exception, used to customize exception types depending on the calling context
Returns: dict mapping strings to list of strings
dictionary mapping node uuids to their ssh keys

InitSSHSetup(key_type, key_bits, error_fn=errors.OpPrereqError, _homedir_fn=None, _suffix="")

source code 

Setup the SSH configuration for the node.

This generates a dsa keypair for root, adds the pub key to the permitted hosts and adds the hostkey to its own known hosts.

Parameters:
  • key_type - the type of SSH keypair to be generated
  • key_bits - the key length, in bits, to be used

InitPubKeyFile(master_uuid, key_type, key_file=pathutils.SSH_PUB_KEYS)

source code 

Creates the public key file and adds the master node's SSH key.

Parameters:
  • master_uuid (str) - the master node's UUID
  • key_type (one of constants.SSHK_ALL) - the type of ssh key to be used
  • key_file (str) - name of the file containing the public keys

_EnsureCorrectGanetiVersion(cmd)

source code 

Ensured the correct Ganeti version before running a command via SSH.

Before a command is run on a node via SSH, it makes sense in some situations to ensure that this node is indeed running the correct version of Ganeti like the rest of the cluster.

Parameters:
  • cmd (string) - string
Returns: list of strings
a list of commands with the newly added ones at the beginning

RunSshCmdWithStdin(cluster_name, node, basecmd, port, data, debug=False, verbose=False, use_cluster_key=False, ask_key=False, strict_host_check=False, ensure_version=False)

source code 

Runs a command on a remote machine via SSH and provides input in stdin.

Parameters:
  • cluster_name (string) - Cluster name
  • node (string) - Node name
  • basecmd (string) - Base command (path on the remote machine)
  • port (int) - The SSH port of the remote machine or None for the default
  • data - JSON-serializable input data for script (passed to stdin)
  • debug (bool) - Enable debug output
  • verbose (bool) - Enable verbose output
  • use_cluster_key (bool) - See ssh.SshRunner.BuildCmd
  • ask_key (bool) - See ssh.SshRunner.BuildCmd
  • strict_host_check (bool) - See ssh.SshRunner.BuildCmd

ReadRemoteSshPubKey(pub_key_file, node, cluster_name, port, ask_key, strict_host_check)

source code 

Fetches a public SSH key from a node via SSH.

Parameters:
  • pub_key_file (string) - a tuple consisting of the file name of the public DSA key

GetSshKeyFilenames(key_type, suffix="")

source code 

Get filenames of the SSH key pair of the given type.

Parameters:
  • key_type (string) - type of SSH key, must be element of constants.SSHK_ALL
  • suffix (string) - optional suffix for the key filenames
Returns: tuple of (string, string)
a tuple containing the name of the private key file and the public key file.

GetSshPubKeyFilename(key_type, suffix="")

source code 

Get filename of the public SSH key of the given type.

Parameters:
  • key_type (string) - type of SSH key, must be element of constants.SSHK_ALL
  • suffix (string) - optional suffix for the key filenames
Returns: string
file name of the public key file

_ComputeKeyFilePathWithSuffix(key_filepath, suffix)

source code 

Converts the given key filename to a key filename with a suffix.

Parameters:
  • key_filepath (string) - path of the key file
  • suffix (string) - suffix to be appended to the basename of the file

ReplaceSshKeys(src_key_type, dest_key_type, src_key_suffix="", dest_key_suffix="")

source code 

Replaces an SSH key pair by another SSH key pair.

Note that both parts, the private and the public key, are replaced.

Parameters:
  • src_key_type (string) - key type of key pair that is replacing the other key pair
  • dest_key_type (string) - key type of the key pair that is being replaced by the source key pair
  • src_key_suffix (string) - optional suffix of the key files of the source key pair
  • dest_key_suffix (string) - optional suffix of the keey files of the destination key pair

ReadLocalSshPubKeys(key_types, suffix="")

source code 

Reads the local root user SSH key.

Parameters:
  • key_types (list of string) - types of SSH keys. Must be subset of constants.SSHK_ALL. If 'None' or [], all available keys are returned.
  • suffix (string) - optional suffix to be attached to key names when reading them. Used for temporary key files.
Returns: list of string
list of public keys

DetermineKeyBits(key_type, key_bits, old_key_type, old_key_bits)

source code 

Checks the key bits to be used for a given key type, or provides defaults.

Parameters:
  • key_type (one of constants.SSHK_ALL) - The key type to use.
  • key_bits (positive int or None) - The number of bits to use, if supplied by user.
  • old_key_type (one of constants.SSHK_ALL or None) - The previously used key type, if any.
  • old_key_bits (positive int or None) - The previously used number of bits, if any.
Returns: positive int
The number of bits to use.

Variables Details [hide private]

KeyBitInfo

Value:
namedtuple('KeyBitInfo', ['default', 'validation_fn'])

SSH_KEY_VALID_BITS

Value:
{constants.SSHK_DSA: KeyBitInfo(1024, lambda b: b== 1024), constants.S\
SHK_RSA: KeyBitInfo(2048, lambda b: b >= 768), constants.SSHK_ECDSA: K\
eyBitInfo(384, lambda b: b in [256, 384, 521]),}