Esempio n. 1
0
def create_aws_instances():
    """
    Create AWS instances and let Fabric point to them

    This method creates AWS instances and points the fabric environment to them with
    the current public IP and username.
    """

    default_if_empty(env, 'AWS_KEY_NAME', DEFAULT_AWS_KEY_NAME)
    default_if_empty(env, 'AWS_INSTANCE_NAME', default_instance_name)

    # Create the key pair and security group if necessary
    conn = connect()
    aws_create_key_pair(conn)
    sgid = check_create_aws_sec_group(conn)

    # Create the instance in AWS
    host_names = create_instances(conn, sgid)

    # Update our fabric environment so from now on we connect to the
    # AWS machine using the correct user and SSH private key
    env.hosts = host_names
    env.key_filename = key_filename(env.AWS_KEY_NAME)
    # Instances have started, but are not usable yet, make sure SSH has started
    puts('Started the instance(s) now waiting for the SSH daemon to start.')
    execute(check_ssh, timeout=300)
Esempio n. 2
0
def check_create_aws_sec_group(conn):
    """
    Check whether the security group exists
    """
    import boto.exception

    default_if_empty(env, 'AWS_SEC_GROUP', DEFAULT_AWS_SEC_GROUP)
    default_if_empty(env, 'AWS_SEC_GROUP_PORTS', DEFAULT_AWS_SEC_GROUP_PORTS)

    app_secgroup = env.AWS_SEC_GROUP
    sec = conn.get_all_security_groups()
    conn.close()
    exfl = False
    for sg in sec:
        if sg.name.upper() == app_secgroup and sg.vpc_id == env.AWS_VPC_ID:
            puts(
                green("AWS Security Group {0} exists ({1})".format(
                    app_secgroup, sg.id)))
            exfl = True
            appsg = sg
    if not exfl:
        # Not found, create a new one
        appsg = conn.create_security_group(app_secgroup,
                                           '{0} default permissions'.format(
                                               APP_name()),
                                           vpc_id=env.AWS_VPC_ID)

    # make sure the correct ports are open
    for port in env.AWS_SEC_GROUP_PORTS:
        try:
            appsg.authorize('tcp', port, port, '0.0.0.0/0')
        except boto.exception.EC2ResponseError as error:
            if not error.code == 'InvalidPermission.Duplicate':
                raise error
    return appsg.id
Esempio n. 3
0
def connect():
    import boto.vpc
    default_if_empty(env, 'AWS_PROFILE', DEFAULT_AWS_PROFILE)
    default_if_empty(env, 'AWS_REGION', DEFAULT_AWS_REGION)
    conn = boto.vpc.connect_to_region(env.AWS_REGION,
                                      profile_name=env.AWS_PROFILE)
    default_if_empty(env, 'AWS_KEY', conn.access_key)
    default_if_empty(env, 'AWS_SECRET', conn.secret_key)

    return conn
Esempio n. 4
0
def create_instances(conn, sgid):
    """
    Create one or more EC2 instances
    """

    default_if_empty(env, 'AWS_AMI_NAME', DEFAULT_AWS_AMI_NAME)
    default_if_empty(env, 'AWS_INSTANCE_TYPE', DEFAULT_AWS_INSTANCE_TYPE)
    default_if_empty(env, 'AWS_INSTANCES', DEFAULT_AWS_INSTANCES)
    puts("About to create instance {0} of type {1}.".format(
        env.AWS_AMI_NAME, env.AWS_INSTANCE_TYPE))

    n_instances = int(env.AWS_INSTANCES)
    if n_instances > 1:
        names = [
            "%s_%d" % (env.AWS_INSTANCE_NAME, i) for i in range(n_instances)
        ]
    else:
        names = [env.AWS_INSTANCE_NAME]
    puts('Creating instances {0}'.format(names))

    public_ips = None
    if 'AWS_ELASTIC_IPS' in env:

        public_ips = env.AWS_ELASTIC_IPS.split(',')
        if len(public_ips) != n_instances:
            abort("n_instances != #AWS_ELASTIC_IPS (%d != %d)" %
                  (n_instances, len(public_ips)))

        # Disassociate the public IPs
        for public_ip in public_ips:
            if not conn.disassociate_address(public_ip=public_ip):
                abort('Could not disassociate the IP {0}'.format(public_ip))

    if 'AMI_ID' in env:
        AMI_ID = env['AMI_ID']
        env.user = env['root']
    else:
        AMI_ID = AMI_INFO[env.AWS_AMI_NAME]['id']
        env.user = AMI_INFO[env.AWS_AMI_NAME]['root']

    interface = boto.ec2.networkinterface.NetworkInterfaceSpecification(
        subnet_id=env.AWS_SUBNET_ID,
        groups=[sgid],
        associate_public_ip_address=True)
    interfaces = boto.ec2.networkinterface.NetworkInterfaceCollection(
        interface)

    reservations = conn.run_instances(AMI_ID,
                                      instance_type=env.AWS_INSTANCE_TYPE,
                                      key_name=env.AWS_KEY_NAME,
                                      min_count=n_instances,
                                      max_count=n_instances,
                                      network_interfaces=interfaces)
    instances = reservations.instances

    # Sleep so Amazon recognizes the new instance
    for i in range(4):
        fastprint('.')
        time.sleep(5)

    # Are we running yet?
    iid = [x.id for x in instances]
    stat = conn.get_all_instance_status(iid)
    running = [x.state_name == 'running' for x in stat]
    puts('\nWaiting for instances to be fully available:\n')
    while sum(running) != n_instances:
        fastprint('.')
        time.sleep(5)
        stat = conn.get_all_instance_status(iid)
        running = [x.state_name == 'running' for x in stat]
    puts('.')  #enforce the line-end

    # Local user and host
    userAThost = userAtHost()

    # We save the user under which we install APP for later display
    nuser = APP_user()

    # Tag the instance
    for name, instance in zip(names, instances):
        conn.create_tags(
            [instance.id], {
                'Name': name,
                'Created By': userAThost,
                'APP User': nuser,
                'allocate-cost-to': APP_name(),
            })

    # Associate the IP if needed
    if public_ips:
        for instance, public_ip in zip(instances, public_ips):
            puts('Current DNS name is {0}. About to associate the Elastic IP'.
                 format(instance.dns_name))
            if not conn.associate_address(instance_id=instance.id,
                                          public_ip=public_ip):
                abort('Could not associate the IP {0} to the instance {1}'.
                      format(public_ip, instance.id))

    # Load the new instance data as the dns_name may have changed
    host_names = []
    for instance in instances:
        instance.update(True)
        print_instance(instance)
        host_names.append(str(instance.dns_name))
    return host_names
