web-dev-qa-db-fra.com

Connexion à un hôte répertorié dans ~ / .ssh / config lors de l'utilisation de Fabric

J'ai des problèmes avec Fabric ne reconnaissant pas les hôtes que j'ai dans ~/.ssh/config.

Ma fabfile.py est comme suit:

from fabric.api import run, env

env.hosts = ['lulu']

def whoami():
    run('whoami')

Fonctionnement $ fab whoami donne:

[lulu] run: whoami

Erreur fatale: la recherche de nom a échoué pour Lulu

Le nom lulu est dans mon ~/.ssh/config, comme ça:

Host lulu
     hostname 192.168.100.100
     port 2100
     IdentityFile ~/.ssh/lulu-key

Ma première pensée pour résoudre ce problème est d'ajouter quelque chose comme lulu.lulu à /etc/hosts (Je suis sur un Mac), mais je dois également transmettre le fichier d'identité à Fabric - et je préfère garder mon authentification (c'est-à-dire ~/.ssh/config) distinct de mon déploiement (c'est-à-dire fabfile.py).

De plus, accessoirement, si vous essayez de vous connecter à un hôte dans le fichier hosts, fabric.contrib.projects.rsync_project ne semble pas reconnaître les "ports" dans le hosts.env (c'est-à-dire si vous utilisez hosts.env = [lulu:2100] un appel à rsync_project semble essayer de se connecter à lulu:21).

Y a-t-il une raison pour laquelle Fabric ne reconnaît pas ce nom lulu?

83
Brian M. Hunt

Depuis la version 1.4.0, Fabric utilise votre configuration ssh (en partie). Cependant, vous devez l'activer explicitement, avec

env.use_ssh_config = True

quelque part près du haut de votre fabfile. Une fois cette opération effectuée, Fabric devrait lire votre configuration ssh (à partir de ~/.ssh/config par défaut, ou à partir de env.ssh_config_path).

Un avertissement: si vous utilisez une version antérieure à 1.5.4, un abandon se produira si env.use_ssh_config est défini mais aucun fichier de configuration n'est présent. Dans ce cas, vous pouvez utiliser une solution de contournement comme:

if env.ssh_config_path and os.path.isfile(os.path.expanduser(env.ssh_config_path)):
    env.use_ssh_config = True
143
rbp

Notez que cela se produit également lorsque le nom n'est pas dans /etc/hosts. J'ai eu le même problème et j'ai dû ajouter le nom d'hôte à ce fichier et ~/.ssh/config.

9
MrD

mise à jour : Cette réponse est désormais obsolète .


Fabric ne prend actuellement pas en charge le fichier .ssh/config. Vous pouvez les paramétrer dans une fonction pour ensuite appeler le cli, par exemple: fab production task; où la production définit le nom d'utilisateur, le nom d'hôte, le port et l'identité ssh.

En ce qui concerne le projet rsync, qui devrait maintenant avoir la possibilité de définir le port, sinon, vous pouvez toujours exécuter local ("rsync ...") car c'est essentiellement ce que fait cette fonction.

5
Morgan

On peut utiliser le code suivant pour lire la config (code original tiré de: http://markpasc.typepad.com/blog/2010/04/loading-ssh-config-settings-for-fabric.html =):

from fabric.api import *
env.hosts = ['servername']

def _annotate_hosts_with_ssh_config_info():
    from os.path import expanduser
    from paramiko.config import SSHConfig

    def hostinfo(Host, config):
        Hive = config.lookup(Host)
        if 'hostname' in Hive:
            Host = Hive['hostname']
        if 'user' in Hive:
            Host = '%s@%s' % (Hive['user'], Host)
        if 'port' in Hive:
            Host = '%s:%s' % (Host, Hive['port'])
        return Host

    try:
        config_file = file(expanduser('~/.ssh/config'))
    except IOError:
        pass
    else:
        config = SSHConfig()
        config.parse(config_file)
        keys = [config.lookup(Host).get('identityfile', None)
            for Host in env.hosts]
        env.key_filename = [expanduser(key) for key in keys if key is not None]
        env.hosts = [hostinfo(Host, config) for Host in env.hosts]

        for role, rolehosts in env.roledefs.items():
            env.roledefs[role] = [hostinfo(Host, config) for Host in rolehosts]

_annotate_hosts_with_ssh_config_info()
4
jmu