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
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
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
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)
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
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
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)
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