Commits

Garth Johnson  committed aef8d8d

First stage new deployment process

  • Participants
  • Parent commits 42e6667

Comments (0)

Files changed (2)

File djaboto/aws.py

 # -*- coding: utf-8 -*-
-import optparse
 import os, sys
 from os.path import isfile
-from time import sleep
-from fabric import operations as fab_op
-from fabric import api as fab_api
-from fabric import colors as fab_colors
-from fabric.contrib.files import exists as fab_exists
-from fabric.contrib.files import append as fab_append
 
-from boto import config as BotoConfig, ec2, exception as BotoException
+import time
+import fabric
+import boto
 
 from urllib import urlencode
 from urllib2 import Request
 from urllib2 import urlopen
-
 from base64 import b64encode
 import json
-from django.core.management.base import BaseCommand
-import djaboto
 from django.conf import settings
-
 from getpass import getuser
 
-PROJECT_TEMPLATES_DIR = os.path.join(os.path.dirname(djaboto.__file__), 'recipe')
-
-###TODO: move all references to the target and source directories to a dynamic variable instead of hardcoded
-###TODO: allow for commandline overrides of target and source directories
-###TODO: streamline the sub-commands down to one or two that automatically perform all of the steps dynamically and 'as-needed'/specified
-
-AWS_SETTINGS_PROMPTS = {
-    'SITENAME':('Site name',''),
-    'AWS_INSTANCE_ID':('AWS instance ID',''),
-    'AWS_ACCESS_KEY_ID':('AWS Security Credentials, Access Key ID',''),
-    'AWS_ACCESS_SECRET':('AWS Security Credentials, Secret Access Key',''),
-    'AWS_REGION':('Amazon Region','us-west-1'),
-    'AWS_TYPE':('Amazon Instance Type','t1.micro'),
-    'AWS_AMI_ID':('AMI ID','ami-87712ac2'),
-    'AWS_USER':('Instance default username','ubuntu'),
-    'AWS_HTTPD_USER':('Apache user','www-data'),
-    'AWS_HTTPD_GROUP':('Apache group','www-data'),
-}
 
 
-#################################################################
-def handle(self, *args, **options):
+def get_awsConnection(region=None, aws_key=None, aws_secret=None):
     """
-    Command argument processor
+    Get the connection object for the configured AWS account
+    Returns: connection object
     """
 
-    reboot=False
-    restart=False
-
-    # Parse the options and make any settings changes as needed
-    if options.get('sitename', None):
-        fab_api.env['SITENAME'] = options['sitename']
-        fab_api.env['unsaved'] = True
-    if options.get('git_repo', False):
-        fab_api.env['git_repo'] = options['git_repo']
-    else:
-        fab_api.env['git_repo'] = False
-    fab_api.env['rcfile'] = options.get('fabricrc', './.aws_fabric')
-
-    ###TODO: this should be yanked and replaced with a boto config file solution instead
-    rcfile = options.get('fabricrc', None)
-    if rcfile:
-        rcfile = os.path.abspath(rcfile)
-    else:
-        rcfile = os.path.abspath(os.path.join(os.getcwd(),'.aws_fabric'))
-
-    fab_api.env['rcfile'] = rcfile
+    if not region:
+        region = fabric.api.env.get('aws_default_region','us-west-1')
 
-    ssh_pubkey_file = options.get('aws_security_key', None)
-
-    # Load/set the settings
-    self.set_awsSettings()
-
-    # Parse the arguments
-    if len(args)==0:
-        self.get_awsInstanceList()
-        #self.cmd_awsManage(args, options)
-    else:
-        if 'instance' in args:
-            self.set_awsSSHKey()
-            self.get_awsInstance()
-        elif 'terminate' in args:
-            self.cmd_terminateInstance()
-        elif 'ip' in args:
-            self.cmd_getIP()
-        elif 'rmkey' in args:
-            self.cmd_rmKey()
-        elif 'addkey' in args:
-            self.cmd_addKey(ssh_pubkey_file)
-        elif 'keys' in args:
-            self.cmd_listKeys()
-        elif 'settings' in args:
-            self.list_awsSettings()
-        elif 'firewall' in args:
-            self.set_awsSecurityGroups()
-        elif 'create' in args:
-            self.set_awsSSHKey(ssh_pubkey_file)
-            self.set_awsSecurityGroups()
-            self.install_awsUbuntuUpgrades()
-            ###TODO: need to enable this as default, as soon as the function works safely
-            # self.set_awsElasticIP()
-            self.sync_awsProject(push=True)
-            self.install_awsPythonRequirements(reinstall=True)
-            ###TODO: DropDB needs to use the RDS Settings
-            self.aws_DropDB()
-            self.sync_awsDB()
-            self.sync_awsStaticfiles()
-            self.set_awsPermissions()
-            self.set_awsApacheconf(options.get('domain', None))
-            reboot=True
-        elif 'dropdb' in args:
-            self.aws_DropDB()
-            self.sync_awsDB()
-        elif 'update' in args:
-            if options.get('updateos', False):
-                self.install_awsUbuntuUpgrades()
-            self.sync_awsProject(push=options.get('awsoverwrite', False))
-            if options.get('updatepy', False):
-                self.install_awsPythonRequirements(reinstall=options.get('awsreinstall', False))
-            #self.sync_awsPurify() #we would only need this if we were moving the database back and forth
-            if options.get('initial', False):
-                self.aws_DropDB()
-            self.sync_awsDB()
-            if options.get('updatepy', False) or options.get('initial', False):
-                self.sync_awsStaticfiles()
-            if options.get('initial', False):
-                self.set_awsPermissions()
-                self.set_awsApacheconf(options.get('domain', None))
-            self.set_awsPermissions()
-        elif 'perms' in args:
-            self.set_awsPermissions()
-        elif 'apache' in args:
-            self.set_awsApacheconf(options.get('domain', None))
-        elif 'shell' in args:
-            self.cmd_awsShell()
-        elif 'dropdb' in args:
-            self.aws_DropDB()
-            self.sync_awsDB()
-        if reboot or 'reboot' in args or options.get('reboot', False):
-            self.cmd_awsReboot()
-        elif restart or 'restart' in args or options.get('restart', False):
-            self.sync_awsStaticfiles()
-            self.set_awsPermissions()
-            self.cmd_awsApacheRestart()
-
-#################################################################
-
-def set_awsSettings(self, path=None):
-    """
-    Load any settings found, or prompt for them.
-    """
+    ###TODO: get or prompt for 'aws_access_key_id'
+    if not aws_key:
+        aws_key = boto.config.get('Credentials','aws_access_key_id')
+    ###TODO: get or prompt for 'aws_secret_access_key'
+    if not aws_secret:
+        aws_secret = boto.config.get('Credentials','aws_secret_access_key')
 
-    if not path:
-        # If path is not specified, use the default
-        path = fab_api.env.rcfile
-
-    if os.path.exists(path):
-        # If the RC file exists, load it up
-        comments = lambda s: s and not s.startswith("#")
-        filesettings = filter(comments, open(path, 'r'))
-        settings_dict = dict((k.strip(), v.strip()) for k, _, v in
-            [s.partition('=') for s in filesettings])
-        fab_api.env.update(settings_dict)
-
-    # NOTE bugged me how the prompts where random, so i sorted them
-    for key, prompt_pair in sorted(AWS_SETTINGS_PROMPTS.items(), key=lambda x: x[0]):
-        question, default = prompt_pair
-        # only save the setting to file if it exists and has a value
-        # and allow for the fact that the instance may not exist yet.
-        if not key in fab_api.env and not key == 'AWS_INSTANCE_ID':
-            fab_api.prompt("%s :" % question, key, default)
-            fab_api.env['unsaved'] = True
-
-    fab_api.env['user'] = fab_api.env.AWS_USER
-
-    self.save_awsSettings()
-
-def list_awsSettings(self):
-    """
-    Shows settings related to AWS actions
-    """
-
-    print("-"*55)
-    print(fab_colors.yellow("AWS Instance Settings:"))
-    print("-"*55)
-    for setting in AWS_SETTINGS_PROMPTS:
-        if setting in fab_api.env:
-            if fab_api.env[setting]:
-                print("%55s : %-20s" % ( fab_colors.yellow(AWS_SETTINGS_PROMPTS[setting][0]), fab_colors.cyan( fab_api.env[setting])))
-    print("-"*55)
-    ###TODO: move all AWS settings to the boto config file, and site settings to settings.py - makes more sense that way
-    #print BotoConfig.getboolean('Boto','debug')
-    #print BotoConfig.get('Credentials','aws_access_key_id')
-
-
-def save_awsSettings(self, path=None):
-    """
-    Write the settings for AWS to file
-    """
-    if not path:
-        path = fab_api.env.rcfile
+    if not region or not aws_key or not aws_secret:
+        raise("Missing connection information, cannot continue.")
+        ###TODO: craft error message detailing the creation of boto config and fabric files
 
-    # Write these settings back to the fabric.env.rcfile only if needed
-    if fab_api.env.get('unsaved', False):
-
-        fab_api.env['unsaved'] = False
-        print(fab_colors.green("Saving settings to %s." % path))
+    # Create a connection to the AWS region of choice with our keys
+    from boto import ec2
+    conn = ec2.connect_to_region(
+        region_name             = region,
+        aws_access_key_id       = boto.config.get('Credentials','aws_access_key_id'),
+        aws_secret_access_key   = boto.config.get('Credentials','aws_secret_access_key'),
+        )
 
-        local_settings_file = open(path, "w")
-        local_settings_file.write("# This file was autocreated from Soupmix.\n")
-        local_settings_file.write("# Do not edit this file directly, all changes will be lost!\n")
-        for setting in AWS_SETTINGS_PROMPTS:
-            if setting in fab_api.env:
-                value = fab_api.env[setting] or ''
-                if value:
-                    local_settings_file.write("%s = %s\n" % (setting, value) )
+    if not conn:
+        raise Exception("No AWS Connection! Cannot continue!")
 
-        local_settings_file.close()
+    return conn
 
 
-def get_awsInstanceList(self):
+def get_awsInstanceList(region=None, aws_key=None, aws_secret=None):
     """
-    Lists all AWS instances in the account
+    Returns: all AWS instances in the account for the selected region
     """
 
-    self.get_awsConnection()
-
     instance_list = []
