Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/gsutil/boto/boto/route53/connection.py

Issue 12042069: Scripts to download files from google storage based on sha1 sums (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Review fixes, updated gsutil Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/
2 # Copyright (c) 2010, Eucalyptus Systems, Inc.
3 # Copyright (c) 2011 Blue Pines Technologies LLC, Brad Carleton
4 # www.bluepines.org
5 # Copyright (c) 2012 42 Lines Inc., Jim Browne
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a
8 # copy of this software and associated documentation files (the
9 # "Software"), to deal in the Software without restriction, including
10 # without limitation the rights to use, copy, modify, merge, publish, dis-
11 # tribute, sublicense, and/or sell copies of the Software, and to permit
12 # persons to whom the Software is furnished to do so, subject to the fol-
13 # lowing conditions:
14 #
15 # The above copyright notice and this permission notice shall be included
16 # in all copies or substantial portions of the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
20 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 # IN THE SOFTWARE.
25 #
26
27 import xml.sax
28 import uuid
29 import urllib
30 import boto
31 from boto.connection import AWSAuthConnection
32 from boto import handler
33 from boto.route53.record import ResourceRecordSets
34 from boto.route53.zone import Zone
35 import boto.jsonresponse
36 import exception
37
38 HZXML = """<?xml version="1.0" encoding="UTF-8"?>
39 <CreateHostedZoneRequest xmlns="%(xmlns)s">
40 <Name>%(name)s</Name>
41 <CallerReference>%(caller_ref)s</CallerReference>
42 <HostedZoneConfig>
43 <Comment>%(comment)s</Comment>
44 </HostedZoneConfig>
45 </CreateHostedZoneRequest>"""
46
47 #boto.set_stream_logger('dns')
48
49
50 class Route53Connection(AWSAuthConnection):
51 DefaultHost = 'route53.amazonaws.com'
52 """The default Route53 API endpoint to connect to."""
53
54 Version = '2012-02-29'
55 """Route53 API version."""
56
57 XMLNameSpace = 'https://route53.amazonaws.com/doc/2012-02-29/'
58 """XML schema for this Route53 API version."""
59
60 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
61 port=None, proxy=None, proxy_port=None,
62 host=DefaultHost, debug=0, security_token=None,
63 validate_certs=True):
64 AWSAuthConnection.__init__(self, host,
65 aws_access_key_id, aws_secret_access_key,
66 True, port, proxy, proxy_port, debug=debug,
67 security_token=security_token,
68 validate_certs=validate_certs)
69
70 def _required_auth_capability(self):
71 return ['route53']
72
73 def make_request(self, action, path, headers=None, data='', params=None):
74 if params:
75 pairs = []
76 for key, val in params.iteritems():
77 if val is None:
78 continue
79 pairs.append(key + '=' + urllib.quote(str(val)))
80 path += '?' + '&'.join(pairs)
81 return AWSAuthConnection.make_request(self, action, path,
82 headers, data)
83
84 # Hosted Zones
85
86 def get_all_hosted_zones(self, start_marker=None, zone_list=None):
87 """
88 Returns a Python data structure with information about all
89 Hosted Zones defined for the AWS account.
90
91 :param int start_marker: start marker to pass when fetching additional
92 results after a truncated list
93 :param list zone_list: a HostedZones list to prepend to results
94 """
95 params = {}
96 if start_marker:
97 params = {'marker': start_marker}
98 response = self.make_request('GET', '/%s/hostedzone' % self.Version,
99 params=params)
100 body = response.read()
101 boto.log.debug(body)
102 if response.status >= 300:
103 raise exception.DNSServerError(response.status,
104 response.reason,
105 body)
106 e = boto.jsonresponse.Element(list_marker='HostedZones',
107 item_marker=('HostedZone',))
108 h = boto.jsonresponse.XmlHandler(e, None)
109 h.parse(body)
110 if zone_list:
111 e['ListHostedZonesResponse']['HostedZones'].extend(zone_list)
112 while 'NextMarker' in e['ListHostedZonesResponse']:
113 next_marker = e['ListHostedZonesResponse']['NextMarker']
114 zone_list = e['ListHostedZonesResponse']['HostedZones']
115 e = self.get_all_hosted_zones(next_marker, zone_list)
116 return e
117
118 def get_hosted_zone(self, hosted_zone_id):
119 """
120 Get detailed information about a particular Hosted Zone.
121
122 :type hosted_zone_id: str
123 :param hosted_zone_id: The unique identifier for the Hosted Zone
124
125 """
126 uri = '/%s/hostedzone/%s' % (self.Version, hosted_zone_id)
127 response = self.make_request('GET', uri)
128 body = response.read()
129 boto.log.debug(body)
130 if response.status >= 300:
131 raise exception.DNSServerError(response.status,
132 response.reason,
133 body)
134 e = boto.jsonresponse.Element(list_marker='NameServers',
135 item_marker=('NameServer',))
136 h = boto.jsonresponse.XmlHandler(e, None)
137 h.parse(body)
138 return e
139
140 def get_hosted_zone_by_name(self, hosted_zone_name):
141 """
142 Get detailed information about a particular Hosted Zone.
143
144 :type hosted_zone_name: str
145 :param hosted_zone_name: The fully qualified domain name for the Hosted
146 Zone
147
148 """
149 if hosted_zone_name[-1] != '.':
150 hosted_zone_name += '.'
151 all_hosted_zones = self.get_all_hosted_zones()
152 for zone in all_hosted_zones['ListHostedZonesResponse']['HostedZones']:
153 #check that they gave us the FQDN for their zone
154 if zone['Name'] == hosted_zone_name:
155 return self.get_hosted_zone(zone['Id'].split('/')[-1])
156
157 def create_hosted_zone(self, domain_name, caller_ref=None, comment=''):
158 """
159 Create a new Hosted Zone. Returns a Python data structure with
160 information about the newly created Hosted Zone.
161
162 :type domain_name: str
163 :param domain_name: The name of the domain. This should be a
164 fully-specified domain, and should end with a final period
165 as the last label indication. If you omit the final period,
166 Amazon Route 53 assumes the domain is relative to the root.
167 This is the name you have registered with your DNS registrar.
168 It is also the name you will delegate from your registrar to
169 the Amazon Route 53 delegation servers returned in
170 response to this request.A list of strings with the image
171 IDs wanted.
172
173 :type caller_ref: str
174 :param caller_ref: A unique string that identifies the request
175 and that allows failed CreateHostedZone requests to be retried
176 without the risk of executing the operation twice. If you don't
177 provide a value for this, boto will generate a Type 4 UUID and
178 use that.
179
180 :type comment: str
181 :param comment: Any comments you want to include about the hosted
182 zone.
183
184 """
185 if caller_ref is None:
186 caller_ref = str(uuid.uuid4())
187 params = {'name': domain_name,
188 'caller_ref': caller_ref,
189 'comment': comment,
190 'xmlns': self.XMLNameSpace}
191 xml_body = HZXML % params
192 uri = '/%s/hostedzone' % self.Version
193 response = self.make_request('POST', uri,
194 {'Content-Type': 'text/xml'}, xml_body)
195 body = response.read()
196 boto.log.debug(body)
197 if response.status == 201:
198 e = boto.jsonresponse.Element(list_marker='NameServers',
199 item_marker=('NameServer',))
200 h = boto.jsonresponse.XmlHandler(e, None)
201 h.parse(body)
202 return e
203 else:
204 raise exception.DNSServerError(response.status,
205 response.reason,
206 body)
207
208 def delete_hosted_zone(self, hosted_zone_id):
209 uri = '/%s/hostedzone/%s' % (self.Version, hosted_zone_id)
210 response = self.make_request('DELETE', uri)
211 body = response.read()
212 boto.log.debug(body)
213 if response.status not in (200, 204):
214 raise exception.DNSServerError(response.status,
215 response.reason,
216 body)
217 e = boto.jsonresponse.Element()
218 h = boto.jsonresponse.XmlHandler(e, None)
219 h.parse(body)
220 return e
221
222 # Resource Record Sets
223
224 def get_all_rrsets(self, hosted_zone_id, type=None,
225 name=None, identifier=None, maxitems=None):
226 """
227 Retrieve the Resource Record Sets defined for this Hosted Zone.
228 Returns the raw XML data returned by the Route53 call.
229
230 :type hosted_zone_id: str
231 :param hosted_zone_id: The unique identifier for the Hosted Zone
232
233 :type type: str
234 :param type: The type of resource record set to begin the record
235 listing from. Valid choices are:
236
237 * A
238 * AAAA
239 * CNAME
240 * MX
241 * NS
242 * PTR
243 * SOA
244 * SPF
245 * SRV
246 * TXT
247
248 Valid values for weighted resource record sets:
249
250 * A
251 * AAAA
252 * CNAME
253 * TXT
254
255 Valid values for Zone Apex Aliases:
256
257 * A
258 * AAAA
259
260 :type name: str
261 :param name: The first name in the lexicographic ordering of domain
262 names to be retrieved
263
264 :type identifier: str
265 :param identifier: In a hosted zone that includes weighted resource
266 record sets (multiple resource record sets with the same DNS
267 name and type that are differentiated only by SetIdentifier),
268 if results were truncated for a given DNS name and type,
269 the value of SetIdentifier for the next resource record
270 set that has the current DNS name and type
271
272 :type maxitems: int
273 :param maxitems: The maximum number of records
274
275 """
276 params = {'type': type, 'name': name,
277 'Identifier': identifier, 'maxitems': maxitems}
278 uri = '/%s/hostedzone/%s/rrset' % (self.Version, hosted_zone_id)
279 response = self.make_request('GET', uri, params=params)
280 body = response.read()
281 boto.log.debug(body)
282 if response.status >= 300:
283 raise exception.DNSServerError(response.status,
284 response.reason,
285 body)
286 rs = ResourceRecordSets(connection=self, hosted_zone_id=hosted_zone_id)
287 h = handler.XmlHandler(rs, self)
288 xml.sax.parseString(body, h)
289 return rs
290
291 def change_rrsets(self, hosted_zone_id, xml_body):
292 """
293 Create or change the authoritative DNS information for this
294 Hosted Zone.
295 Returns a Python data structure with information about the set of
296 changes, including the Change ID.
297
298 :type hosted_zone_id: str
299 :param hosted_zone_id: The unique identifier for the Hosted Zone
300
301 :type xml_body: str
302 :param xml_body: The list of changes to be made, defined in the
303 XML schema defined by the Route53 service.
304
305 """
306 uri = '/%s/hostedzone/%s/rrset' % (self.Version, hosted_zone_id)
307 response = self.make_request('POST', uri,
308 {'Content-Type': 'text/xml'},
309 xml_body)
310 body = response.read()
311 boto.log.debug(body)
312 if response.status >= 300:
313 raise exception.DNSServerError(response.status,
314 response.reason,
315 body)
316 e = boto.jsonresponse.Element()
317 h = boto.jsonresponse.XmlHandler(e, None)
318 h.parse(body)
319 return e
320
321 def get_change(self, change_id):
322 """
323 Get information about a proposed set of changes, as submitted
324 by the change_rrsets method.
325 Returns a Python data structure with status information about the
326 changes.
327
328 :type change_id: str
329 :param change_id: The unique identifier for the set of changes.
330 This ID is returned in the response to the change_rrsets method.
331
332 """
333 uri = '/%s/change/%s' % (self.Version, change_id)
334 response = self.make_request('GET', uri)
335 body = response.read()
336 boto.log.debug(body)
337 if response.status >= 300:
338 raise exception.DNSServerError(response.status,
339 response.reason,
340 body)
341 e = boto.jsonresponse.Element()
342 h = boto.jsonresponse.XmlHandler(e, None)
343 h.parse(body)
344 return e
345
346 def create_zone(self, name):
347 """
348 Create a new Hosted Zone. Returns a Zone object for the newly
349 created Hosted Zone.
350
351 :type name: str
352 :param name: The name of the domain. This should be a
353 fully-specified domain, and should end with a final period
354 as the last label indication. If you omit the final period,
355 Amazon Route 53 assumes the domain is relative to the root.
356 This is the name you have registered with your DNS registrar.
357 It is also the name you will delegate from your registrar to
358 the Amazon Route 53 delegation servers returned in
359 response to this request.
360 """
361 zone = self.create_hosted_zone(name)
362 return Zone(self, zone['CreateHostedZoneResponse']['HostedZone'])
363
364 def get_zone(self, name):
365 """
366 Returns a Zone object for the specified Hosted Zone.
367
368 :param name: The name of the domain. This should be a
369 fully-specified domain, and should end with a final period
370 as the last label indication.
371 """
372 name = self._make_qualified(name)
373 for zone in self.get_zones():
374 if name == zone.name:
375 return zone
376
377 def get_zones(self):
378 """
379 Returns a list of Zone objects, one for each of the Hosted
380 Zones defined for the AWS account.
381 """
382 zones = self.get_all_hosted_zones()
383 return [Zone(self, zone) for zone in
384 zones['ListHostedZonesResponse']['HostedZones']]
385
386 def _make_qualified(self, value):
387 """
388 Ensure passed domain names end in a period (.) character.
389 This will usually make a domain fully qualified.
390 """
391 if type(value) in [list, tuple, set]:
392 new_list = []
393 for record in value:
394 if record and not record[-1] == '.':
395 new_list.append("%s." % record)
396 else:
397 new_list.append(record)
398 return new_list
399 else:
400 value = value.strip()
401 if value and not value[-1] == '.':
402 value = "%s." % value
403 return value
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698