Skip to content
Newer
Older
100755 206 lines (187 sloc) 8.82 KB
8b65bfb Updated Route53 connections to use the same XML parsing used elsewhere
Chris Moyer authored
1 #!/usr/bin/env python
2 # Author: Chris Moyer
3 #
4 # route53 is similar to sdbadmin for Route53, it's a simple
5 # console utility to perform the most frequent tasks with Route53
3409a6f @jimbrowne Add examples of usage.
jimbrowne authored
6 #
7 # Example usage. Use route53 get after each command to see how the
8 # zone changes.
9 #
10 # Add a non-weighted record, change its value, then delete. Default TTL:
11 #
12 # route53 add_record ZPO9LGHZ43QB9 rr.example.com A 4.3.2.1
13 # route53 change_record ZPO9LGHZ43QB9 rr.example.com A 9.8.7.6
14 # route53 del_record ZPO9LGHZ43QB9 rr.example.com A 9.8.7.6
15 #
16 # Add a weighted record with two different weights. Note that the TTL
17 # must be specified as route53 uses positional parameters rather than
18 # option flags:
19 #
20 # route53 add_record ZPO9LGHZ43QB9 wrr.example.com A 1.2.3.4 600 foo9 10
21 # route53 add_record ZPO9LGHZ43QB9 wrr.example.com A 4.3.2.1 600 foo8 10
22 #
23 # route53 change_record ZPO9LGHZ43QB9 wrr.example.com A 9.9.9.9 600 foo8 10
24 #
25 # route53 del_record ZPO9LGHZ43QB9 wrr.example.com A 1.2.3.4 600 foo9 10
26 # route53 del_record ZPO9LGHZ43QB9 wrr.example.com A 9.9.9.9 600 foo8 10
27 #
28 # Add a non-weighted alias, change its value, then delete. Alaises inherit
29 # their TTLs from the backing ELB:
30 #
31 # route53 add_alias ZPO9LGHZ43QB9 alias.example.com A Z3DZXE0Q79N41H lb-1218761514.us-east-1.elb.amazonaws.com.
32 # route53 change_alias ZPO9LGHZ43QB9 alias.example.com. A Z3DZXE0Q79N41H lb2-1218761514.us-east-1.elb.amazonaws.com.
33 # route53 delete_alias ZPO9LGHZ43QB9 alias.example.com. A Z3DZXE0Q79N41H lb2-1218761514.us-east-1.elb.amazonaws.com.
8b65bfb Updated Route53 connections to use the same XML parsing used elsewhere
Chris Moyer authored
34
35 def _print_zone_info(zoneinfo):
fc797d4 Added paging support directly into the ResourceRecordSets object
Chris Moyer authored
36 print "="*80
37 print "| ID: %s" % zoneinfo['Id'].split("/")[-1]
38 print "| Name: %s" % zoneinfo['Name']
39 print "| Ref: %s" % zoneinfo['CallerReference']
40 print "="*80
41 print zoneinfo['Config']
42 print
a636d0a @aficionado Add WRR support for Route53
aficionado authored
43
8b65bfb Updated Route53 connections to use the same XML parsing used elsewhere
Chris Moyer authored
44
45 def create(conn, hostname, caller_reference=None, comment=''):
89a69e6 Fixed up route53 command line script to include a delete method and
Chris Moyer authored
46 """Create a hosted zone, returning the nameservers"""
fc797d4 Added paging support directly into the ResourceRecordSets object
Chris Moyer authored
47 response = conn.create_hosted_zone(hostname, caller_reference, comment)
89a69e6 Fixed up route53 command line script to include a delete method and
Chris Moyer authored
48 print "Pending, please add the following Name Servers:"
49 for ns in response.NameServers:
50 print "\t", ns
51
52 def delete_zone(conn, hosted_zone_id):
53 """Delete a hosted zone by ID"""
54 response = conn.delete_hosted_zone(hosted_zone_id)
55 print response
8b65bfb Updated Route53 connections to use the same XML parsing used elsewhere
Chris Moyer authored
56
57 def ls(conn):
fc797d4 Added paging support directly into the ResourceRecordSets object
Chris Moyer authored
58 """List all hosted zones"""
59 response = conn.get_all_hosted_zones()
60 for zoneinfo in response['ListHostedZonesResponse']['HostedZones']:
61 _print_zone_info(zoneinfo)
8b65bfb Updated Route53 connections to use the same XML parsing used elsewhere
Chris Moyer authored
62
63 def get(conn, hosted_zone_id, type=None, name=None, maxitems=None):
89a69e6 Fixed up route53 command line script to include a delete method and
Chris Moyer authored
64 """Get all the records for a single zone"""
4a1d5fd @kopertop Fixed issue with:
kopertop authored
65 response = conn.get_all_rrsets(hosted_zone_id, type, name, maxitems=maxitems)
66 # If a maximum number of items was set, we limit to that number
67 # by turning the response into an actual list (copying it)
68 # instead of allowing it to page
69 if maxitems:
70 response = response[:]
021c408 @michaelnt Improve formatting when printing zone records and listing commands
michaelnt authored
71 print '%-40s %-5s %-20s %s' % ("Name", "Type", "TTL", "Value(s)")
fc797d4 Added paging support directly into the ResourceRecordSets object
Chris Moyer authored
72 for record in response:
d68fd27 @kennu Added Alias Resource Record Sets support to Route 53
kennu authored
73 print '%-40s %-5s %-20s %s' % (record.name, record.type, record.ttl, record.to_print())
8b65bfb Updated Route53 connections to use the same XML parsing used elsewhere
Chris Moyer authored
74
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
75 def _add_del(conn, hosted_zone_id, change, name, type, identifier, weight, values, ttl, comment):
a636d0a @aficionado Add WRR support for Route53
aficionado authored
76 from boto.route53.record import ResourceRecordSets
77 changes = ResourceRecordSets(conn, hosted_zone_id, comment)
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
78 change = changes.add_change(change, name, type, ttl,
79 identifier=identifier, weight=weight)
a636d0a @aficionado Add WRR support for Route53
aficionado authored
80 for value in values.split(','):
81 change.add_value(value)
82 print changes.commit()
83
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
84 def _add_del_alias(conn, hosted_zone_id, change, name, type, identifier, weight, alias_hosted_zone_id, alias_dns_name, comment):
d68fd27 @kennu Added Alias Resource Record Sets support to Route 53
kennu authored
85 from boto.route53.record import ResourceRecordSets
86 changes = ResourceRecordSets(conn, hosted_zone_id, comment)
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
87 change = changes.add_change(change, name, type,
88 identifier=identifier, weight=weight)
ff602b5 @kennu Fixed set_alias call in route53 binary
kennu authored
89 change.set_alias(alias_hosted_zone_id, alias_dns_name)
d68fd27 @kennu Added Alias Resource Record Sets support to Route 53
kennu authored
90 print changes.commit()
91
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
92 def add_record(conn, hosted_zone_id, name, type, values, ttl=600,
93 identifier=None, weight=None, comment=""):
94 """Add a new record to a zone. identifier and weight are optional."""
95 _add_del(conn, hosted_zone_id, "CREATE", name, type, identifier,
96 weight, values, ttl, comment)
97
98 def del_record(conn, hosted_zone_id, name, type, values, ttl=600,
99 identifier=None, weight=None, comment=""):
100 """Delete a record from a zone: name, type, ttl, identifier, and weight must match."""
101 _add_del(conn, hosted_zone_id, "DELETE", name, type, identifier,
102 weight, values, ttl, comment)
103
104 def add_alias(conn, hosted_zone_id, name, type, alias_hosted_zone_id,
105 alias_dns_name, identifier=None, weight=None, comment=""):
106 """Add a new alias to a zone. identifier and weight are optional."""
107 _add_del_alias(conn, hosted_zone_id, "CREATE", name, type, identifier,
108 weight, alias_hosted_zone_id, alias_dns_name, comment)
109
110 def del_alias(conn, hosted_zone_id, name, type, alias_hosted_zone_id,
111 alias_dns_name, identifier=None, weight=None, comment=""):
112 """Delete an alias from a zone: name, type, alias_hosted_zone_id, alias_dns_name, weight and identifier must match."""
113 _add_del_alias(conn, hosted_zone_id, "DELETE", name, type, identifier,
114 weight, alias_hosted_zone_id, alias_dns_name, comment)
115
116 def change_record(conn, hosted_zone_id, name, type, newvalues, ttl=600,
117 identifier=None, weight=None, comment=""):
118 """Delete and then add a record to a zone. identifier and weight are optional."""
d68fd27 @kennu Added Alias Resource Record Sets support to Route 53
kennu authored
119 from boto.route53.record import ResourceRecordSets
120 changes = ResourceRecordSets(conn, hosted_zone_id, comment)
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
121 # Assume there are not more than 10 WRRs for a given (name, type)
122 responses = conn.get_all_rrsets(hosted_zone_id, type, name, maxitems=10)
123 for response in responses:
124 if response.name != name or response.type != type:
125 continue
126 if response.identifier != identifier or response.weight != weight:
127 continue
128 change1 = changes.add_change("DELETE", name, type, response.ttl,
129 identifier=response.identifier,
130 weight=response.weight)
131 for old_value in response.resource_records:
132 change1.add_value(old_value)
d68fd27 @kennu Added Alias Resource Record Sets support to Route 53
kennu authored
133
a636d0a @aficionado Add WRR support for Route53
aficionado authored
134 change2 = changes.add_change("CREATE", name, type, ttl,
135 identifier=identifier, weight=weight)
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
136 for new_value in newvalues.split(','):
6c2ded4 @michaelnt Add a change_record command to bin/route53
michaelnt authored
137 change2.add_value(new_value)
138 print changes.commit()
139
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
140 def change_alias(conn, hosted_zone_id, name, type, new_alias_hosted_zone_id, new_alias_dns_name, identifier=None, weight=None, comment=""):
141 """Delete and then add an alias to a zone. identifier and weight are optional."""
4f1fdf0 @bmaltby Added a change_alias command to route53 script to match the change_re…
bmaltby authored
142 from boto.route53.record import ResourceRecordSets
143 changes = ResourceRecordSets(conn, hosted_zone_id, comment)
603d8a3 @jimbrowne Re-write support for WRRs so they are just extentions to the
jimbrowne authored
144 # Assume there are not more than 10 WRRs for a given (name, type)
145 responses = conn.get_all_rrsets(hosted_zone_id, type, name, maxitems=10)
146 for response in responses:
147 if response.name != name or response.type != type:
148 continue
149 if response.identifier != identifier or response.weight != weight:
150 continue
151 change1 = changes.add_change("DELETE", name, type,
152 identifier=response.identifier,
153 weight=response.weight)
154 change1.set_alias(response.alias_hosted_zone_id, response.alias_dns_name)
155 change2 = changes.add_change("CREATE", name, type, identifier=identifier, weight=weight)
156 change2.set_alias(new_alias_hosted_zone_id, new_alias_dns_name)
a636d0a @aficionado Add WRR support for Route53
aficionado authored
157 print changes.commit()
158
cf54c9f Added missing "help" function for the route53 command line script
Chris Moyer authored
159 def help(conn, fnc=None):
fc797d4 Added paging support directly into the ResourceRecordSets object
Chris Moyer authored
160 """Prints this help message"""
161 import inspect
162 self = sys.modules['__main__']
163 if fnc:
164 try:
165 cmd = getattr(self, fnc)
166 except:
167 cmd = None
168 if not inspect.isfunction(cmd):
169 print "No function named: %s found" % fnc
170 sys.exit(2)
171 (args, varargs, varkw, defaults) = inspect.getargspec(cmd)
172 print cmd.__doc__
173 print "Usage: %s %s" % (fnc, " ".join([ "[%s]" % a for a in args[1:]]))
174 else:
175 print "Usage: route53 [command]"
176 for cname in dir(self):
177 if not cname.startswith("_"):
178 cmd = getattr(self, cname)
179 if inspect.isfunction(cmd):
180 doc = cmd.__doc__
021c408 @michaelnt Improve formatting when printing zone records and listing commands
michaelnt authored
181 print "\t%-20s %s" % (cname, doc)
fc797d4 Added paging support directly into the ResourceRecordSets object
Chris Moyer authored
182 sys.exit(1)
8b65bfb Updated Route53 connections to use the same XML parsing used elsewhere
Chris Moyer authored
183
184
185 if __name__ == "__main__":
fc797d4 Added paging support directly into the ResourceRecordSets object
Chris Moyer authored
186 import boto
187 import sys
188 conn = boto.connect_route53()
189 self = sys.modules['__main__']
190 if len(sys.argv) >= 2:
191 try:
192 cmd = getattr(self, sys.argv[1])
193 except:
194 cmd = None
195 args = sys.argv[2:]
196 else:
197 cmd = help
198 args = []
199 if not cmd:
200 cmd = help
201 try:
202 cmd(conn, *args)
203 except TypeError, e:
204 print e
205 help(conn, cmd.__name__)
Something went wrong with that request. Please try again.