Friday, May 13, 2011

Fabric and Pageant

Here's an example of using Fabric with Pageant, the ssh key agent that comes with PuTTY.

We're using ssh keys in PuTTY (.ppk) format, not in OpenSSH format.

It's a long example, but the work of connecting to Pageant happens in the _start_pageant_and_store_key function.

# Regular Python imports
# Note: In the fabfile, don't do regular python imports like this
#from urllib import urlopen
# rather do them like this
#import urllib
# Any functions imported into this fabfile will be regarded as possible fabric
# tasks (in the example above, urlopen will show up when the user runs 'fab
# --list'), so instead of importing specific functions from modules, just import
# the whole module.
import os.path
import subprocess

# Import Fabric
from fabric.api import env
from fabric.api import run
from fabric.api import sudo

# To run the tasks defined in this file, use the 'fab' command line tool.
# cd \path\to\
# fab dev|prod task1 [task2]
# Note that you must specify dev or prod first, to set up the right server
# connection configuration.

# Constants
KEY_DIR = r'\path\to\keys'
PUTTY_DIR = r'C:\Program Files\PuTTY'

# These functions become tasks that can be executed from the command line using
# the 'fab' tool.
# Note: I couldn't find a more elegant way of specifying different connection
# parameters (such as key_filename) for each host, so I just made a 'dev' task
# and a 'prod' task.
def dev():
Set up for connection to the dev server
# Once DNS is set up for these hosts, I can use hostname instead of ip address
env.user = 'admin_user'
env.hosts = ['dev_server']

def prod():
Set up for connection to the prod server
env.user = 'admin_user'
env.hosts = ['prod_server']

def install_all_all():
Install everything to all servers

def install_all():
Does all the installation.
# Note: put actual installation steps here.

# These utility functions are the building blocks of the install process. The
# can also be called individually on the command line, using the 'fab' tool, and
# specifying the target host and values for the arguments.
def ps():
Prints a process listing
run('ps -ef')

def add_group(group_name):
Adds a linux user group.
# --force This option causes the command to simply exit with success
# status if the specified group already exists.
return sudo('groupadd --force %s' % group_name)

# These private python functions do not get exposed on the command line via the
# 'fab' tool. They will not show up when the user runs 'fab --list'
def _start_pageant_and_store_key(keyfile_name):
Starts the Pageant key agent, and loads the private key in to it, prompting
for the passphrase if needed. Also sets the Fabric env.keyfile_name
keyfile_path = os.path.join(KEY_DIR, keyfile_name)

# Start pageant. Note that this works with the PuTTY key format (*.ppk), not
# the OpenSSH format.
path_to_pageant = os.path.join(PUTTY_DIR, 'pageant.exe')
result =[path_to_pageant, keyfile_path])
if result > 0:
raise OSError, "Bad result %s" % result

# Store the path to the key file in fabric's global env dictionary
env.key_filename = keyfile_path

Thanks to Luka Marinko for his instructions for setting up syntax highlighting on Blogger.

No comments: