Beispiel #1
0
def get_ec2_security_group_id(name=None, verbose=0):
    from burlap.common import shelf, OrderedDict

    verbose = int(verbose)

    group_id = None
    conn = get_ec2_connection()
    groups = conn.get_all_security_groups()
    for group in groups:
        if verbose:
            print('group:', group.name, group.id)
        if group.name == name:
            group_id = group.id

    # Otherwise try the local cache.
    if not group_id:
        v = shelf.get('vm_ec2_security_group_ids', OrderedDict())
        group_id = v.get(name)

    if verbose:
        print(group_id)
    return group_id
Beispiel #2
0
def get_ec2_security_group_id(name=None, verbose=0):
    from burlap.common import shelf, OrderedDict
    
    verbose = int(verbose)
    
    group_id = None
    conn = get_ec2_connection()
    groups = conn.get_all_security_groups()
    for group in groups:
        if verbose:
            print('group:',group.name,group.id)
        if group.name == name:
            group_id = group.id
    
    # Otherwise try the local cache.
    if not group_id:
        v = shelf.get('vm_ec2_security_group_ids', OrderedDict())
        group_id = v.get(name)
        
    if verbose:
        print(group_id)
    return group_id
Beispiel #3
0
def get_or_create_ec2_instance(name=None,
                               group=None,
                               release=None,
                               verbose=0,
                               backend_opts=None):
    """
    Creates a new EC2 instance.

    You should normally run get_or_create() instead of directly calling this.
    """
    from burlap.common import shelf, OrderedDict
    from boto.exception import EC2ResponseError

    assert name, "A name must be specified."

    backend_opts = backend_opts or {}

    verbose = int(verbose)

    conn = get_ec2_connection()

    security_groups = get_or_create_ec2_security_groups()
    security_group_ids = [_.id for _ in security_groups]
    if verbose:
        print('security_groups:', security_group_ids)

    pem_path = get_or_create_ec2_key_pair()

    assert env.vm_ec2_ami, 'No AMI specified.'
    print('Creating EC2 instance from %s...' % (env.vm_ec2_ami, ))
    print(env.vm_ec2_zone)
    opts = backend_opts.get('run_instances', {})
    reservation = conn.run_instances(
        env.vm_ec2_ami,
        key_name=env.vm_ec2_keypair_name,
        #security_groups=env.vm_ec2_selected_security_groups,#conflicts with subnet_id?!
        security_group_ids=security_group_ids,
        placement=env.vm_ec2_zone,
        instance_type=env.vm_ec2_instance_type,
        subnet_id=env.vm_ec2_subnet_id,
        **opts)
    instance = reservation.instances[0]

    # Name new instance.
    # Note, creation is not instantious, so we may have to wait for a moment
    # before we can access it.
    while 1:
        try:
            if name:
                instance.add_tag(env.vm_name_tag, name)
            if group:
                instance.add_tag(env.vm_group_tag, group)
            if release:
                instance.add_tag(env.vm_release_tag, release)
            break
        except EC2ResponseError as e:
            #print('Unable to set tag: %s' % e)
            print('Waiting for the instance to be created...')
            if verbose:
                print(e)
            time.sleep(3)

    # Assign IP.
    allocation_id = None
    if env.vm_ec2_use_elastic_ip:
        # Initialize name/ip mapping since we can't tag elastic IPs.
        shelf.setdefault('vm_elastic_ip_mappings', OrderedDict())
        vm_elastic_ip_mappings = shelf.get('vm_elastic_ip_mappings')
        elastic_ip = vm_elastic_ip_mappings.get(name)
        if not elastic_ip:
            print('Allocating new elastic IP address...')
            addr = conn.allocate_address(
                domain=env.vm_ec2_allocate_address_domain)
            #allocation_id = addr.allocation_id
            #print('allocation_id:',allocation_id)
            elastic_ip = addr.public_ip
            print('Allocated address %s.' % elastic_ip)
            vm_elastic_ip_mappings[name] = str(elastic_ip)
            shelf.set('vm_elastic_ip_mappings', vm_elastic_ip_mappings)
            #conn.get_all_addresses()

        # Lookup allocation_id.
        all_eips = conn.get_all_addresses()
        for eip in all_eips:
            if elastic_ip == eip.public_ip:
                allocation_id = eip.allocation_id
                break
        print('allocation_id:', allocation_id)

        while 1:
            try:
                conn.associate_address(
                    instance_id=instance.id,
                    #public_ip=elastic_ip,
                    allocation_id=allocation_id,  # needed for VPC instances
                )
                print('IP address associated!')
                break
            except EC2ResponseError as e:
                #print('Unable to assign IP: %s' % e)
                print('Waiting to associate IP address...')
                if verbose:
                    print(e)
                time.sleep(3)

    # Confirm public DNS name was assigned.
    while 1:
        try:
            instance = get_all_ec2_instances(instance_ids=[instance.id])[0]
            #assert instance.public_dns_name, 'No public DNS name found!'
            if instance.public_dns_name:
                break
        except Exception as e:
            print('error:', e)
        except SystemExit as e:
            print('systemexit:', e)
        print('Waiting for public DNS name to be assigned...')
        time.sleep(3)

    # Confirm we can SSH into the server.
    #TODO:better handle timeouts? try/except doesn't really work?
    env.connection_attempts = 10
    while 1:
        try:
            with settings(warn_only=True):
                env.host_string = instance.public_dns_name
                ret = run_or_dryrun('who -b')
                #print 'ret.return_code:',ret.return_code
                if not ret.return_code:
                    break
        except Exception as e:
            print('error:', e)
        except SystemExit as e:
            print('systemexit:', e)
        print('Waiting for sshd to accept connections...')
        time.sleep(3)

    print("")
    print("Login with: ssh -o StrictHostKeyChecking=no -i %s %s@%s" \
        % (pem_path, env.user, instance.public_dns_name))
    print("OR")
    print("fab %(ROLE)s:hostname=%(name)s shell" %
          dict(name=name, ROLE=env.ROLE))

    ip = socket.gethostbyname(instance.public_dns_name)
    print("")
    print("""Example hosts entry:)
%(ip)s    www.mydomain.com # %(name)s""" % dict(ip=ip, name=name))
    return instance
