· 6 years ago · Sep 15, 2019, 07:18 AM
1#! /usr/bin/env python
2
3import argparse
4import os
5import sys
6
7import boto.ec2
8
9
10def parse_args():
11 parser = argparse.ArgumentParser(
12 description='Display EC2 hosts in ssh-config or hosts file format',
13 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
14
15 parser.add_argument('-k', '--aws-key', type=str,
16 default=os.environ.get("AWS_ACCESS_KEY_ID"),
17 help='Amazon EC2 Key, defaults to ENV[AWS_ACCESS_KEY_ID]')
18 parser.add_argument('-s', '--aws-secret', type=str,
19 default=os.environ.get("AWS_SECRET_ACCESS_KEY"),
20 help='Amazon EC2 Secret, defaults to ENV[AWS_SECRET_ACCESS_KEY]')
21 parser.add_argument('-r', '--region', type=str,
22 default=os.environ.get("AWS_EC2_REGION"),
23 help='Amazon EC2 Region, defaults to us-east-1 or ENV[AWS_EC2_REGION]')
24
25 parser.add_argument('-t', '--tag', type=str,
26 default='Name', dest='name_tag',
27 help="Amazon EC2 Tag for instance name, defaults to 'Name'")
28
29 parser.add_argument('--prefix', type=str, default='',
30 help='prefix to the instance name')
31 parser.add_argument('--suffix', type=str, default='',
32 help='suffix to the instance name')
33 parser.add_argument('--domain', type=str, default='',
34 help='domain to the instance name')
35
36 parser.add_argument('--format', choices=['ssh', 'hosts'], default='ssh',
37 help='output format. ssh-config or hosts file style. ')
38 parser.add_argument('--filter', type=str, action='append', default=[],
39 help=('Amazon EC2 API filter to limit the result returned. '
40 '(Example: --filter instance-state-name=running)'))
41 parser.add_argument('--use-elastic-ip', action='store_true',
42 help='use elastic IP instead of private IP')
43
44 return parser.parse_args()
45
46
47def main(opts):
48 aws_key = opts['aws_key']
49 aws_secret = opts['aws_secret']
50 region = opts['region']
51 name_tag = opts['name_tag']
52 prefix = opts['prefix']
53 suffix = opts['suffix']
54 domain = opts['domain']
55 format = opts['format']
56 filter = opts['filter']
57 use_elastic_ip = opts['use_elastic_ip']
58
59 filters = dict([f.split('=', 1) for f in filter])
60 if domain and not domain.startswith('.'):
61 domain = '.' + domain
62
63 ip_addr_attr = 'ip_address' if use_elastic_ip else 'private_ip_address'
64
65 # validation
66 if not aws_key or not aws_secret:
67 if not aws_key:
68 print >> sys.stderr,\
69 "AWS_ACCESS_KEY_ID not set in environment and not",\
70 "specified by -k AWS_KEY or --aws-key AWS_KEY"
71 if not aws_secret:
72 print >> sys.stderr,\
73 "AWS_SECRET_ACCESS_KEY not set in envoronment and not",\
74 "specified by -s AWS_SECRET or --aws-secret AWS_SECRET"
75 sys.exit(2)
76
77 region = region and boto.ec2.get_region(region,
78 aws_access_key_id=aws_key,
79 aws_secret_access_key=aws_secret)
80
81 conn = boto.ec2.connection.EC2Connection(aws_key, aws_secret,
82 region=region)
83
84 # list of (instance_name, ip_address)
85 instances = get_ec2_instances(conn, name_tag, ip_addr_attr, filters)
86
87 # sort by name
88 instances = sorted(instances)
89
90 # print out
91 print_fn = print_ssh_config if format == 'ssh' else print_hosts
92 print_fn(instances, prefix, suffix, domain)
93
94
95def get_ec2_instances(conn, name_tag, ip_addr_attr, filters):
96 instances = [] # (instance_name, ip_address)
97 reservations = conn.get_all_instances(filters=filters)
98 for reservation in reservations:
99 for instance in reservation.instances:
100 instance_name = instance.tags.get(name_tag)
101 ip_address = getattr(instance, ip_addr_attr)
102 if instance_name and ip_address:
103 pair = (instance_name, ip_address)
104 instances.append(pair)
105 return instances
106
107
108def print_ssh_config(instances, prefix, suffix, domain):
109 """ Print out as ssh-config file format """
110 for instance_name, ip_address in instances:
111 instance_name = prefix + instance_name + suffix + domain
112 # double quote if name contains space
113 instance_name = '"{0}"'.format(
114 instance_name) if ' ' in instance_name else instance_name
115 print "Host %s" % instance_name
116 print "Hostname %s" % ip_address
117 print ""
118
119
120def print_hosts(instances, prefix, suffix, domain):
121 """ Print out as hosts file format """
122 for instance_name, ip_address in instances:
123 if ' ' in instance_name:
124 continue # skip if name contains space.
125 instance_name = prefix + instance_name + suffix + domain
126 print "%s\t%s" % (ip_address, instance_name)
127
128
129if __name__ == '__main__':
130 args = vars(parse_args())
131 main(args)