-    reservations = self.conn.get_all_instances()
+    conn = get_awsConnection(region, aws_key, aws_secret)
+
+    reservations = conn.get_all_instances()
 
     if reservations:
         for reservation in reservations:
             instances = reservation.instances
             for instance in instances:
-                print('%s) %s (%s-%s)\t%s (%s/%s/%s)\t%s (%s)' % (
-                    fab_colors.yellow(len(instance_list)),
-                    instance.id, instance.instance_type, instance.state,
-                    instance.image_id, instance.region.name, instance.architecture, instance.root_device_type,
-                    instance.public_dns_name, instance.ip_address,
-                    ))
                 instance_list += [instance]
-    else:
-        print("No instances found.")
 
     return instance_list
 
-def get_awsInstance(self,create=True):
+def get_awsInstance(region=None, aws_key=None, aws_secret=None, instance_id=None):
     """
-    Gets or creates an instance for AWS actions
-    """
-    if not self.instance:
-
-        self.get_awsConnection()
-
-        if 'AWS_INSTANCE_ID' in fab_api.env:
-            try:
-                self.instance = self.conn.get_all_instances(instance_ids=fab_api.env.AWS_INSTANCE_ID)[0].instances[0]
-            except:
-                pass
-                # Ya know what? If it is a bad ID, then lets just offer to change it!  ;)
-
-        # If no valid instance is pre-set then lets go get one!
-        if not self.instance:
-            # Show the existing instances
-            instance_list = self.get_awsInstanceList()
-
-            # If there are any, offer to select one
-            if instance_list:
-                fab_api.prompt('Select an existing instance or hit enter to create a new one:', 'instance_selection')
-                if fab_api.env.instance_selection:
-                    self.instance = instance_list[int(fab_api.env.instance_selection)]
-                    fab_api.env['AWS_INSTANCE_ID'] = self.instance.id
-                    print(fab_colors.green("%s selected." % (self.instance.id,)))
-                    fab_api.env['unsaved'] = True
-
-        # Nope.  No valid instance is selected, yet.  Time to create one then!
-        if not self.instance and create:
-            fab_api.warn('Creating new instance in the %s region with the %s image.' % (fab_api.env.AWS_REGION, fab_api.env.AWS_AMI_ID, ))
+    Get an instance for AWS actions based on configured instance ID
 
-            (keyid, keyvalue) = self.get_sshKey()
-
-            # Creates a server instance in your AWS account
-            reservation = self.conn.run_instances(
-                image_id= fab_api.env.AWS_AMI_ID,
-                instance_type=fab_api.env.AWS_TYPE,
-                key_name=keyid,
-                security_groups=['apache', 'developer',],
-                )
-
-            # Select the just-created instance
-            self.instance = reservation.instances[0]
-            fab_api.env['AWS_INSTANCE_ID'] = self.instance.id
-            print(fab_colors.green("Server instance %s created." % (self.instance.id,)))
-            fab_api.env['unsaved'] = True
-
-            # Give the instance a head start getting spun-up
-            sleep(60)
-
-
-        # Write the instance data to the local settings
-        self.save_awsSettings()
-
-    # Make sure that the instance has spun-up before continuing
-    while self.instance.state != 'running':
-        print fab_colors.yellow("Waiting for instance...")
-        sleep(5)
-        self.instance.update()
-        if self.instance.state == 'running':
-            print fab_colors.green("Instance %s is up!" % self.instance.id)
-
-    fab_api.env.host_string = self.instance.ip_address
-    return self.instance
-
-
-def set_awsElasticIP(self):
-    """
+    Returns: None if no ID is configured or the configured ID is invalid
+    Fabric: 'aws_instance' = instance ID
     """
-    ###TODO: TEST THIS BEFORE USING!!!  ..and add some error catching fer crying out loud!
-    ###TODO: check if there already is an elasticIP assigned to this instance before creating ANOTHER
-    ###TODO: check to see if even though an EIP exists, whether this instance still needs it (use options?)
-
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    elasticip = self.conn.allocate_address()
-    self.conn.associate_address(instance_id=instance.id , allocation_id=elasticip.allocation_id)
 
+    conn = get_awsConnection(region, aws_key, aws_secret)
+    instance = None
+    if not instance_id:
+        instance_id = fabric.api.env.get('aws_default_instance',None)
 
-def get_sshKey(self, keyfile=None):
 
-    if not keyfile:
-        # *********************
-
-        fab_api.env.host_string = 'localhost'
-        fab_api.env['user'] = getuser()
-        if not fab_exists('/%s/etc/ssh/id_rsa.pub' % settings.PROJECT_DIR):
-            if not fab_exists('%s/etc/ssh' % settings.PROJECT_DIR):
-                fab_api.run('mkdir -p %s/etc/ssh' % settings.PROJECT_DIR)
-            fab_api.run('ssh-keygen -f "%s/etc/ssh/id_rsa" -q -N "" -C "%s via AWS on %s"' % (settings.PROJECT_DIR, fab_api.env.AWS_USER, fab_api.env.SITENAME))
-        fab_api.env['host_string'] = None
-        fab_api.env['user'] = fab_api.env.AWS_USER
-
-        keyfile = os.path.abspath(os.path.join(settings.PROJECT_DIR, "etc", "ssh", "id_rsa.pub"))
-        privkey = os.path.abspath(os.path.join(settings.PROJECT_DIR, "etc", "ssh", "id_rsa"))
-
-    keyfile = os.path.expanduser(keyfile)
-
-    try:
-       kf = open(keyfile)
-    except IOError as e:
-        print fab_colors.red('Keyfile: %s does not exist!  Please specify a valid pubkey file with --sshpubkey=PATH_TO_SECURITY_KEY' % keyfile)
-        sys.exit(0)
-
-    keyvalue = kf.readline()
-    keyid = keyvalue.split()[-1].strip() # delimeter not always "== ", but always id is last text following final space
-    kf.close()
-    fab_api.env['key_filename'] = privkey
-    return (keyid, keyvalue)
-
-def set_awsSSHKey(self, keyfile=None):
-    """
-    Imports your local ssh pubkey into your AWS account
-    """
-    if keyfile:
+    # See if we already have an instance ID
+    if 'aws_default_instance' in fabric.api.env:
         try:
-            (keyid, keyvalue) = self.get_sshKey(keyfile)
+            instance = conn.get_all_instances(instance_ids=instance_id)[0].instances[0]
+            fabric.api.env['aws_instance'] = instance.id
         except:
-            raise Exception("SSH pubkey not found! Cannot continue!")
-
-    else:
-        (keyid, keyvalue) = self.get_sshKey()
-
-    self.get_awsConnection()
-
-    try:
-        try:
-            home = os.getenv('USERPROFILE') or os.getenv('HOME')
-            home_keyfile = os.path.abspath(os.path.join(home, ".ssh", "id_rsa.pub"))
-            kf = open(home_keyfile)
-            homekeyvalue = kf.readline()
-            homekeyid = homekeyvalue.split()[-1].strip() # delimeter not always "== ", but always id is last text following final space
-            kf.close()
-            keypairs = self.conn.get_all_key_pairs(keynames=[homekeyid,])
-        except IOError as e:
             pass
-    except BotoException.EC2ResponseError:
-        # Nope.  Not there!  Lets create it
-        self.conn.import_key_pair(keyid,keyvalue)
-        print(fab_colors.green("Key ID '%s' installed from %s." % (keyid, keyfile)))
-    else:
-        pass
-
-    # Import a security pub key for us to use ssh with
-    try:
-        # Look to see if it already exists first
-        keypairs = self.conn.get_all_key_pairs(keynames=[keyid,])
-    except BotoException.EC2ResponseError:
-        # Nope.  Not there!  Lets create it
-        self.conn.import_key_pair(keyid,keyvalue)
-        print(fab_colors.green("Key ID '%s' installed from %s." % (keyid, keyfile)))
-    else:
-        print(fab_colors.green("Key ID '%s' exists." % keyid))
-
-def set_awsSecurityGroups(self):
-    """
-    Creates necessary firewall security groups in your AWS account
-    """
-
-    self.get_awsConnection()
-
-    # Check security group for the webserver
-    try:
-        self.conn.get_all_security_groups(groupnames=['apache',])
-    except BotoException.EC2ResponseError:
-        # Create a security group for internet access to the webserver
-        web = self.conn.create_security_group('apache', 'Apache Security Group')
-        web.authorize('tcp', 80, 80, '0.0.0.0/0')
-        print(fab_colors.green("Apache firewall entry added."))
-    else:
-        print(fab_colors.green("Apache firewall entry exists."))
-
-    # Check security group for the developer access
-    try:
-        self.conn.get_all_security_groups(groupnames=['developer',])
-    except BotoException.EC2ResponseError:
-        # Create a security group for internet access to the test server and ssh
-        dev = self.conn.create_security_group('developer', 'Developer Security Group')
-        dev.authorize('tcp', 8000, 8000, '0.0.0.0/0')
-        dev.authorize('tcp', 22, 22, '0.0.0.0/0')
-        print(fab_colors.green("Developer firewall entry added."))
-    else:
-        print(fab_colors.green("Developer firewall entry exists."))
-
-def install_awsUbuntuUpgrades(self):
-    """
-    Installs the core components needed to run Django, Apache etc on Ubuntu
-    """
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-    print fab_api.env.host_string
-    print fab_api.env.key_filename
-
-
-    # Update all of the server and library components first
-    print(fab_colors.yellow("Checking OS for available updates..."))
-    fab_api.sudo('apt-get -y update')
-    fab_api.sudo('apt-get -y dist-upgrade')
 
-    # Install all of the server and library components
-    print(fab_colors.yellow("Checking OS for required packages..."))
-    fab_api.sudo('apt-get -y install python-setuptools python-dev python-virtualenv git mercurial gcc unison python-pip node-less libtidy-dev')
+    return instance
+# -------------------------------------------------------
 
-    # Install Apache and necesary components
-    fab_api.sudo('apt-get -y install apache2 libapache2-mod-wsgi')
 
-    # Install PIL support for Virtual Environment on 64 bit systems
-    fab_api.sudo('apt-get -y install python-imaging libjpeg62 libjpeg62-dev libjpeg8')
 