Beispiel #4
0
def set_ec2_security_group_id(name, id):  # pylint: disable=redefined-builtin
    from burlap.common import shelf, OrderedDict
    v = shelf.get('vm_ec2_security_group_ids', OrderedDict())
    v[name] = str(id)
    shelf.set('vm_ec2_security_group_ids', v)
Beispiel #5
0
def list_instances(show=1,
                   name=None,
                   group=None,
                   release=None,
                   except_release=None):
    """
    Retrieves all virtual machines instances in the current environment.
    """
    from burlap.common import shelf, OrderedDict, get_verbose

    verbose = get_verbose()
    require('vm_type', 'vm_group')
    assert env.vm_type, 'No VM type specified.'
    env.vm_type = (env.vm_type or '').lower()
    _name = name
    _group = group
    _release = release
    if verbose:
        print('name=%s, group=%s, release=%s' % (_name, _group, _release))

    env.vm_elastic_ip_mappings = shelf.get('vm_elastic_ip_mappings')

    data = type(env)()
    if env.vm_type == EC2:
        if verbose:
            print('Checking EC2...')
        for instance in get_all_running_ec2_instances():
            name = instance.tags.get(env.vm_name_tag)
            group = instance.tags.get(env.vm_group_tag)
            release = instance.tags.get(env.vm_release_tag)
            if env.vm_group and env.vm_group != group:
                if verbose:
                    print(('Skipping instance %s because its group "%s" '
                        'does not match env.vm_group "%s".') \
                            % (instance.public_dns_name, group, env.vm_group))
                continue
            if _group and group != _group:
                if verbose:
                    print(('Skipping instance %s because its group "%s" '
                        'does not match local group "%s".') \
                            % (instance.public_dns_name, group, _group))
                continue
            if _name and name != _name:
                if verbose:
                    print(('Skipping instance %s because its name "%s" '
                        'does not match name "%s".') \
                            % (instance.public_dns_name, name, _name))
                continue
            if _release and release != _release:
                if verbose:
                    print(('Skipping instance %s because its release "%s" '
                        'does not match release "%s".') \
                            % (instance.public_dns_name, release, _release))
                continue
            if except_release and release == except_release:
                continue
            if verbose:
                print('Adding instance %s (%s).' \
                    % (name, instance.public_dns_name))
            data.setdefault(name, type(env)())
            data[name]['id'] = instance.id
            data[name]['public_dns_name'] = instance.public_dns_name
            if verbose:
                print('Public DNS: %s' % instance.public_dns_name)

            if env.vm_elastic_ip_mappings and name in env.vm_elastic_ip_mappings:
                data[name]['ip'] = env.vm_elastic_ip_mappings[name]
            else:
                data[name]['ip'] = socket.gethostbyname(
                    instance.public_dns_name)

        if int(show):
            pprint(data, indent=4)
        return data
    elif env.vm_type == KVM:
        #virsh list
        pass
    else:
        raise NotImplementedError
