import boto from fabric.decorators import serial from ssh_tunnel import setup_tunnel import socket from fabric.api import env, task, abort from fabric.colors import red import logging def hosts_by_tag(tag, value): """ Return a list of all hosts that have the specified value for the specified tag """ return hosts_by_tags(**{tag: value}) def hosts_by_tags(**tags): """ Return a list of all hosts that have the specified value for the specified tags. Tag values are allowed to include wildcards If no variant tag is specified, this command will ignore all hosts that have a variant specified. """ if 'env' in tags: tags['environment'] = tags['env'] del(tags['env']) ec2 = boto.connect_ec2() hosts = [] for res in ec2.get_all_instances(filters={'tag:' + tag: value for tag, value in tags.iteritems() if value != '*'}): for inst in res.instances: if inst.state == "running": if (inst.public_dns_name): hosts.append(inst.public_dns_name) else: hosts.append(inst.private_dns_name) print hosts return hosts def _fleet(): ec2 = boto.connect_ec2() hosts = [] for res in ec2.get_all_instances(): for inst in res.instances: if inst.state == "running": try: instance_name = inst.tags['Name'] except: logging.warning("Instance with id {id} and {dns} has no assigned Name.".format(id=inst.id,dns=inst.public_dns_name)) host_to_add = instance_name + "." + DOMAIN # fallback to the public hostname if the m.edx.org # name doesn't exist try: socket.gethostbyname(host_to_add.replace(':22','')) except socket.error: if inst.public_dns_name: host_to_add = inst.public_dns_name if host_to_add: hosts.append(host_to_add) return hosts def exemplar(**tags): """ Return the hostname of one host from the specified set of tags, or None if there is no such host """ hosts = hosts_by_tags(**tags) if hosts: return hosts[0] else: return None @task(alias='exemplar') def exemplar_from_tags(**tags): env.hosts.append(exemplar(**tags)) @task(aliases=['tag', 'tags']) def by_tags(**tags): """ Add all running hosts that match the tag names provided as keyword arguments. """ env.hosts.extend(hosts_by_tags(**tags)) env.hosts.sort() env.hosts = setup_tunnel(env.hosts) @task(aliases=['fleet']) def fleet(): """ Return a list of all hosts available and running via the default AWS credentials. Your ability to operate on these hosts will depend upon the ssh credentials that you are using to drive fab. There is likely to be a mismatch between what hosts you can see via IAM managed AWS credentials and which hosts you can actually connect to even if you are using highly privileged AWS pems. """ hosts = _fleet() env.hosts.extend(hosts) env.hosts.sort() env.hosts = setup_tunnel(env.hosts)