-    # Link the libraries so that PIL can find them
-    if not fab_exists('/usr/lib/libz.so'):
-        fab_api.sudo('ln -s  /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/')
-    if not fab_exists('/usr/lib/libjpeg.so'):
-        fab_api.sudo('ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib/')
 
-    # Instal MySQL components to system
-    fab_api.sudo('apt-get install -y mysql-server mysql-client python-mysqldb libmysqlclient-dev build-essential python-dev')
-    fab_api.sudo('apt-get -y install python-mysqldb')
 
-    # Clean up our mess and reduce system footprint on the HDD
-    fab_api.sudo('apt-get -y clean')
 
 
-    # Create the base directory
-    ###TODO: make this use a dynamic variable instead of hardcoded as it is
-    if not fab_exists('/home/%s/django' % fab_api.env.AWS_USER):
-        fab_api.run('mkdir /home/%s/django' % fab_api.env.AWS_USER)
-    if not fab_exists('/home/%s/django/cache' % fab_api.env.AWS_USER):
-        fab_api.run('mkdir /home/%s/django/cache' % fab_api.env.AWS_USER)
 
 
-def cmd_awsReboot(self):
+def select_awsInstance():
     """
-    Reboot the AWS server
+    Select an instance from a list of existing ones
+    Returns instance
+    Fabric: 'aws_instance' = instance ID
     """
 
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    print fab_colors.yellow("Rebooting instance...")
-    fab_api.sudo('reboot')
-    sleep(60)
-    while self.instance.state != 'running':
-        print fab_colors.yellow(self.instance.state)
-        sleep(5)
-        self.instance.update()
-
-def aws_DropDB(self):
-    """
-    Drop the database and recreate
-    """
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    with fab_api.settings(
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/python/bin/activate'),
-                        fab_api.prefix('source ~/django/%s/bin/remote_data.sh' % fab_api.env.SITENAME)):
-        fab_api.prompt('What is the server MySQL root password:', 'mysqlpwd')
-        fab_api.run('mysql --host=${RDS_HOSTNAME} -P3306 -u root -p%s -e "DROP DATABASE IF EXISTS django_$SITE;"' % fab_api.env.mysqlpwd)
-        fab_api.run('mysql --host=${RDS_HOSTNAME} -P3306 -u root -p%s -e "CREATE DATABASE django_$SITE;"' % fab_api.env.mysqlpwd)
-        fab_api.run('mysql --host=${RDS_HOSTNAME} -P3306 -u root -p%s -e "GRANT ALL ON django_$SITE.* TO \'$RDS_USERNAME\'@\'localhost\' IDENTIFIED BY \'$RDS_PASSWORD\';"' % fab_api.env.mysqlpwd)
-
-def install_awsPythonRequirements(self, reinstall=False):
-    """
-    Installs the Python virtual environment needed for safe-n-sane Django using the
-    requirements.txt file contents
-    """
-
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    print(fab_colors.yellow("Updating Python virtual environment (this may take around 20 minutes the first time)..."))
-
-    if reinstall or not fab_exists('~/django/python'):
-        ###TODO: create a dated and sorted freeze first
-        print(fab_colors.yellow("Creating Python virtual environment..."))
-        fab_api.run('rm -rf ~/django/python')
-        fab_api.run('virtualenv --no-site-packages --distribute ~/django/python')
-
-    with fab_api.settings(
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/python/bin/activate')):
-
-        # Install MySQL-Python with appropriate distribute version as well
-        fab_api.run('pip install --upgrade --download-cache=/home/%s/django/cache --source=/home/%s/django/cache distribute==0.6.30' % (fab_api.env.AWS_USER, fab_api.env.AWS_USER))
-        fab_api.run('pip install --upgrade --download-cache=/home/%s/django/cache --source=/home/%s/django/cache MySQL-python==1.2.3' % (fab_api.env.AWS_USER, fab_api.env.AWS_USER))
-
-        # Install all of the modules in requirements.txt for this project
-        fab_api.run('pip install --upgrade --download-cache=~/django/cache --source=~/django/cache -r requirements.txt')
-
-def sync_awsProject(self, push=False):
-    """
-    Sync the local copy up to the remote server
-    """
-
-    if not fab_api.env.git_repo:
-        ###TODO: Add -ignore flags for unison call
-
-        fab_api.prompt("Are you sure you want to use Unison instead of git? (Y/N) ", 'sync_cont')
-        if fab_api.env.sync_cont is "Y" or fab_api.env.sync_cont is "y":
-
-            self.get_sshKey()
-            fab_api.env.host_string = 'localhost'
-            fab_api.env['user'] = getuser()
-
-            here = os.getcwd()
-            there = "ssh://%s@%s//home/%s/django/%s" % (fab_api.env.AWS_USER, instance.ip_address, fab_api.env.AWS_USER, fab_api.env.SITENAME)
-
-            print(fab_colors.yellow("Synchronizing project files..."))
-
-            with fab_api.settings(warn_only=True): # unison has return code 1 when no changes
-                if push:
-                    fab_api.run('unison -ignore "Path httpdocs"  -silent -force %s %s %s' % (here, here, there))
-                else:
-                    fab_api.run('unison -auto -ignore "Path httpdocs"  %s %s' % (here, there))
-        else:
-            fab_api.prompt("Please enter the url for the repository clone: ", 'git_repo')
-
-    if fab_api.env.git_repo:
+    conn = get_awsConnection()
+    instance = None
 
-        self.get_sshKey()
-        instance = self.get_awsInstance()
-        fab_api.env.host_string = instance.ip_address
-        fab_api.env['user'] = fab_api.env.AWS_USER
+    if not instance:
+        # Show the existing instances
+        instance_list = get_awsInstanceList()
 
-        if fab_exists('/home/%s/.ssh/%s.pub' % (fab_api.env.AWS_USER, fab_api.env.SITENAME)):
-            fab_op.get('/home/%s/.ssh/config' % fab_api.env.AWS_USER, '/home/%s/django/%s/etc/ssh/config' % (getuser(), fab_api.env.SITENAME))
-            sshconf = file('/home/%s/django/%s/etc/ssh/config' % (getuser(), fab_api.env.SITENAME))
-            found = False
-            for line in sshconf:
-                bbhost = 'Host %s_BB' % fab_api.env.SITENAME
-                if bbhost in line:
-                    found = True
-                    break
-            if not found:
-                fab_api.run('cat /home/%s/.ssh/%s.pub' % (fab_api.env.AWS_USER, fab_api.env.SITENAME))
-                fab_api.prompt('Press return once the key has been added to the repo', '')
-        else:
-            self.get_sshKey()
-            fab_api.env.host_string = 'localhost'
-            fab_api.env['user'] = getuser()
-            fab_api.run('cat /home/%s/django/%s/etc/ssh/id_rsa.pub' % (fab_api.env.user, fab_api.env.SITENAME))
-            fab_api.prompt('Press return once the key has been added to the repo', '')
-            instance = self.get_awsInstance()
-            fab_api.env.host_string = instance.ip_address
-            fab_api.env['user'] = fab_api.env.AWS_USER
-            fab_op.put('/home/%s/django/%s/etc/ssh/id_rsa.pub' % (getuser(), fab_api.env.SITENAME), '/home/%s/.ssh/%s.pub' % (fab_api.env.AWS_USER, fab_api.env.SITENAME))
-            fab_op.put('/home/%s/django/%s/etc/ssh/id_rsa' % (getuser(), fab_api.env.SITENAME), '/home/%s/.ssh/%s' % (fab_api.env.AWS_USER, fab_api.env.SITENAME))
+        # If there are any, offer to select one
+        if instance_list:
+            fabric.api.prompt('Select an existing instance or hit enter to create a new one:', 'instance_selection')
+            if fabric.api.env.instance_selection:
+                instance = instance_list[int(fabric.api.env.instance_selection)]
+                fabric.api.env['aws_instance'] = instance.id
+                print(fabric.colors.green("%s selected." % (instance.id,)))
 
-        path = os.path.join('/home', '%s' % fab_api.env.AWS_USER, '.ssh', 'config')
-        instance = self.get_awsInstance()
-        fab_api.env.host_string = instance.ip_address
-        fab_api.env['user'] = fab_api.env.AWS_USER
-        print "%s on %s" % (fab_api.env.user, fab_api.env.host_string)
-        if not fab_exists(path, False):
-            fab_api.run('touch %s' % path)
-        sshconf = file('/home/%s/django/%s/etc/ssh/config' % (getuser(), fab_api.env.SITENAME))
-        found = False
-        for line in sshconf:
-            bbhost = 'Host %s_BB' % fab_api.env.SITENAME
-            if bbhost in line:
-                found = True
-                break
-        if not found:
-            fab_append(path, 'Host %s_BB\n\tHostName bitbucket.org\n\tUser git\n\tIdentityFile /home/%s/.ssh/%s\n' % (fab_api.env.SITENAME, fab_api.env.AWS_USER, fab_api.env.SITENAME))
-        fab_api.run('sudo chown -R %s:%s /home/%s/.ssh' % (fab_api.env.AWS_USER, fab_api.env.AWS_USER, fab_api.env.AWS_USER))
-        fab_api.run('sudo chmod -R go-rwx /home/%s/.ssh' % fab_api.env.AWS_USER)
-        fab_api.run('chmod -R u+rw /home/%s/.ssh' % fab_api.env.AWS_USER)
-        replace = 'bitbucket.org'
-        withstring = '%s_BB' % fab_api.env.SITENAME
-        newstr,found,endpart = fab_api.env.git_repo.partition(replace)
-
-        if found:
-            newstr+=withstring+endpart
-            fab_api.env['git_repo'] = newstr
-            print fab_api.env.git_repo
-
-        fab_api.run('sudo service ssh restart')
-        if not fab_exists('~/django/%s' % fab_api.env.SITENAME):
-
-            fab_api.run('git clone %s /home/%s/django/%s' % (fab_api.env.git_repo, fab_api.env.AWS_USER, fab_api.env.SITENAME))
-
-        else:
-            with fab_api.settings(
-                                fab_api.cd('~/django/%s' % fab_api.env.SITENAME)):
-                fab_api.run('git pull')
-
-def sync_awsPurify(self):
-    """
-    Clear the menu cache or errors may ensue!
-    """
-
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    print(fab_colors.yellow("Cleaning menu entries..."))
-
-    with fab_api.settings(
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/python/bin/activate'),
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/%s/bin/remote_data.sh' % fab_api.env.SITENAME)):
-        fab_api.run('python manage.py reset --noinput menus')
-
-
-def sync_awsDB(self, push=False):
-    """
-    Run the django database maintenance commands within the AWS server instance
-    """
-
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    print(fab_colors.yellow("Initializing/updating database..."))
-
-    with fab_api.settings(
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/python/bin/activate'),
-                        fab_api.prefix('source ~/django/%s/bin/remote_data.sh' % fab_api.env.SITENAME)):
-
-        # Update the database and link all media files
-        fab_api.run('python manage.py syncdb --noinput --verbosity=0')
-        fab_api.run('python manage.py migrate --verbosity=0')
-
-
-def sync_awsStaticfiles(self):
-    """
-    Link the static files from the various modules into a common file tree for serving up on Apache
-    """
-
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    print(fab_colors.yellow("Collecting static files from included modules..."))
-
-
-    ###TODO: the directory should be puled from the settings.py file
-    with fab_api.settings(
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/python/bin/activate'),
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/%s/bin/remote_data.sh' % fab_api.env.SITENAME)):
-
-        # Link the media files
-
-        if fab_exists('~/django/%s/httpdocs/static' % fab_api.env.SITENAME):
-            fab_api.sudo('rm -rf ~/django/%s/httpdocs/static' % fab_api.env.SITENAME)
-        if not fab_exists('~/django/%s/httpdocs/media' % fab_api.env.SITENAME):
-            fab_api.sudo('mkdir -p ~/django/%s/httpdocs/media' % fab_api.env.SITENAME)
-        fab_api.run('python manage.py collectstatic -l --noinput --verbosity=0')
-
-def set_awsApacheconf(self, domain=None):
-    """
-    Enable the Apache config
-    """
-
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    if not domain:
-        fab_api.prompt('Base domain to host as:', 'domain', fab_api.env.SITENAME + ".com")
-    else:
-        fab_api['domain']=domain
-
-    fab_api.env['django_base_dir'] = "/home/%s/django/" % fab_api.env.AWS_USER
-
-    print(fab_colors.yellow("Creating and installing Apache configuration file..."))
-
-    # upload the settings.py and apache config templates to project/website
-    target = "/etc/apache2/sites-available/%s.conf" % fab_api.env.domain
-    template = os.path.join('etc','apache2_vhost.conf')
-    fab_op.put(template, target, use_sudo=True)
-
-    if fab_exists('/etc/apache2/sites-enabled/000-default') or fab_exists('/etc/apache2/sites-enabled/default'):
-        fab_api.prompt('Disable [000-]default? (y/n) ', 'nopchdflt')
-        if fab_api.env.nopchdflt == 'y':
-            if fab_exists('/etc/apache2/sites-enabled/000-default'):
-                fab_api.sudo('a2dissite 000-default')
-            if fab_exists('/etc/apache2/sites-enabled/default'):
-                fab_api.sudo('a2dissite default')
-
-    fab_api.sudo('a2ensite %s.conf' % fab_api.env.domain)
-
-def cmd_awsApacheRestart(self):
-    """
-    Restart Apache
-    """
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    print(fab_colors.yellow("Graceful Apache..."))
-
-    fab_api.sudo('apache2ctl graceful')
-
-def cmd_terminateInstance(self):
-    """terminate instance and remove from .aws_fabric"""
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    print fab_colors.red('You are about to TERMINATE an instance. This CANNOT be undone.')
-    print fab_colors.red('!!!!!!!!!! You will LOSE all its DATA. !!!!!!!!!!!!!!!!!!!!!!!')
-    print 'id: %s ip_address: %s' % (instance.id, instance.ip_address)
-    output = raw_input('\nTo proceed, type the ip address of this instance: ')
-    # terminate instance
-    if output == instance.ip_address:
-        instance.terminate()
-    # remove instance from .aws_fabric
-    path = fab_api.env.get('rcfile')
-    if isfile(path):
-        with open(path) as file:
-            new_lines = [line for line in file if 'AWS_INSTANCE_ID' not in line]
-        with open(path,'w') as file:
-            file.writelines(new_lines)
-    print fab_colors.yellow('\ninstance terminated')
-
-def _list_keys_on_remote(self, id_only=False):
-    """get ssh keys on remote"""
-    with fab_api.hide('everything'):
-        output = fab_api.run('cat ~/.ssh/authorized_keys')
-    if id_only:
-        return [line.split()[-1] for line in output.splitlines()]
-    else:
-        return output.splitlines()
-
-def cmd_rmKey(self):
-    """rm keys from remote"""
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-    ids = self._list_keys_on_remote(id_only=True)
-
-    def prompt_for_delete(): # local func so it can easily be repeated
-        print fab_colors.yellow("\n========================\nThese keys are installed.")
-        for num, id in enumerate(ids):
-            print '(%s) %s' % (num, id)
-        print fab_colors.yellow('\nEnter the numbers of the keys to delete, seperated by spaces.')
-        # get keys to delete
-        input = raw_input('nums: ')
-        to_delete = [int(num) for num in input.split() if num.isdigit()]
-        to_delete = filter(lambda x: 0 <= x < len(ids), to_delete)
-        # validate selection, to prevent terrible crisis
-        if not to_delete:
-            print fab_colors.red('\nYou didnt choose anything. Lets start over...')
-            prompt_for_delete()
-        if len(to_delete) >= len(ids):
-            print fab_colors.red('\nDO NOT delete all keys. you will be LOCKED OUT permanently.')
-            prompt_for_delete()
-        key_id, key_value = self.get_sshKey()
-        if ['fail' for num in to_delete if ids[num]==key_id ]:
-            print fab_colors.red('\nDUDE. Do NOT delete you own key. Get a grip...')
-            prompt_for_delete()
-        # print selection and confirm
-        print fab_colors.yellow('\nYou would like to delete:')
-        for num in sorted(to_delete):
-            print '(%s) %s' % (num, ids[num])
-        output = raw_input('\nIs this correct? ' + fab_colors.yellow('[yes|no]') + ' : ')
-        # update the keys
-        if output == 'yes':
-            old_keys = enumerate(self._list_keys_on_remote())
-            new_keys = [key for num, key in old_keys if num not in to_delete]
-            new_keys =  '\n'.join(new_keys)
-            with fab_api.hide('everything'):
-                fab_api.run('echo "%s" > ~/.ssh/authorized_keys' % new_keys)
-            to_print =  fab_colors.yellow('\ndeleted keys ')
-            to_print += fab_colors.yellow(' and ').join([ids[num] for num in to_delete])
-            to_print += fab_colors.yellow(' from remote.')
-            print to_print
-        # if chose not to proceed, start over
-        else:
-            prompt_for_delete()
-
-    prompt_for_delete() # call the func
-
-def cmd_addKey(self, keyfile=None):
-    """
-    add keys to remote
-    """
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-    print(fab_colors.yellow("Enter ssh pub keys, one per line.\nEnter blank line to terminate input."))
-    # prompt for ssh keys
-    keys = []
-    while True:
-        output = raw_input('ssh pub key: ')
-        if output:
-            keys.append(output)
-        else:
-            break
-    # add keys to remote
-    for key in keys:
-        with fab_api.hide('everything'):
-            fab_api.run('echo "%s" >> ~/.ssh/authorized_keys' % key)
-    print(fab_colors.yellow("keys have been added to remote instance."))
-
-def cmd_listKeys(self):
-    """list the id/user of all installed ssh keys on remote instance"""
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-    print(fab_colors.yellow("Pub Key IDs..."))
-    print '\n'.join(self._list_keys_on_remote(id_only=True))
-
-def cmd_getIP(self):
-    """print the ip of our instance"""
-    self.get_sshKey()
-    instance = self.get_awsInstance(create=False)
-    if instance:
-        print instance.ip_address
-    else:
-        print 'no instance created yet'
-
-def cmd_awsShell(self):
-    """
-    Open an interactive shell on the AWS server instance
-    """
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-    fab_api.open_shell()
-
-
-#noinspection PyUnusedLocal
-def cmd_awsManage(self, *args, **options):
-    """
-    Run any series of available Django command in the aws instance
-    """
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    ###TODO: Clean this up so that it accepts options like the local command does
-
-    with fab_api.settings(
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/python/bin/activate'),
-                        fab_api.cd('~/django/%s' % fab_api.env.SITENAME),
-                        fab_api.prefix('source ~/django/%s/bin/remote_data.sh' % fab_api.env.SITENAME)):
-
-        for cmd in args[0]:
-            fab_api.run(command='python manage.py %s' % cmd)
-            #print('python manage.py %s' % cmd)
-
-
-def set_awsPermissions(self):
-    """
-    Set file permissions to usable values
-    """
-
-    self.get_sshKey()
-    instance = self.get_awsInstance()
-    fab_api.env.host_string = instance.ip_address
-
-    print(fab_colors.yellow("Settings apropriate default permissions on project files..."))
-
-    if not fab_exists('~/django/%s/httpdocs/media' % fab_api.env.SITENAME):
-        fab_api.sudo('mkdir -p ~/django/%s/httpdocs/media' % fab_api.env.SITENAME)
-
-    fab_api.sudo('chown -R %s:%s ~/django/%s/httpdocs/media' % (fab_api.env.AWS_USER, fab_api.env.AWS_HTTPD_GROUP, fab_api.env.SITENAME))
-    fab_api.sudo('chmod -R ug+rw ~/django/%s/httpdocs/media' % (fab_api.env.SITENAME))
-
-    # Add access to the webserver to write into the cache directory
-    fab_api.sudo('chown -R %s:%s ~/django/%s/' % (fab_api.env.AWS_USER, fab_api.env.AWS_HTTPD_GROUP, fab_api.env.SITENAME))
-    fab_api.sudo('chmod -R ug+rw ~/django/%s/' % (fab_api.env.SITENAME))
-
-
-def get_awsConnection(self):
-    """
-    Get or create the connection object to AWS
-    """
-
-    if self.conn:
-        return self.conn
-
-    # Create a connection to the AWS region of choice with our keys
-    self.conn = ec2.connect_to_region(
-        region_name             = fab_api.env.AWS_REGION,
-        aws_access_key_id       = fab_api.env.AWS_ACCESS_KEY_ID,
-        aws_secret_access_key   = fab_api.env.AWS_ACCESS_SECRET,
-        )
-
-    if not self.conn:
-        raise Exception("No AWS Connection! Cannot continue!")
-
-    return self.conn
-
-class RESTRequest(Request):
-    def __init__(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None):
-        Request.__init__(self, url, data, headers, origin_req_host, unverifiable)
-        self.method = method
-
-    def get_method(self):
-        if self.method:
-            return self.method
-        return Request.get_method(self)
-
-class DeployKey():
-
-    def __init__(self, spice_repo=None, repo_owner=None, owner_passwd=None):
-        self.spice_repo = spice_repo
-        self.repo_owner = repo_owner
-        self.owner_passwd = owner_passwd
-        #if owner is None:
-            #print "What would you like to do?"
-            #print ""
-            #print "(g)et a listing of a repositories deploy keys"
-            #print "(a)uthorize a deploy key with BitBucket"
-            #print "(d)eauthorize a deploy key with BitBucket"
-            #print ""
-            #reply = raw_input("[")
-            #if reply == "g":
-                #pass
-                ##add definition for owner,owner_passwd,spice_repo cli
-                ##self.getKeys()
-            #elif reply == "a":
-                #pass
-                ##self.postKey(ssh_key,key_label)
-            #elif reply == "d":
-                #pass
-                ##add addition prompt for ssh keyid preceded by readout of key choices by 'label' and 'ak'
-                ##readout via 'for item in' sort of thing....?
-                ##self.delKey()
-            #else:
-                #return False
-
-    def decode_list(self, jsonData):
-        rv = []
-        for item in jsonData:
-            if isinstance(item, unicode):
-                item = item.encode('utf-8')
-            elif isinstance(item, list):
-                item = self.decode_list(item)
-            elif isinstance(item, dict):
-                item = self.decode_dict(item)
-            rv.append(item)
-        return rv
-
-    def decode_dict(self, jsonData):
-        rv = {}
-        for key, value in jsonData.iteritems():
-            if isinstance(key, unicode):
-               key = key.encode('utf-8')
-            if isinstance(value, unicode):
-               value = value.encode('utf-8')
-            elif isinstance(value, list):
-               value = self.decode_list(value)
-            elif isinstance(value, dict):
-               value = self.decode_dict(value)
-            rv[key] = value
-        return rv
-
-    def getCred(self):
-        credentials = b64encode("{0}:{1}".format(self.owner, self.owner_passwd).encode()).decode("ascii")
-        return credentials
-
-    def getURL(self):
-        url = "https://api.bitbucket.org/1.0/repositories/%s/%s/deploy-keys" % (self.owner, self.spice_repo)
-        return url
-
-    def getHeaders(self):
-        headers = {'Authorization': "Basic " + self.getCred()}
-        return headers
-
-    def getKeys(self):
-        request = RESTRequest(url=self.getURL(), headers=self.getHeaders(), method="GET")
-        connection = urlopen(request)
-        content = connection.read()
-        return json.loads(content, object_hook=self.decode_dict)
-
-    def postKey(self,ssh_key,key_label):
-        data = urlencode({"key": ssh_key, "label": key_label})
-        request = RESTRequest(url=self.getURL(), headers=self.getHeaders(), data=data, method="POST")
-        connection = urlopen(request)
-        connection.read()
-
-    def delKey(self,key_id):
-        request = RESTRequest(url="%s/%s" % (self.getURL(), key_id), headers=self.getHeaders(), method="DELETE")
-        connection = urlopen(request)
-        connection.read()
+    # Make sure that the instance has spun-up before continuing
+    while instance.state != 'running':
+        print fabric.colors.yellow("Waiting for instance...")
+        time.sleep(5)
+        instance.update()
+        if instance.state == 'running':
+            print fabric.colors.green("Instance %s is up!" % instance.id)
+
+    fabric.api.env.host_string = instance.ip_address
+    return instance
+
+# def create_awsInstance():
+#
+#     fabric.api.warn('Creating new instance in the %s region with the %s image.' % (fabric.api.env.AWS_REGION, fabric.api.env.AWS_AMI_ID, ))
+#
+#     (keyid, keyvalue) = get_sshKey()
+#
+#     # Creates a server instance in your AWS account
+#     reservation = conn.run_instances(
+#         image_id= fabric.api.env.AWS_AMI_ID,
+#         instance_type=fabric.api.env.AWS_TYPE,
+#         key_name=keyid,
+#         security_groups=['apache', 'developer',],
+#         )
+#
+#     # Select the just-created instance
+#     instance = reservation.instances[0]
+#     fabric.api.env['AWS_INSTANCE_ID'] = instance.id
+#     print(fabric.colors.green("Server instance %s created." % (instance.id,)))
+#     fabric.api.env['unsaved'] = True
+#
+#     # Make sure that the instance has spun-up before continuing
+#     while instance.state != 'running':
+#         print fabric.colors.yellow("Waiting for instance...")
+#         time.sleep(5)
+#         instance.update()
+#         if instance.state == 'running':
+#             print fabric.colors.green("Instance %s is up!" % instance.id)
+#
+#     fabric.api.env.host_string = instance.ip_address
+#     return instance
+#
+#
+# def set_awsElasticIP():
+#     """
+#     """
+#     ###TODO: TEST THIS BEFORE USING!!!  ..and add some error catching fer crying out loud!
+#     ###TODO: check if there already is an elasticIP assigned to this instance before creating ANOTHER
+#     ###TODO: check to see if even though an EIP exists, whether this instance still needs it (use options?)
+#
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     elasticip = conn.allocate_address()
+#     conn.associate_address(instance_id=instance.id , allocation_id=elasticip.allocation_id)
+#
+#
+# def get_sshKey(keyfile=None):
+#
+#     if not keyfile:
+#         # *********************
+#
+#         fabric.api.env.host_string = 'localhost'
+#         fabric.api.env['user'] = getuser()
+#         if not fabric.contrib.files.exists('/%s/etc/ssh/id_rsa.pub' % settings.PROJECT_DIR):
+#             if not fabric.contrib.files.exists('%s/etc/ssh' % settings.PROJECT_DIR):
+#                 fabric.api.run('mkdir -p %s/etc/ssh' % settings.PROJECT_DIR)
+#             fabric.api.run('ssh-keygen -f "%s/etc/ssh/id_rsa" -q -N "" -C "%s via AWS on %s"' % (settings.PROJECT_DIR, fabric.api.env.AWS_USER, fabric.api.env.SITENAME))
+#         fabric.api.env['host_string'] = None
+#         fabric.api.env['user'] = fabric.api.env.AWS_USER
+#
+#         keyfile = os.path.abspath(os.path.join(settings.PROJECT_DIR, "etc", "ssh", "id_rsa.pub"))
+#         privkey = os.path.abspath(os.path.join(settings.PROJECT_DIR, "etc", "ssh", "id_rsa"))
+#
+#     keyfile = os.path.expanduser(keyfile)
+#
+#     try:
+#        kf = open(keyfile)
+#     except IOError as e:
+#         print fabric.colors.red('Keyfile: %s does not exist!  Please specify a valid pubkey file with --sshpubkey=PATH_TO_SECURITY_KEY' % keyfile)
+#         sys.exit(0)
+#
+#     keyvalue = kf.readline()
+#     keyid = keyvalue.split()[-1].strip() # delimeter not always "== ", but always id is last text following final space
+#     kf.close()
+#     fabric.api.env['key_filename'] = privkey
+#     return (keyid, keyvalue)
+#
+# def set_awsSSHKey(keyfile=None):
+#     """
+#     Imports your local ssh pubkey into your AWS account
+#     """
+#     if keyfile:
+#         try:
+#             (keyid, keyvalue) = get_sshKey(keyfile)
+#         except:
+#             raise Exception("SSH pubkey not found! Cannot continue!")
+#
+#     else:
+#         (keyid, keyvalue) = get_sshKey()
+#
+#     conn = get_awsConnection()
+#
+#     try:
+#         try:
+#             home = os.getenv('USERPROFILE') or os.getenv('HOME')
+#             home_keyfile = os.path.abspath(os.path.join(home, ".ssh", "id_rsa.pub"))
+#             kf = open(home_keyfile)
+#             homekeyvalue = kf.readline()
+#             homekeyid = homekeyvalue.split()[-1].strip() # delimeter not always "== ", but always id is last text following final space
+#             kf.close()
+#             keypairs = conn.get_all_key_pairs(keynames=[homekeyid,])
+#         except IOError as e:
+#             pass
+#     except boto.exception.boto.ec2ResponseError:
+#         # Nope.  Not there!  Lets create it
+#         conn.import_key_pair(keyid,keyvalue)
+#         print(fabric.colors.green("Key ID '%s' installed from %s." % (keyid, keyfile)))
+#     else:
+#         pass
+#
+#     # Import a security pub key for us to use ssh with
+#     try:
+#         # Look to see if it already exists first
+#         keypairs = conn.get_all_key_pairs(keynames=[keyid,])
+#     except boto.exception.boto.ec2ResponseError:
+#         # Nope.  Not there!  Lets create it
+#         conn.import_key_pair(keyid,keyvalue)
+#         print(fabric.colors.green("Key ID '%s' installed from %s." % (keyid, keyfile)))
+#     else:
+#         print(fabric.colors.green("Key ID '%s' exists." % keyid))
+#
+# def set_awsSecurityGroups():
+#     """
+#     Creates necessary firewall security groups in your AWS account
+#     """
+#
+#     conn = get_awsConnection()
+#
+#     # Check security group for the webserver
+#     try:
+#         conn.get_all_security_groups(groupnames=['apache',])
+#     except boto.exception.boto.ec2ResponseError:
+#         # Create a security group for internet access to the webserver
+#         web = conn.create_security_group('apache', 'Apache Security Group')
+#         web.authorize('tcp', 80, 80, '0.0.0.0/0')
+#         print(fabric.colors.green("Apache firewall entry added."))
+#     else:
+#         print(fabric.colors.green("Apache firewall entry exists."))
+#
+#     # Check security group for the developer access
+#     try:
+#         conn.get_all_security_groups(groupnames=['developer',])
+#     except boto.exception.boto.ec2ResponseError:
+#         # Create a security group for internet access to the test server and ssh
+#         dev = conn.create_security_group('developer', 'Developer Security Group')
+#         dev.authorize('tcp', 8000, 8000, '0.0.0.0/0')
+#         dev.authorize('tcp', 22, 22, '0.0.0.0/0')
+#         print(fabric.colors.green("Developer firewall entry added."))
+#     else:
+#         print(fabric.colors.green("Developer firewall entry exists."))
+#
+# def install_awsUbuntuUpgrades():
+#     """
+#     Installs the core components needed to run Django, Apache etc on Ubuntu
+#     """
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#     print fabric.api.env.host_string
+#     print fabric.api.env.key_filename
+#
+#
+#     # Update all of the server and library components first
+#     print(fabric.colors.yellow("Checking OS for available updates..."))
+#     fabric.api.sudo('apt-get -y update')
+#     fabric.api.sudo('apt-get -y dist-upgrade')
+#
+#     # Install all of the server and library components
+#     print(fabric.colors.yellow("Checking OS for required packages..."))
+#     fabric.api.sudo('apt-get -y install python-setuptools python-dev python-virtualenv git mercurial gcc unison python-pip node-less libtidy-dev')
+#
+#     # Install Apache and necesary components
+#     fabric.api.sudo('apt-get -y install apache2 libapache2-mod-wsgi')
+#
+#     # Install PIL support for Virtual Environment on 64 bit systems
+#     fabric.api.sudo('apt-get -y install python-imaging libjpeg62 libjpeg62-dev libjpeg8')
+#
+#     # Link the libraries so that PIL can find them
+#     if not fabric.contrib.files.exists('/usr/lib/libz.so'):
+#         fabric.api.sudo('ln -s  /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/')
+#     if not fabric.contrib.files.exists('/usr/lib/libjpeg.so'):
+#         fabric.api.sudo('ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib/')
+#
+#     # Instal MySQL components to system
+#     fabric.api.sudo('apt-get install -y mysql-server mysql-client python-mysqldb libmysqlclient-dev build-essential python-dev')
+#     fabric.api.sudo('apt-get -y install python-mysqldb')
+#
+#     # Clean up our mess and reduce system footprint on the HDD
+#     fabric.api.sudo('apt-get -y clean')
+#
+#
+#     # Create the base directory
+#     ###TODO: make this use a dynamic variable instead of hardcoded as it is
+#     if not fabric.contrib.files.exists('/home/%s/django' % fabric.api.env.AWS_USER):
+#         fabric.api.run('mkdir /home/%s/django' % fabric.api.env.AWS_USER)
+#     if not fabric.contrib.files.exists('/home/%s/django/cache' % fabric.api.env.AWS_USER):
+#         fabric.api.run('mkdir /home/%s/django/cache' % fabric.api.env.AWS_USER)
+#
+#
+# def cmd_awsReboot():
+#     """
+#     Reboot the AWS server
+#     """
+#
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     print fabric.colors.yellow("Rebooting instance...")
+#     fabric.api.sudo('reboot')
+#     time.sleep(60)
+#     while instance.state != 'running':
+#         print fabric.colors.yellow(instance.state)
+#         time.sleep(5)
+#         instance.update()
+#
+# def aws_DropDB():
+#     """
+#     Drop the database and recreate
+#     """
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     with fabric.api.settings(
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/python/bin/activate'),
+#                         fabric.api.prefix('source ~/django/%s/bin/remote_data.sh' % fabric.api.env.SITENAME)):
+#         fabric.api.prompt('What is the server MySQL root password:', 'mysqlpwd')
+#         fabric.api.run('mysql --host=${RDS_HOSTNAME} -P3306 -u root -p%s -e "DROP DATABASE IF EXISTS django_$SITE;"' % fabric.api.env.mysqlpwd)
+#         fabric.api.run('mysql --host=${RDS_HOSTNAME} -P3306 -u root -p%s -e "CREATE DATABASE django_$SITE;"' % fabric.api.env.mysqlpwd)
+#         fabric.api.run('mysql --host=${RDS_HOSTNAME} -P3306 -u root -p%s -e "GRANT ALL ON django_$SITE.* TO \'$RDS_USERNAME\'@\'localhost\' IDENTIFIED BY \'$RDS_PASSWORD\';"' % fabric.api.env.mysqlpwd)
+#
+# def install_awsPythonRequirements(reinstall=False):
+#     """
+#     Installs the Python virtual environment needed for safe-n-sane Django using the
+#     requirements.txt file contents
+#     """
+#
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     print(fabric.colors.yellow("Updating Python virtual environment (this may take around 20 minutes the first time)..."))
+#
+#     if reinstall or not fabric.contrib.files.exists('~/django/python'):
+#         ###TODO: create a dated and sorted freeze first
+#         print(fabric.colors.yellow("Creating Python virtual environment..."))
+#         fabric.api.run('rm -rf ~/django/python')
+#         fabric.api.run('virtualenv --no-site-packages --distribute ~/django/python')
+#
+#     with fabric.api.settings(
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/python/bin/activate')):
+#
+#         # Install MySQL-Python with appropriate distribute version as well
+#         fabric.api.run('pip install --upgrade --download-cache=/home/%s/django/cache --source=/home/%s/django/cache distribute==0.6.30' % (fabric.api.env.AWS_USER, fabric.api.env.AWS_USER))
+#         fabric.api.run('pip install --upgrade --download-cache=/home/%s/django/cache --source=/home/%s/django/cache MySQL-python==1.2.3' % (fabric.api.env.AWS_USER, fabric.api.env.AWS_USER))
+#
+#         # Install all of the modules in requirements.txt for this project
+#         fabric.api.run('pip install --upgrade --download-cache=~/django/cache --source=~/django/cache -r requirements.txt')
+#
+# def sync_awsProject(push=False):
+#     """
+#     Sync the local copy up to the remote server
+#     """
+#
+#     if not fabric.api.env.git_repo:
+#         ###TODO: Add -ignore flags for unison call
+#
+#         fabric.api.prompt("Are you sure you want to use Unison instead of git? (Y/N) ", 'sync_cont')
+#         if fabric.api.env.sync_cont is "Y" or fabric.api.env.sync_cont is "y":
+#
+#             get_sshKey()
+#             fabric.api.env.host_string = 'localhost'
+#             fabric.api.env['user'] = getuser()
+#
+#             here = os.getcwd()
+#             there = "ssh://%s@%s//home/%s/django/%s" % (fabric.api.env.AWS_USER, instance.ip_address, fabric.api.env.AWS_USER, fabric.api.env.SITENAME)
+#
+#             print(fabric.colors.yellow("Synchronizing project files..."))
+#
+#             with fabric.api.settings(warn_only=True): # unison has return code 1 when no changes
+#                 if push:
+#                     fabric.api.run('unison -ignore "Path httpdocs"  -silent -force %s %s %s' % (here, here, there))
+#                 else:
+#                     fabric.api.run('unison -auto -ignore "Path httpdocs"  %s %s' % (here, there))
+#         else:
+#             fabric.api.prompt("Please enter the url for the repository clone: ", 'git_repo')
+#
+#     if fabric.api.env.git_repo:
+#
+#         get_sshKey()
+#         instance = get_awsInstance()
+#         fabric.api.env.host_string = instance.ip_address
+#         fabric.api.env['user'] = fabric.api.env.AWS_USER
+#
+#         if fabric.contrib.files.exists('/home/%s/.ssh/%s.pub' % (fabric.api.env.AWS_USER, fabric.api.env.SITENAME)):
+#             fabric.operations.get('/home/%s/.ssh/config' % fabric.api.env.AWS_USER, '/home/%s/django/%s/etc/ssh/config' % (getuser(), fabric.api.env.SITENAME))
+#             sshconf = file('/home/%s/django/%s/etc/ssh/config' % (getuser(), fabric.api.env.SITENAME))
+#             found = False
+#             for line in sshconf:
+#                 bbhost = 'Host %s_BB' % fabric.api.env.SITENAME
+#                 if bbhost in line:
+#                     found = True
+#                     break
+#             if not found:
+#                 fabric.api.run('cat /home/%s/.ssh/%s.pub' % (fabric.api.env.AWS_USER, fabric.api.env.SITENAME))
+#                 fabric.api.prompt('Press return once the key has been added to the repo', '')
+#         else:
+#             get_sshKey()
+#             fabric.api.env.host_string = 'localhost'
+#             fabric.api.env['user'] = getuser()
+#             fabric.api.run('cat /home/%s/django/%s/etc/ssh/id_rsa.pub' % (fabric.api.env.user, fabric.api.env.SITENAME))
+#             fabric.api.prompt('Press return once the key has been added to the repo', '')
+#             instance = get_awsInstance()
+#             fabric.api.env.host_string = instance.ip_address
+#             fabric.api.env['user'] = fabric.api.env.AWS_USER
+#             fabric.operations.put('/home/%s/django/%s/etc/ssh/id_rsa.pub' % (getuser(), fabric.api.env.SITENAME), '/home/%s/.ssh/%s.pub' % (fabric.api.env.AWS_USER, fabric.api.env.SITENAME))
+#             fabric.operations.put('/home/%s/django/%s/etc/ssh/id_rsa' % (getuser(), fabric.api.env.SITENAME), '/home/%s/.ssh/%s' % (fabric.api.env.AWS_USER, fabric.api.env.SITENAME))
+#
+#         path = os.path.join('/home', '%s' % fabric.api.env.AWS_USER, '.ssh', 'config')
+#         instance = get_awsInstance()
+#         fabric.api.env.host_string = instance.ip_address
+#         fabric.api.env['user'] = fabric.api.env.AWS_USER
+#         print "%s on %s" % (fabric.api.env.user, fabric.api.env.host_string)
+#         if not fabric.contrib.files.exists(path, False):
+#             fabric.api.run('touch %s' % path)
+#         sshconf = file('/home/%s/django/%s/etc/ssh/config' % (getuser(), fabric.api.env.SITENAME))
+#         found = False
+#         for line in sshconf:
+#             bbhost = 'Host %s_BB' % fabric.api.env.SITENAME
+#             if bbhost in line:
+#                 found = True
+#                 break
+#         if not found:
+#             fabric.contrib.files.append(path, 'Host %s_BB\n\tHostName bitbucket.org\n\tUser git\n\tIdentityFile /home/%s/.ssh/%s\n' % (fabric.api.env.SITENAME, fabric.api.env.AWS_USER, fabric.api.env.SITENAME))
+#         fabric.api.run('sudo chown -R %s:%s /home/%s/.ssh' % (fabric.api.env.AWS_USER, fabric.api.env.AWS_USER, fabric.api.env.AWS_USER))
+#         fabric.api.run('sudo chmod -R go-rwx /home/%s/.ssh' % fabric.api.env.AWS_USER)
+#         fabric.api.run('chmod -R u+rw /home/%s/.ssh' % fabric.api.env.AWS_USER)
+#         replace = 'bitbucket.org'
+#         withstring = '%s_BB' % fabric.api.env.SITENAME
+#         newstr,found,endpart = fabric.api.env.git_repo.partition(replace)
+#
+#         if found:
+#             newstr+=withstring+endpart
+#             fabric.api.env['git_repo'] = newstr
+#             print fabric.api.env.git_repo
+#
+#         fabric.api.run('sudo service ssh restart')
+#         if not fabric.contrib.files.exists('~/django/%s' % fabric.api.env.SITENAME):
+#
+#             fabric.api.run('git clone %s /home/%s/django/%s' % (fabric.api.env.git_repo, fabric.api.env.AWS_USER, fabric.api.env.SITENAME))
+#
+#         else:
+#             with fabric.api.settings(
+#                                 fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME)):
+#                 fabric.api.run('git pull')
+#
+# def sync_awsPurify():
+#     """
+#     Clear the menu cache or errors may ensue!
+#     """
+#
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     print(fabric.colors.yellow("Cleaning menu entries..."))
+#
+#     with fabric.api.settings(
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/python/bin/activate'),
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/%s/bin/remote_data.sh' % fabric.api.env.SITENAME)):
+#         fabric.api.run('python manage.py reset --noinput menus')
+#
+#
+# def sync_awsDB(push=False):
+#     """
+#     Run the django database maintenance commands within the AWS server instance
+#     """
+#
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     print(fabric.colors.yellow("Initializing/updating database..."))
+#
+#     with fabric.api.settings(
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/python/bin/activate'),
+#                         fabric.api.prefix('source ~/django/%s/bin/remote_data.sh' % fabric.api.env.SITENAME)):
+#
+#         # Update the database and link all media files
+#         fabric.api.run('python manage.py syncdb --noinput --verbosity=0')
+#         fabric.api.run('python manage.py migrate --verbosity=0')
+#
+#
+# def sync_awsStaticfiles():
+#     """
+#     Link the static files from the various modules into a common file tree for serving up on Apache
+#     """
+#
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     print(fabric.colors.yellow("Collecting static files from included modules..."))
+#
+#
+#     ###TODO: the directory should be puled from the settings.py file
+#     with fabric.api.settings(
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/python/bin/activate'),
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/%s/bin/remote_data.sh' % fabric.api.env.SITENAME)):
+#
+#         # Link the media files
+#
+#         if fabric.contrib.files.exists('~/django/%s/httpdocs/static' % fabric.api.env.SITENAME):
+#             fabric.api.sudo('rm -rf ~/django/%s/httpdocs/static' % fabric.api.env.SITENAME)
+#         if not fabric.contrib.files.exists('~/django/%s/httpdocs/media' % fabric.api.env.SITENAME):
+#             fabric.api.sudo('mkdir -p ~/django/%s/httpdocs/media' % fabric.api.env.SITENAME)
+#         fabric.api.run('python manage.py collectstatic -l --noinput --verbosity=0')
+#
+# def set_awsApacheconf(domain=None):
+#     """
+#     Enable the Apache config
+#     """
+#
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     if not domain:
+#         fabric.api.prompt('Base domain to host as:', 'domain', fabric.api.env.SITENAME + ".com")
+#     else:
+#         fabric.api['domain']=domain
+#
+#     fabric.api.env['django_base_dir'] = "/home/%s/django/" % fabric.api.env.AWS_USER
+#
+#     print(fabric.colors.yellow("Creating and installing Apache configuration file..."))
+#
+#     # upload the settings.py and apache config templates to project/website
+#     target = "/etc/apache2/sites-available/%s.conf" % fabric.api.env.domain
+#     template = os.path.join('etc','apache2_vhost.conf')
+#     fabric.operations.put(template, target, use_sudo=True)
+#
+#     if fabric.contrib.files.exists('/etc/apache2/sites-enabled/000-default') or fabric.contrib.files.exists('/etc/apache2/sites-enabled/default'):
+#         fabric.api.prompt('Disable [000-]default? (y/n) ', 'nopchdflt')
+#         if fabric.api.env.nopchdflt == 'y':
+#             if fabric.contrib.files.exists('/etc/apache2/sites-enabled/000-default'):
+#                 fabric.api.sudo('a2dissite 000-default')
+#             if fabric.contrib.files.exists('/etc/apache2/sites-enabled/default'):
+#                 fabric.api.sudo('a2dissite default')
+#
+#     fabric.api.sudo('a2ensite %s.conf' % fabric.api.env.domain)
+#
+# def cmd_awsApacheRestart():
+#     """
+#     Restart Apache
+#     """
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     print(fabric.colors.yellow("Graceful Apache..."))
+#
+#     fabric.api.sudo('apache2ctl graceful')
+#
+# def cmd_terminateInstance():
+#     """terminate instance and remove from .aws_fabric"""
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     print fabric.colors.red('You are about to TERMINATE an instance. This CANNOT be undone.')
+#     print fabric.colors.red('!!!!!!!!!! You will LOSE all its DATA. !!!!!!!!!!!!!!!!!!!!!!!')
+#     print 'id: %s ip_address: %s' % (instance.id, instance.ip_address)
+#     output = raw_input('\nTo proceed, type the ip address of this instance: ')
+#     # terminate instance
+#     if output == instance.ip_address:
+#         instance.terminate()
+#     # remove instance from .aws_fabric
+#     path = fabric.api.env.get('rcfile')
+#     if isfile(path):
+#         with open(path) as file:
+#             new_lines = [line for line in file if 'AWS_INSTANCE_ID' not in line]
+#         with open(path,'w') as file:
+#             file.writelines(new_lines)
+#     print fabric.colors.yellow('\ninstance terminated')
+#
+# def _list_keys_on_remote(id_only=False):
+#     """get ssh keys on remote"""
+#     with fabric.api.hide('everything'):
+#         output = fabric.api.run('cat ~/.ssh/authorized_keys')
+#     if id_only:
+#         return [line.split()[-1] for line in output.splitlines()]
+#     else:
+#         return output.splitlines()
+#
+# def cmd_rmKey():
+#     """rm keys from remote"""
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#     ids = _list_keys_on_remote(id_only=True)
+#
+#     def prompt_for_delete(): # local func so it can easily be repeated
+#         print fabric.colors.yellow("\n========================\nThese keys are installed.")
+#         for num, id in enumerate(ids):
+#             print '(%s) %s' % (num, id)
+#         print fabric.colors.yellow('\nEnter the numbers of the keys to delete, seperated by spaces.')
+#         # get keys to delete
+#         input = raw_input('nums: ')
+#         to_delete = [int(num) for num in input.split() if num.isdigit()]
+#         to_delete = filter(lambda x: 0 <= x < len(ids), to_delete)
+#         # validate selection, to prevent terrible crisis
+#         if not to_delete:
+#             print fabric.colors.red('\nYou didnt choose anything. Lets start over...')
+#             prompt_for_delete()
+#         if len(to_delete) >= len(ids):
+#             print fabric.colors.red('\nDO NOT delete all keys. you will be LOCKED OUT permanently.')
+#             prompt_for_delete()
+#         key_id, key_value = get_sshKey()
+#         if ['fail' for num in to_delete if ids[num]==key_id ]:
+#             print fabric.colors.red('\nDUDE. Do NOT delete you own key. Get a grip...')
+#             prompt_for_delete()
+#         # print selection and confirm
+#         print fabric.colors.yellow('\nYou would like to delete:')
+#         for num in sorted(to_delete):
+#             print '(%s) %s' % (num, ids[num])
+#         output = raw_input('\nIs this correct? ' + fabric.colors.yellow('[yes|no]') + ' : ')
+#         # update the keys
+#         if output == 'yes':
+#             old_keys = enumerate(_list_keys_on_remote())
+#             new_keys = [key for num, key in old_keys if num not in to_delete]
+#             new_keys =  '\n'.join(new_keys)
+#             with fabric.api.hide('everything'):
+#                 fabric.api.run('echo "%s" > ~/.ssh/authorized_keys' % new_keys)
+#             to_print =  fabric.colors.yellow('\ndeleted keys ')
+#             to_print += fabric.colors.yellow(' and ').join([ids[num] for num in to_delete])
+#             to_print += fabric.colors.yellow(' from remote.')
+#             print to_print
+#         # if chose not to proceed, start over
+#         else:
+#             prompt_for_delete()
+#
+#     prompt_for_delete() # call the func
+#
+# def cmd_addKey(keyfile=None):
+#     """
+#     add keys to remote
+#     """
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#     print(fabric.colors.yellow("Enter ssh pub keys, one per line.\nEnter blank line to terminate input."))
+#     # prompt for ssh keys
+#     keys = []
+#     while True:
+#         output = raw_input('ssh pub key: ')
+#         if output:
+#             keys.append(output)
+#         else:
+#             break
+#     # add keys to remote
+#     for key in keys:
+#         with fabric.api.hide('everything'):
+#             fabric.api.run('echo "%s" >> ~/.ssh/authorized_keys' % key)
+#     print(fabric.colors.yellow("keys have been added to remote instance."))
+#
+# def cmd_listKeys():
+#     """list the id/user of all installed ssh keys on remote instance"""
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#     print(fabric.colors.yellow("Pub Key IDs..."))
+#     print '\n'.join(_list_keys_on_remote(id_only=True))
+#
+# def cmd_getIP():
+#     """print the ip of our instance"""
+#     get_sshKey()
+#     instance = get_awsInstance(create=False)
+#     if instance:
+#         print instance.ip_address
+#     else:
+#         print 'no instance created yet'
+#
+# def cmd_awsShell():
+#     """
+#     Open an interactive shell on the AWS server instance
+#     """
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#     fabric.api.open_shell()
+#
+#
+# #noinspection PyUnusedLocal
+# def cmd_awsManage(*args, **options):
+#     """
+#     Run any series of available Django command in the aws instance
+#     """
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     ###TODO: Clean this up so that it accepts options like the local command does
+#
+#     with fabric.api.settings(
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/python/bin/activate'),
+#                         fabric.api.cd('~/django/%s' % fabric.api.env.SITENAME),
+#                         fabric.api.prefix('source ~/django/%s/bin/remote_data.sh' % fabric.api.env.SITENAME)):
+#
+#         for cmd in args[0]:
+#             fabric.api.run(command='python manage.py %s' % cmd)
+#             #print('python manage.py %s' % cmd)
+#
+#
+# def set_awsPermissions():
+#     """
+#     Set file permissions to usable values
+#     """
+#
+#     get_sshKey()
+#     instance = get_awsInstance()
+#     fabric.api.env.host_string = instance.ip_address
+#
+#     print(fabric.colors.yellow("Settings apropriate default permissions on project files..."))
+#
+#     if not fabric.contrib.files.exists('~/django/%s/httpdocs/media' % fabric.api.env.SITENAME):
+#         fabric.api.sudo('mkdir -p ~/django/%s/httpdocs/media' % fabric.api.env.SITENAME)
+#
+#     fabric.api.sudo('chown -R %s:%s ~/django/%s/httpdocs/media' % (fabric.api.env.AWS_USER, fabric.api.env.AWS_HTTPD_GROUP, fabric.api.env.SITENAME))
+#     fabric.api.sudo('chmod -R ug+rw ~/django/%s/httpdocs/media' % (fabric.api.env.SITENAME))
+#
+#     # Add access to the webserver to write into the cache directory
+#     fabric.api.sudo('chown -R %s:%s ~/django/%s/' % (fabric.api.env.AWS_USER, fabric.api.env.AWS_HTTPD_GROUP, fabric.api.env.SITENAME))
+#     fabric.api.sudo('chmod -R ug+rw ~/django/%s/' % (fabric.api.env.SITENAME))
+#
+#
+#
+# class RESTRequest(Request):
+#     def __init__(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None):
+#         Request.__init__(self, url, data, headers, origin_req_host, unverifiable)
+#         method = method
+#
+#     def get_method(self):
+#         if method:
+#             return method
+#         return Request.get_method(self)
+#
+# class DeployKey():
+#
+#     def __init__(self, spice_repo=None, repo_owner=None, owner_passwd=None):
+#         spice_repo = spice_repo
+#         repo_owner = repo_owner
+#         owner_passwd = owner_passwd
+#         #if owner is None:
+#             #print "What would you like to do?"
+#             #print ""
+#             #print "(g)et a listing of a repositories deploy keys"
+#             #print "(a)uthorize a deploy key with BitBucket"
+#             #print "(d)eauthorize a deploy key with BitBucket"
+#             #print ""
+#             #reply = raw_input("[")
+#             #if reply == "g":
+#                 #pass
+#                 ##add definition for owner,owner_passwd,spice_repo cli
+#                 ##getKeys()
+#             #elif reply == "a":
+#                 #pass
+#                 ##postKey(ssh_key,key_label)
+#             #elif reply == "d":
+#                 #pass
+#                 ##add addition prompt for ssh keyid preceded by readout of key choices by 'label' and 'ak'
+#                 ##readout via 'for item in' sort of thing....?
+#                 ##delKey()
+#             #else:
+#                 #return False
+#
+#     def decode_list(self, jsonData):
+#         rv = []
+#         for item in jsonData:
+#             if isinstance(item, unicode):
+#                 item = item.encode('utf-8')
+#             elif isinstance(item, list):
+#                 item = decode_list(item)
+#             elif isinstance(item, dict):
+#                 item = decode_dict(item)
+#             rv.append(item)
+#         return rv
+#
+#     def decode_dict(self, jsonData):
+#         rv = {}
+#         for key, value in jsonData.iteritems():
+#             if isinstance(key, unicode):
+#                key = key.encode('utf-8')
+#             if isinstance(value, unicode):
+#                value = value.encode('utf-8')
+#             elif isinstance(value, list):
+#                value = decode_list(value)
+#             elif isinstance(value, dict):
+#                value = decode_dict(value)
+#             rv[key] = value
+#         return rv
+#
+#     def getCred(self):
+#         credentials = b64encode("{0}:{1}".format(owner, owner_passwd).encode()).decode("ascii")
+#         return credentials
+#
+#     def getURL(self):
+#         url = "https://api.bitbucket.org/1.0/repositories/%s/%s/deploy-keys" % (owner, spice_repo)
+#         return url
+#
+#     def getHeaders(self):
+#         headers = {'Authorization': "Basic " + getCred()}
+#         return headers
+#
+#     def getKeys(self):
+#         request = RESTRequest(url=getURL(), headers=getHeaders(), method="GET")
+#         connection = urlopen(request)
+#         content = connection.read()
+#         return json.loads(content, object_hook=decode_dict)
+#
+#     def postKey(self,ssh_key,key_label):
+#         data = urlencode({"key": ssh_key, "label": key_label})
+#         request = RESTRequest(url=getURL(), headers=getHeaders(), data=data, method="POST")
+#         connection = urlopen(request)
+#         connection.read()
+#
+#     def delKey(self,key_id):
+#         request = RESTRequest(url="%s/%s" % (getURL(), key_id), headers=getHeaders(), method="DELETE")
+#         connection = urlopen(request)
+#         connection.read()

File djaboto/management/fabfile/__init__.py

 __author__ = 'growlf'
 
-from fabric.api import task, run
+from fabric import colors
+from fabric.api import task, run, env, prompt
 from djaboto.debian import install_system
+import os, sys, boto
 
 
 def gitReady(target_dir, git_url=None):
         if git_url:
             repository = git.Repo.clone_from(git_url, target_dir)
 
+@task
+def check_os():
+    """
+    Check the local operating system
+    """
+    import platform
+    is_64bits = sys.maxsize > 2**32
+
+    print("-"*55)
+    print platform.machine()
+    if platform.system() == 'Linux':
+        print platform.linux_distribution()[0]
+    print platform.system()
+
+    ###TODO: if Ubuntu, Linux - install all system modules
+    ###TODO: if Ubuntu, Linux - link the correct PIL libs
+    ###TODO: offer to reboot
+
+
 
 @task
 def check_pve():
     """
-    Check the python virtual environment for possible upgrades
+    Check the local python virtual environment for possible upgrades
     """
     import pip, xmlrpclib
 
             pkg_info = '{dist.project_name} {dist.version}'.format(dist=dist)
             print '{pkg_info:40} {msg}'.format(pkg_info=pkg_info, msg=msg)
 
+    ###TODO: check the local requirements.txt if it exists
+
 @task
 def check_debian():
     """
     pass
 
 @task
-def awsdeploy():
+def create_instance():
     """
     Create instance and git clone the site on the created instance
     Steps:
-    - if FIRST_RUN, then create an instance
-    - if FIRST_RUN, then  add all system modules and updates - then restart
-    - if FIRST_RUN, then  install and enable Apache config for site
-    - if FIRST_RUN, then  install deployment key
-    - if FIRST_RUN, then  makeppi
-    - if FIRST_RUN makedb (account, permissions)
-    - if FIRST_RUN, then  makedve with project requirements.txt file
-    - if FIRST_RUN, then  git clone the site
-      else: git pull
+    - create an instance
+    - system modules and updates - then restart
+    - install and enable Apache config for site
+    - install deployment key
+    - makeppi
+    - makedb (account, permissions)
+    - makedve with project requirements.txt file
+    - git clone the site
     - Cleanup and bump Apache
         rm -rf httpdocs/static/ && \
             ./manage.py clean_pyc && \
     """
 
 
-    run("mkdir -p ~/django")
-    run("cd ~/django")
-    run("mkdir bin/0a_makeppi python")
+    #run("mkdir -p ~/django")
+    #run("cd ~/django")
+    #run("mkdir bin/0a_makeppi python")
+
+@task
+def settings():
+    """
+    Display fabric and boto settings
+    """
+
+    print
+    print("-"*55)
+    for setting in env:
+        if env[setting]:
+            print("%55s : %-20s" % ( colors.yellow(setting), colors.cyan( env[setting])))
+    print("-"*55)
+    print("%55s : %-20s" % (colors.yellow('boto debug'), colors.cyan( boto.config.getboolean('Boto','debug') )))
+    print("%55s : %-20s" % (colors.yellow('aws_access_key_id'), colors.cyan( boto.config.get('Credentials','aws_access_key_id') )))
+    print("%55s : %-20s" % (colors.yellow('aws_secret_access_key'), colors.cyan( boto.config.get('Credentials','aws_secret_access_key') )))
+    print
+
+@task
+def list_instances():
+    """
+    List all AWS instances for the configured ID
+    """
+    from djaboto.aws import get_awsInstanceList
+    instance_list = get_awsInstanceList()
+    if instance_list:
+        for instance in instance_list:
+            print('%s) %s (%s-%s)\t%s (%s/%s/%s)\t%s (%s)' % (
+                colors.yellow(len(instance_list)),
+                instance.id, instance.instance_type, instance.state,
+                instance.image_id, instance.region.name, instance.architecture, instance.root_device_type,
+                instance.public_dns_name, instance.ip_address,
+                ))
+    else:
+        print("No instances found.")
+
+    return instance_list
+
+@task
+def instance():
+    """
+    List information about the selected instance
+    """
+
+    from djaboto.aws import get_awsInstance
+    instance = get_awsInstance()
+
+    if instance:
+        print("%55s: %s" % (colors.yellow('Instance'),instance.id))
+        print("%55s: %s" % (colors.yellow('State'),instance.state))
+        print("%55s: %s" % (colors.yellow('Architecture'),instance.architecture))
+        print("%55s: %s" % (colors.yellow('Type'),instance.instance_type))
+        print("%55s: %s" % (colors.yellow('Address'),instance.ip_address))
+        print("%55s: %s" % (colors.yellow('Image'),instance.image_id))
+        print("%s" % (instance.region))
+    else:
+        print("No instance is configured.")
+        list_instances()
+        prompt("Select an instance from above or '0' to create one:", instance_choice)
+        print env[instance_choice]