OLD | NEW |
1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ | 1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ |
2 # Copyright (c) 2010, Eucalyptus Systems, Inc. | 2 # Copyright (c) 2010, Eucalyptus Systems, Inc. |
3 # | 3 # |
4 # Permission is hereby granted, free of charge, to any person obtaining a | 4 # Permission is hereby granted, free of charge, to any person obtaining a |
5 # copy of this software and associated documentation files (the | 5 # copy of this software and associated documentation files (the |
6 # "Software"), to deal in the Software without restriction, including | 6 # "Software"), to deal in the Software without restriction, including |
7 # without limitation the rights to use, copy, modify, merge, publish, dis- | 7 # without limitation the rights to use, copy, modify, merge, publish, dis- |
8 # tribute, sublicense, and/or sell copies of the Software, and to permit | 8 # tribute, sublicense, and/or sell copies of the Software, and to permit |
9 # persons to whom the Software is furnished to do so, subject to the fol- | 9 # persons to whom the Software is furnished to do so, subject to the fol- |
10 # lowing conditions: | 10 # lowing conditions: |
(...skipping 27 matching lines...) Expand all Loading... |
38 <Name>%(name)s</Name> | 38 <Name>%(name)s</Name> |
39 <CallerReference>%(caller_ref)s</CallerReference> | 39 <CallerReference>%(caller_ref)s</CallerReference> |
40 <HostedZoneConfig> | 40 <HostedZoneConfig> |
41 <Comment>%(comment)s</Comment> | 41 <Comment>%(comment)s</Comment> |
42 </HostedZoneConfig> | 42 </HostedZoneConfig> |
43 </CreateHostedZoneRequest>""" | 43 </CreateHostedZoneRequest>""" |
44 | 44 |
45 #boto.set_stream_logger('dns') | 45 #boto.set_stream_logger('dns') |
46 | 46 |
47 class Route53Connection(AWSAuthConnection): | 47 class Route53Connection(AWSAuthConnection): |
| 48 DefaultHost = 'route53.amazonaws.com' |
| 49 """The default Route53 API endpoint to connect to.""" |
48 | 50 |
49 DefaultHost = 'route53.amazonaws.com' | 51 Version = '2011-05-05' |
50 Version = '2010-10-01' | 52 """Route53 API version.""" |
51 XMLNameSpace = 'https://route53.amazonaws.com/doc/2010-10-01/' | 53 |
| 54 XMLNameSpace = 'https://route53.amazonaws.com/doc/2011-05-05/' |
| 55 """XML schema for this Route53 API version.""" |
52 | 56 |
53 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, | 57 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, |
54 port=None, proxy=None, proxy_port=None, | 58 port=None, proxy=None, proxy_port=None, |
55 host=DefaultHost, debug=0): | 59 host=DefaultHost, debug=0): |
56 AWSAuthConnection.__init__(self, host, | 60 AWSAuthConnection.__init__(self, host, |
57 aws_access_key_id, aws_secret_access_key, | 61 aws_access_key_id, aws_secret_access_key, |
58 True, port, proxy, proxy_port, debug=debug) | 62 True, port, proxy, proxy_port, debug=debug) |
59 | 63 |
60 def _required_auth_capability(self): | 64 def _required_auth_capability(self): |
61 return ['route53'] | 65 return ['route53'] |
62 | 66 |
63 def make_request(self, action, path, headers=None, data='', params=None): | 67 def make_request(self, action, path, headers=None, data='', params=None): |
64 if params: | 68 if params: |
65 pairs = [] | 69 pairs = [] |
66 for key, val in params.iteritems(): | 70 for key, val in params.iteritems(): |
67 if val is None: continue | 71 if val is None: continue |
68 pairs.append(key + '=' + urllib.quote(str(val))) | 72 pairs.append(key + '=' + urllib.quote(str(val))) |
69 path += '?' + '&'.join(pairs) | 73 path += '?' + '&'.join(pairs) |
70 return AWSAuthConnection.make_request(self, action, path, headers, data) | 74 return AWSAuthConnection.make_request(self, action, path, headers, data) |
71 | 75 |
72 # Hosted Zones | 76 # Hosted Zones |
73 | 77 |
74 def get_all_hosted_zones(self): | 78 def get_all_hosted_zones(self, start_marker=None, zone_list=None): |
75 """ | 79 """ |
76 Returns a Python data structure with information about all | 80 Returns a Python data structure with information about all |
77 Hosted Zones defined for the AWS account. | 81 Hosted Zones defined for the AWS account. |
| 82 |
| 83 :param int start_marker: start marker to pass when fetching additional |
| 84 results after a truncated list |
| 85 :param list zone_list: a HostedZones list to prepend to results |
78 """ | 86 """ |
79 response = self.make_request('GET', '/%s/hostedzone' % self.Version) | 87 params = {} |
| 88 if start_marker: |
| 89 params = {'marker': start_marker} |
| 90 response = self.make_request('GET', '/%s/hostedzone' % self.Version, |
| 91 params=params) |
80 body = response.read() | 92 body = response.read() |
81 boto.log.debug(body) | 93 boto.log.debug(body) |
82 if response.status >= 300: | 94 if response.status >= 300: |
83 raise exception.DNSServerError(response.status, | 95 raise exception.DNSServerError(response.status, |
84 response.reason, | 96 response.reason, |
85 body) | 97 body) |
86 e = boto.jsonresponse.Element(list_marker='HostedZones', | 98 e = boto.jsonresponse.Element(list_marker='HostedZones', |
87 item_marker=('HostedZone',)) | 99 item_marker=('HostedZone',)) |
88 h = boto.jsonresponse.XmlHandler(e, None) | 100 h = boto.jsonresponse.XmlHandler(e, None) |
89 h.parse(body) | 101 h.parse(body) |
| 102 if zone_list: |
| 103 e['ListHostedZonesResponse']['HostedZones'].extend(zone_list) |
| 104 while e['ListHostedZonesResponse'].has_key('NextMarker'): |
| 105 next_marker = e['ListHostedZonesResponse']['NextMarker'] |
| 106 zone_list = e['ListHostedZonesResponse']['HostedZones'] |
| 107 e = self.get_all_hosted_zones(next_marker, zone_list) |
90 return e | 108 return e |
91 | 109 |
92 def get_hosted_zone(self, hosted_zone_id): | 110 def get_hosted_zone(self, hosted_zone_id): |
93 """ | 111 """ |
94 Get detailed information about a particular Hosted Zone. | 112 Get detailed information about a particular Hosted Zone. |
95 | 113 |
96 :type hosted_zone_id: str | 114 :type hosted_zone_id: str |
97 :param hosted_zone_id: The unique identifier for the Hosted Zone | 115 :param hosted_zone_id: The unique identifier for the Hosted Zone |
98 | 116 |
99 """ | 117 """ |
100 uri = '/%s/hostedzone/%s' % (self.Version, hosted_zone_id) | 118 uri = '/%s/hostedzone/%s' % (self.Version, hosted_zone_id) |
101 response = self.make_request('GET', uri) | 119 response = self.make_request('GET', uri) |
102 body = response.read() | 120 body = response.read() |
103 boto.log.debug(body) | 121 boto.log.debug(body) |
104 if response.status >= 300: | 122 if response.status >= 300: |
105 raise exception.DNSServerError(response.status, | 123 raise exception.DNSServerError(response.status, |
106 response.reason, | 124 response.reason, |
107 body) | 125 body) |
108 e = boto.jsonresponse.Element(list_marker='NameServers', | 126 e = boto.jsonresponse.Element(list_marker='NameServers', |
109 item_marker=('NameServer',)) | 127 item_marker=('NameServer',)) |
110 h = boto.jsonresponse.XmlHandler(e, None) | 128 h = boto.jsonresponse.XmlHandler(e, None) |
111 h.parse(body) | 129 h.parse(body) |
112 return e | 130 return e |
113 | 131 |
114 def create_hosted_zone(self, domain_name, caller_ref=None, comment=''): | 132 def create_hosted_zone(self, domain_name, caller_ref=None, comment=''): |
115 """ | 133 """ |
116 Create a new Hosted Zone. Returns a Python data structure with | 134 Create a new Hosted Zone. Returns a Python data structure with |
117 information about the newly created Hosted Zone. | 135 information about the newly created Hosted Zone. |
118 | 136 |
119 :type domain_name: str | 137 :type domain_name: str |
120 :param domain_name: The name of the domain. This should be a | 138 :param domain_name: The name of the domain. This should be a |
121 fully-specified domain, and should end with | 139 fully-specified domain, and should end with a final period |
122 a final period as the last label indication. | 140 as the last label indication. If you omit the final period, |
123 If you omit the final period, Amazon Route 53 | 141 Amazon Route 53 assumes the domain is relative to the root. |
124 assumes the domain is relative to the root. | 142 This is the name you have registered with your DNS registrar. |
125 This is the name you have registered with your | 143 It is also the name you will delegate from your registrar to |
126 DNS registrar. It is also the name you will | 144 the Amazon Route 53 delegation servers returned in |
127 delegate from your registrar to the Amazon | 145 response to this request.A list of strings with the image |
128 Route 53 delegation servers returned in | 146 IDs wanted. |
129 response to this request.A list of strings | |
130 with the image IDs wanted | |
131 | 147 |
132 :type caller_ref: str | 148 :type caller_ref: str |
133 :param caller_ref: A unique string that identifies the request | 149 :param caller_ref: A unique string that identifies the request |
134 and that allows failed CreateHostedZone requests | 150 and that allows failed CreateHostedZone requests to be retried |
135 to be retried without the risk of executing the | 151 without the risk of executing the operation twice. If you don't |
136 operation twice. | 152 provide a value for this, boto will generate a Type 4 UUID and |
137 If you don't provide a value for this, boto will | 153 use that. |
138 generate a Type 4 UUID and use that. | |
139 | 154 |
140 :type comment: str | 155 :type comment: str |
141 :param comment: Any comments you want to include about the hosted | 156 :param comment: Any comments you want to include about the hosted |
142 zone. | 157 zone. |
143 | 158 |
144 """ | 159 """ |
145 if caller_ref is None: | 160 if caller_ref is None: |
146 caller_ref = str(uuid.uuid4()) | 161 caller_ref = str(uuid.uuid4()) |
147 params = {'name' : domain_name, | 162 params = {'name' : domain_name, |
148 'caller_ref' : caller_ref, | 163 'caller_ref' : caller_ref, |
149 'comment' : comment, | 164 'comment' : comment, |
150 'xmlns' : self.XMLNameSpace} | 165 'xmlns' : self.XMLNameSpace} |
151 xml = HZXML % params | 166 xml = HZXML % params |
152 uri = '/%s/hostedzone' % self.Version | 167 uri = '/%s/hostedzone' % self.Version |
(...skipping 22 matching lines...) Expand all Loading... |
175 response.reason, | 190 response.reason, |
176 body) | 191 body) |
177 e = boto.jsonresponse.Element() | 192 e = boto.jsonresponse.Element() |
178 h = boto.jsonresponse.XmlHandler(e, None) | 193 h = boto.jsonresponse.XmlHandler(e, None) |
179 h.parse(body) | 194 h.parse(body) |
180 return e | 195 return e |
181 | 196 |
182 # Resource Record Sets | 197 # Resource Record Sets |
183 | 198 |
184 def get_all_rrsets(self, hosted_zone_id, type=None, | 199 def get_all_rrsets(self, hosted_zone_id, type=None, |
185 name=None, maxitems=None): | 200 name=None, identifier=None, maxitems=None): |
186 """ | 201 """ |
187 Retrieve the Resource Record Sets defined for this Hosted Zone. | 202 Retrieve the Resource Record Sets defined for this Hosted Zone. |
188 Returns the raw XML data returned by the Route53 call. | 203 Returns the raw XML data returned by the Route53 call. |
189 | 204 |
190 :type hosted_zone_id: str | 205 :type hosted_zone_id: str |
191 :param hosted_zone_id: The unique identifier for the Hosted Zone | 206 :param hosted_zone_id: The unique identifier for the Hosted Zone |
192 | 207 |
193 :type type: str | 208 :type type: str |
194 :param type: The type of resource record set to begin the record | 209 :param type: The type of resource record set to begin the record |
195 listing from. Valid choices are: | 210 listing from. Valid choices are: |
196 | 211 |
197 * A | 212 * A |
198 * AAAA | 213 * AAAA |
199 * CNAME | 214 * CNAME |
200 * MX | 215 * MX |
201 * NS | 216 * NS |
202 * PTR | 217 * PTR |
203 * SOA | 218 * SOA |
204 * SPF | 219 * SPF |
205 * SRV | 220 * SRV |
206 * TXT | 221 * TXT |
| 222 |
| 223 Valid values for weighted resource record sets: |
| 224 |
| 225 * A |
| 226 * AAAA |
| 227 * CNAME |
| 228 * TXT |
| 229 |
| 230 Valid values for Zone Apex Aliases: |
| 231 |
| 232 * A |
| 233 * AAAA |
207 | 234 |
208 :type name: str | 235 :type name: str |
209 :param name: The first name in the lexicographic ordering of domain | 236 :param name: The first name in the lexicographic ordering of domain |
210 names to be retrieved | 237 names to be retrieved |
211 | 238 |
| 239 :type identifier: str |
| 240 :param identifier: In a hosted zone that includes weighted resource |
| 241 record sets (multiple resource record sets with the same DNS |
| 242 name and type that are differentiated only by SetIdentifier), |
| 243 if results were truncated for a given DNS name and type, |
| 244 the value of SetIdentifier for the next resource record |
| 245 set that has the current DNS name and type |
| 246 |
212 :type maxitems: int | 247 :type maxitems: int |
213 :param maxitems: The maximum number of records | 248 :param maxitems: The maximum number of records |
214 | 249 |
215 """ | 250 """ |
216 from boto.route53.record import ResourceRecordSets | 251 from boto.route53.record import ResourceRecordSets |
217 params = {'type': type, 'name': name, 'maxitems': maxitems} | 252 params = {'type': type, 'name': name, |
| 253 'Identifier': identifier, 'maxitems': maxitems} |
218 uri = '/%s/hostedzone/%s/rrset' % (self.Version, hosted_zone_id) | 254 uri = '/%s/hostedzone/%s/rrset' % (self.Version, hosted_zone_id) |
219 response = self.make_request('GET', uri, params=params) | 255 response = self.make_request('GET', uri, params=params) |
220 body = response.read() | 256 body = response.read() |
221 boto.log.debug(body) | 257 boto.log.debug(body) |
222 if response.status >= 300: | 258 if response.status >= 300: |
223 raise exception.DNSServerError(response.status, | 259 raise exception.DNSServerError(response.status, |
224 response.reason, | 260 response.reason, |
225 body) | 261 body) |
226 rs = ResourceRecordSets(connection=self, hosted_zone_id=hosted_zone_id) | 262 rs = ResourceRecordSets(connection=self, hosted_zone_id=hosted_zone_id) |
227 h = handler.XmlHandler(rs, self) | 263 h = handler.XmlHandler(rs, self) |
228 xml.sax.parseString(body, h) | 264 xml.sax.parseString(body, h) |
229 return rs | 265 return rs |
230 | 266 |
231 def change_rrsets(self, hosted_zone_id, xml_body): | 267 def change_rrsets(self, hosted_zone_id, xml_body): |
232 """ | 268 """ |
233 Create or change the authoritative DNS information for this | 269 Create or change the authoritative DNS information for this |
234 Hosted Zone. | 270 Hosted Zone. |
235 Returns a Python data structure with information about the set of | 271 Returns a Python data structure with information about the set of |
236 changes, including the Change ID. | 272 changes, including the Change ID. |
237 | 273 |
238 :type hosted_zone_id: str | 274 :type hosted_zone_id: str |
239 :param hosted_zone_id: The unique identifier for the Hosted Zone | 275 :param hosted_zone_id: The unique identifier for the Hosted Zone |
240 | 276 |
241 :type xml_body: str | 277 :type xml_body: str |
242 :param xml_body: The list of changes to be made, defined in the | 278 :param xml_body: The list of changes to be made, defined in the |
243 XML schema defined by the Route53 service. | 279 XML schema defined by the Route53 service. |
244 | 280 |
245 """ | 281 """ |
246 uri = '/%s/hostedzone/%s/rrset' % (self.Version, hosted_zone_id) | 282 uri = '/%s/hostedzone/%s/rrset' % (self.Version, hosted_zone_id) |
247 response = self.make_request('POST', uri, | 283 response = self.make_request('POST', uri, |
248 {'Content-Type' : 'text/xml'}, | 284 {'Content-Type' : 'text/xml'}, |
249 xml_body) | 285 xml_body) |
250 body = response.read() | 286 body = response.read() |
251 boto.log.debug(body) | 287 boto.log.debug(body) |
252 if response.status >= 300: | 288 if response.status >= 300: |
253 raise exception.DNSServerError(response.status, | 289 raise exception.DNSServerError(response.status, |
254 response.reason, | 290 response.reason, |
255 body) | 291 body) |
256 e = boto.jsonresponse.Element() | 292 e = boto.jsonresponse.Element() |
257 h = boto.jsonresponse.XmlHandler(e, None) | 293 h = boto.jsonresponse.XmlHandler(e, None) |
258 h.parse(body) | 294 h.parse(body) |
259 return e | 295 return e |
260 | 296 |
261 def get_change(self, change_id): | 297 def get_change(self, change_id): |
262 """ | 298 """ |
263 Get information about a proposed set of changes, as submitted | 299 Get information about a proposed set of changes, as submitted |
264 by the change_rrsets method. | 300 by the change_rrsets method. |
265 Returns a Python data structure with status information about the | 301 Returns a Python data structure with status information about the |
266 changes. | 302 changes. |
267 | 303 |
268 :type change_id: str | 304 :type change_id: str |
269 :param change_id: The unique identifier for the set of changes. | 305 :param change_id: The unique identifier for the set of changes. |
270 This ID is returned in the response to the | 306 This ID is returned in the response to the change_rrsets method. |
271 change_rrsets method. | |
272 | 307 |
273 """ | 308 """ |
274 uri = '/%s/change/%s' % (self.Version, change_id) | 309 uri = '/%s/change/%s' % (self.Version, change_id) |
275 response = self.make_request('GET', uri) | 310 response = self.make_request('GET', uri) |
276 body = response.read() | 311 body = response.read() |
277 boto.log.debug(body) | 312 boto.log.debug(body) |
278 if response.status >= 300: | 313 if response.status >= 300: |
279 raise exception.DNSServerError(response.status, | 314 raise exception.DNSServerError(response.status, |
280 response.reason, | 315 response.reason, |
281 body) | 316 body) |
282 e = boto.jsonresponse.Element() | 317 e = boto.jsonresponse.Element() |
283 h = boto.jsonresponse.XmlHandler(e, None) | 318 h = boto.jsonresponse.XmlHandler(e, None) |
284 h.parse(body) | 319 h.parse(body) |
285 return e | 320 return e |
OLD | NEW |