Esempio n. 5
0
def docker_image_repository():
    repo_name = "icrar/{0}".format(APP_name().lower())
    default_if_empty(env, 'DOCKER_IMAGE_REPOSITORY', repo_name)
    return env.DOCKER_IMAGE_REPOSITORY
Esempio n. 6
0
DEFAULT_AWS_INSTANCES = 1
DEFAULT_AWS_INSTANCE_NAME_TPL = '{0}'.format(
    APP_name() + '_{0}')  # gets formatted with the git branch name
DEFAULT_AWS_INSTANCE_TYPE = 't1.micro'
DEFAULT_AWS_KEY_NAME = 'icrar_ngas'
DEFAULT_AWS_SEC_GROUP = 'NGAS'  # Security group allows SSH and other ports
DEFAULT_AWS_SEC_GROUP_PORTS = [22, 80, 7777, 8888]

# Connection defaults
DEFAULT_AWS_PROFILE = 'NGAS'  # the default user profile to use
DEFAULT_AWS_REGION = 'us-east-1'  # The default region
DEFAULT_AWS_VPC_ID = 'vpc-0e2d88e4476b37393'  # The default developer VPC in region above
DEFAULT_AWS_SUBNET_ID = 'subnet-0bc37d21234d81577'  # The default subnet ID
# NOTE: Both the VPC and the subnet have been created manually

default_if_empty(env, 'AWS_VPC_ID', DEFAULT_AWS_VPC_ID)
default_if_empty(env, 'AWS_SUBNET_ID', DEFAULT_AWS_SUBNET_ID)


def connect():
    import boto.vpc
    default_if_empty(env, 'AWS_PROFILE', DEFAULT_AWS_PROFILE)
    default_if_empty(env, 'AWS_REGION', DEFAULT_AWS_REGION)
    conn = boto.vpc.connect_to_region(env.AWS_REGION,
                                      profile_name=env.AWS_PROFILE)
    default_if_empty(env, 'AWS_KEY', conn.access_key)
    default_if_empty(env, 'AWS_SECRET', conn.secret_key)

    return conn

Esempio n. 7
0
def APP_name():
    default_if_empty(env, 'APP_NAME', APP_NAME_DEFAULT)
    return env.APP_NAME
Esempio n. 8
0
def APP_repo_root():
    default_if_empty(env, 'APP_repo_root', APP_REPO_ROOT_DEFAULT)
    return env.APP_repo_root
Esempio n. 9
0
def APP_revision():
    default_if_empty(env, 'APP_REV', default_APP_revision)
    return env.APP_REV
Esempio n. 10
0
def APP_install_dir():
    key = 'APP_INSTALL_DIR_NAME'
    default_if_empty(env, key, APP_name().lower()+'_rt')
    if env[key].find('/') != 0: # make sure this is an absolute path
        env[key] = os.path.abspath(os.path.join(home(), env.APP_INSTALL_DIR_NAME))
    return env[key]
Esempio n. 11
0
def APP_user():
    default_if_empty(env, 'APP_USER', APP_USER)
    return env.APP_USER
Esempio n. 12
0
def APP_repo_git():
    default_if_empty(env, 'APP_REPO_GIT', APP_REPO_GIT_DEFAULT)
    return env.APP_REPO_GIT
Esempio n. 13
0
    create_user, get_linux_flavor, python_setup, check_python, \
    MACPORT_DIR
from fabfileTemplate.utils import is_localhost, home, default_if_empty, sudo, run, success,\
    info

# Don't re-export the tasks imported from other modules, only the ones defined
# here
__all__ = [
    'virtualenv_setup',
    'install_user_profile',
    'copy_sources',
    'install_and_check'
]

APP_NAME_DEFAULT = 'DEFAULT'
default_if_empty(env, 'APP_NAME', APP_NAME_DEFAULT)
# # The username to use by default on remote hosts where APP is being installed
# # This user might be different from the initial username used to connect to the
# # remote host, in which case it will be created first
APP_USER = env.APP_NAME.lower()

# # Name of the directory where APP sources will be expanded on the target host
# # This is relative to the APP_USER home directory
APP_SRC_DIR_NAME = env.APP_NAME.lower() + '_src'

# # Name of the directory where APP root directory will be created
# # This is relative to the APP_USER home directory
APP_ROOT_DIR_NAME = env.APP_NAME.upper()

# # Name of the directory where a virtualenv will be created to host the APP
# # software installation, plus the installation of all its related software