Beispiel #6
0
def get_or_create_ec2_instance(name=None, group=None, release=None, verbose=0, backend_opts={}):
    """
    Creates a new EC2 instance.
    
    You should normally run get_or_create() instead of directly calling this.
    """
    from burlap.common import shelf, OrderedDict
    from boto.exception import EC2ResponseError

    assert name, "A name must be specified."

    verbose = int(verbose)

    conn = get_ec2_connection()

    security_groups = get_or_create_ec2_security_groups()
    security_group_ids = [_.id for _ in security_groups]
    if verbose:
        print('security_groups:',security_group_ids)
    
    pem_path = get_or_create_ec2_key_pair()

    assert env.vm_ec2_ami, 'No AMI specified.'
    print('Creating EC2 instance from %s...' % (env.vm_ec2_ami,))
    print(env.vm_ec2_zone)
    opts = backend_opts.get('run_instances', {})
    reservation = conn.run_instances(
        env.vm_ec2_ami,
        key_name=env.vm_ec2_keypair_name,
        #security_groups=env.vm_ec2_selected_security_groups,#conflicts with subnet_id?!
        security_group_ids=security_group_ids,
        placement=env.vm_ec2_zone,
        instance_type=env.vm_ec2_instance_type,
        subnet_id=env.vm_ec2_subnet_id,
        **opts
    )
    instance = reservation.instances[0]
    
    # Name new instance.
    # Note, creation is not instantious, so we may have to wait for a moment
    # before we can access it.
    while 1:
        try:
            if name:
                instance.add_tag(env.vm_name_tag, name)
            if group:
                instance.add_tag(env.vm_group_tag, group)
            if release:
                instance.add_tag(env.vm_release_tag, release)
            break
        except EC2ResponseError as e:
            #print('Unable to set tag: %s' % e)
            print('Waiting for the instance to be created...')
            if verbose:
                print(e)
            time.sleep(3)

    # Assign IP.
    allocation_id = None
    if env.vm_ec2_use_elastic_ip:
        # Initialize name/ip mapping since we can't tag elastic IPs.
        shelf.setdefault('vm_elastic_ip_mappings', OrderedDict())
        vm_elastic_ip_mappings = shelf.get('vm_elastic_ip_mappings')
        elastic_ip = vm_elastic_ip_mappings.get(name)
        if not elastic_ip:
            print('Allocating new elastic IP address...')
            addr = conn.allocate_address(domain=env.vm_ec2_allocate_address_domain)
            #allocation_id = addr.allocation_id
            #print('allocation_id:',allocation_id)
            elastic_ip = addr.public_ip
            print('Allocated address %s.' % elastic_ip)
            vm_elastic_ip_mappings[name] = str(elastic_ip)
            shelf.set('vm_elastic_ip_mappings', vm_elastic_ip_mappings)
            #conn.get_all_addresses()
        
        # Lookup allocation_id.
        all_eips = conn.get_all_addresses()
        for eip in all_eips:
            if elastic_ip == eip.public_ip:
                allocation_id = eip.allocation_id
                break
        print('allocation_id:',allocation_id)
            
        while 1:
            try:
                conn.associate_address(
                    instance_id=instance.id,
                    #public_ip=elastic_ip,
                    allocation_id=allocation_id, # needed for VPC instances
                    )
                print('IP address associated!')
                break
            except EC2ResponseError as e:
                #print('Unable to assign IP: %s' % e)
                print('Waiting to associate IP address...')
                if verbose:
                    print(e)
                time.sleep(3)
    
    # Confirm public DNS name was assigned.
    while 1:
        try:
            instance = get_all_ec2_instances(instance_ids=[instance.id])[0]
            #assert instance.public_dns_name, 'No public DNS name found!'
            if instance.public_dns_name:
                break
        except Exception as e:
            print('error:',e)
        except SystemExit as e:
            print('systemexit:',e)
            pass
        print('Waiting for public DNS name to be assigned...')
        time.sleep(3)

    # Confirm we can SSH into the server.
    #TODO:better handle timeouts? try/except doesn't really work?
    env.connection_attempts = 10
    while 1:
        try:
            with settings(warn_only=True):
                env.host_string = instance.public_dns_name
                ret = run_or_dryrun('who -b')
                #print 'ret.return_code:',ret.return_code
                if not ret.return_code:
                    break
        except Exception as e:
            print('error:',e)
        except SystemExit as e:
            print('systemexit:',e)
            pass
        print('Waiting for sshd to accept connections...')
        time.sleep(3)

    print("")
    print("Login with: ssh -o StrictHostKeyChecking=no -i %s %s@%s" \
        % (pem_path, env.user, instance.public_dns_name))
    print("OR")
    print("fab %(ROLE)s:hostname=%(name)s shell" % dict(name=name, ROLE=env.ROLE))
    
    ip = socket.gethostbyname(instance.public_dns_name)
    print("")
    print("""Example hosts entry:)
%(ip)s    www.mydomain.com # %(name)s""" % dict(ip=ip, name=name))
    return instance
