Usage

A small example of schneider in combination with fabric to execute a command on a remote host. You need fabric for this.

import os
import sys

import schneider.agent
import schneider.manager

import fabric


def main():
    # prepare an agent with a key; you will be asked for a passphrase
    # if the key is encrypted
    agent = schneider.agent.SSHAgent("my_agent")
    agent.create()
    agent.add_key("~/.ssh/keys/my_key")

    # create a manager instance and let is manage the agent
    manager = schneider.manager.Manager()
    manager.add_agent(agent)

    # activate the agent and connect to a server
    manager.activate_agent(agent.name)
    conn = fabric.Connection("my_server")
    result = conn.run("uname -a")
    conn.close()

    # cleanup
    manager.deactivate_agent(agent.name)
    manager.del_agent(agent.name)

    msg = "Ran {0.command!r} on {0.connection.host}, got stdout:\n{0.stdout}"
    print(msg.format(result))


if __name__ == "__main__":
    main()

schneider provides a decorator as a shortcut:

class schneider.Agent(host)[source]

Decorator class.

The Agent decorator takes the name of an entry in your ~/.ssh/conf. It looks for an assigned keyfile and creates a new agent and a manager that takes care of it.

@Agent("prokyon")
def ping(msg):
    print("pinging proykon with", msg)


ping("hallo")
ping("welt")

Classes

class schneider.agent.SSHAgent(name, base_path='~/.ssh')[source]

SSH Agent class

Manages an associated ssh-agent process and kann add keys to it.

Example:

agent = schneider.agent.SSHAgent("my_agent")
agent.create()
agent.add_key("~/.ssh/keys/my_key")
add_key(path)[source]

Add a new key to the ssh-agent process.

create()[source]

Create a new ssh agent process.

If the ssh-agent creation raises a SubprocessError, the method prints an error message and exits with returncode 1.

Returns:

functional Agent instance

destroy()[source]

Destroy the related ssh-agent process.

Will be called automatically at instance deletion.

env()[source]

Return the environment variables for this ssh-agent process.

Raises AgentNotCreated if no ssh-agent was created before.

Returns:

Dictionary with SSH_AUTH_SOCK and SSH_AGENT_PID

Return type:

dict

class schneider.manager.Manager[source]

Manager for SSHAgent instances.

Example:

# create a agent
agent = schneider.agent.SSHAgent("test-agent")
agent.create()
# add keys, other agents ...

# create a manager
manager = schneider.manager.Manager()

# add agent(s) to manager
manager.add_agent(agent)

# activate a manager by name
manager.activate_agent(agent.name)

# use paramiko, fabric etc.

# deactivate agent (=restores the previous environment)
manager.deactive_agent(agent.name)

# delete agent(s)
manager.del_agent(agent.name)
activate_agent(agent_name)[source]

Activate the environment of the given agent.

Raises UnkownAgent if the given agent name is unknown.

Param:

agent_name - name of agent to use

add_agent(agent)[source]

Add an agent instance.

Param:

agent - agent instance

deactivate_agent(agent_name)[source]

Deactive the environment of the given agent.

Raises UnkownAgent if the given agent name is unknown.

Param:

agent_name - name of the agent to use

del_agent(agent_name)[source]

Delete agent from manager.

Param:

agent_name - name of agent to delete

Helper Functions

SSH configuration file parser

Uses paramiko’s file parser and provides some convenience functions.

Example:

import schneider.config


hostname = "my_host"

# use default path
config = schneider.config.parse()

# check ifget entry for the defined hostname if defined
if not hostname in config.get_hostnames():
    print("error: unknown host", hostname)
else:        
    # get its address
    address = config.lookup(hostname)["hostname"]
    # alternative: schneider.config.get_address(config, hostname)

    # multiple identity files are allowed, so this is a list
    keyfile = config.lookup(hostname)["identityfile"][0]
    # alternative: schneider.config.get_keyfile(config, hostname)

    # now use address and keyfile to create a new agent
exception schneider.config.HostNotFound[source]

Host not found in local SSH config

exception schneider.config.NoKeyFile[source]

Host entry has no keyfile

schneider.config.get_address(ssh_config, hostname)[source]

Get address of given host.

Exception:

HostNotFound

Param:

ssh_config - SSH object returned by parse

Param:

hostname - Name of the config file entry

Returns:

host address

schneider.config.get_keyfile(ssh_config, hostname)[source]

Get the first keyfile from given host, if any.

Exception:

HostNotFound, NoKeyFile

Param:

ssh_config - SSH object returned by parse

Param:

hostname - Name of the config entry

Returns:

first keyfile path

schneider.config.parse(path='~/.ssh/config')[source]

Parse the given SSH config file; defaults to ~/.ssh/config.

Param:

path - path to local SSH config file

Returns:

SSHConfig instance