Beispiel #7
0
def set_ec2_security_group_id(name, id):
    from burlap.common import shelf, OrderedDict
    v = shelf.get('vm_ec2_security_group_ids', OrderedDict())
    v[name] = str(id)
    shelf.set('vm_ec2_security_group_ids', v)
Beispiel #8
0
def list_instances(show=1, name=None, group=None, release=None, except_release=None, verbose=0):
    """
    Retrieves all virtual machines instances in the current environment.
    """
    from burlap.common import shelf, OrderedDict
    
    verbose = int(verbose)
    require('vm_type', 'vm_group')
    assert env.vm_type, 'No VM type specified.'
    env.vm_type = (env.vm_type or '').lower()
    _name = name
    _group = group
    _release = release
    if verbose:
        print('name=%s, group=%s, release=%s' % (_name, _group, _release))
        
    env.vm_elastic_ip_mappings = shelf.get('vm_elastic_ip_mappings')
        
    data = type(env)()
    if env.vm_type == EC2:
        for instance in get_all_running_ec2_instances():
            name = instance.tags.get(env.vm_name_tag)
            group = instance.tags.get(env.vm_group_tag)
            release = instance.tags.get(env.vm_release_tag)
            if env.vm_group and group and env.vm_group != group:
                if verbose:
                    print(('Skipping instance %s because its group "%s" '
                        'does not match env.vm_group "%s".') \
                            % (instance.public_dns_name, group, env.vm_group))
                continue
            if _group and group and group != _group:
                if verbose:
                    print(('Skipping instance %s because its group "%s" '
                        'does not match local group "%s".') \
                            % (instance.public_dns_name, group, _group))
                continue
            if _name and name and name != _name:
                if verbose:
                    print(('Skipping instance %s because its name "%s" '
                        'does not match name "%s".') \
                            % (instance.public_dns_name, name, _name))
                continue
            if _release and release and release != _release:
                if verbose:
                    print(('Skipping instance %s because its release "%s" '
                        'does not match release "%s".') \
                            % (instance.public_dns_name, release, _release))
                continue
            if except_release and release == except_release:
                continue
            if verbose:
                print('Adding instance %s (%s).' \
                    % (name, instance.public_dns_name))
            data.setdefault(name, type(env)())
            data[name]['id'] = instance.id
            data[name]['public_dns_name'] = instance.public_dns_name
            if verbose:
                print('Public DNS: %s' % instance.public_dns_name)
            
            if env.vm_elastic_ip_mappings and name in env.vm_elastic_ip_mappings:
                data[name]['ip'] = env.vm_elastic_ip_mappings[name]
            else:
                data[name]['ip'] = socket.gethostbyname(instance.public_dns_name)
                
        if int(show):
            pprint(data, indent=4)
        return data
    elif env.vm_type == KVM:
        #virsh list
        pass
    else:
        raise NotImplementedError
Beispiel #9
0
def set_ec2_security_group_id(name, id):
    from burlap.common import shelf, OrderedDict
    v = shelf.get('vm_ec2_security_group_ids', OrderedDict())
    v[name] = str(id)
    shelf.set('vm_ec2_security_group_ids', v)