OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved |
| 3 # |
| 4 # Permission is hereby granted, free of charge, to any person obtaining a |
| 5 # copy of this software and associated documentation files (the |
| 6 # "Software"), to deal in the Software without restriction, including |
| 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 |
| 9 # persons to whom the Software is furnished to do so, subject to the fol- |
| 10 # lowing conditions: |
| 11 # |
| 12 # The above copyright notice and this permission notice shall be included |
| 13 # in all copies or substantial portions of the Software. |
| 14 # |
| 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
| 17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
| 18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 21 # IN THE SOFTWARE. |
| 22 # |
| 23 from tests.compat import mock |
| 24 import re |
| 25 import xml.dom.minidom |
| 26 from boto.exception import BotoServerError |
| 27 from boto.route53.connection import Route53Connection |
| 28 from boto.route53.exception import DNSServerError |
| 29 from boto.route53.healthcheck import HealthCheck |
| 30 from boto.route53.record import ResourceRecordSets, Record |
| 31 from boto.route53.zone import Zone |
| 32 |
| 33 from nose.plugins.attrib import attr |
| 34 from tests.unit import AWSMockServiceTestCase |
| 35 from boto.compat import six |
| 36 urllib = six.moves.urllib |
| 37 |
| 38 |
| 39 @attr(route53=True) |
| 40 class TestRoute53Connection(AWSMockServiceTestCase): |
| 41 connection_class = Route53Connection |
| 42 |
| 43 def setUp(self): |
| 44 super(TestRoute53Connection, self).setUp() |
| 45 self.calls = { |
| 46 'count': 0, |
| 47 } |
| 48 |
| 49 def default_body(self): |
| 50 return b"""<Route53Result> |
| 51 <Message>It failed.</Message> |
| 52 </Route53Result> |
| 53 """ |
| 54 |
| 55 def test_typical_400(self): |
| 56 self.set_http_response(status_code=400, header=[ |
| 57 ['Code', 'AccessDenied'], |
| 58 ]) |
| 59 |
| 60 with self.assertRaises(DNSServerError) as err: |
| 61 self.service_connection.get_all_hosted_zones() |
| 62 |
| 63 self.assertTrue('It failed.' in str(err.exception)) |
| 64 |
| 65 def test_retryable_400_prior_request_not_complete(self): |
| 66 # Test ability to retry on ``PriorRequestNotComplete``. |
| 67 self.set_http_response(status_code=400, header=[ |
| 68 ['Code', 'PriorRequestNotComplete'], |
| 69 ]) |
| 70 self.do_retry_handler() |
| 71 |
| 72 def test_retryable_400_throttling(self): |
| 73 # Test ability to rety on ``Throttling``. |
| 74 self.set_http_response(status_code=400, header=[ |
| 75 ['Code', 'Throttling'], |
| 76 ]) |
| 77 self.do_retry_handler() |
| 78 |
| 79 @mock.patch('time.sleep') |
| 80 def do_retry_handler(self, sleep_mock): |
| 81 |
| 82 def incr_retry_handler(func): |
| 83 def _wrapper(*args, **kwargs): |
| 84 self.calls['count'] += 1 |
| 85 return func(*args, **kwargs) |
| 86 return _wrapper |
| 87 |
| 88 # Patch. |
| 89 orig_retry = self.service_connection._retry_handler |
| 90 self.service_connection._retry_handler = incr_retry_handler( |
| 91 orig_retry |
| 92 ) |
| 93 self.assertEqual(self.calls['count'], 0) |
| 94 |
| 95 # Retries get exhausted. |
| 96 with self.assertRaises(BotoServerError): |
| 97 self.service_connection.get_all_hosted_zones() |
| 98 |
| 99 self.assertEqual(self.calls['count'], 7) |
| 100 |
| 101 # Unpatch. |
| 102 self.service_connection._retry_handler = orig_retry |
| 103 |
| 104 def test_private_zone_invalid_vpc_400(self): |
| 105 self.set_http_response(status_code=400, header=[ |
| 106 ['Code', 'InvalidVPCId'], |
| 107 ]) |
| 108 |
| 109 with self.assertRaises(DNSServerError) as err: |
| 110 self.service_connection.create_hosted_zone("example.com.", |
| 111 private_zone=True) |
| 112 self.assertTrue('It failed.' in str(err.exception)) |
| 113 |
| 114 |
| 115 @attr(route53=True) |
| 116 class TestCreateZoneRoute53(AWSMockServiceTestCase): |
| 117 connection_class = Route53Connection |
| 118 |
| 119 def setUp(self): |
| 120 super(TestCreateZoneRoute53, self).setUp() |
| 121 |
| 122 def default_body(self): |
| 123 return b""" |
| 124 <CreateHostedZoneResponse xmlns="https://route53.amazonaws.com/doc/2012-02-29/"> |
| 125 <HostedZone> |
| 126 <Id>/hostedzone/Z11111</Id> |
| 127 <Name>example.com.</Name> |
| 128 <CallerReference>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</CallerReference> |
| 129 <Config> |
| 130 <Comment></Comment> |
| 131 <PrivateZone>false</PrivateZone> |
| 132 </Config> |
| 133 <ResourceRecordSetCount>2</ResourceRecordSetCount> |
| 134 </HostedZone> |
| 135 <ChangeInfo> |
| 136 <Id>/change/C1111111111111</Id> |
| 137 <Status>PENDING</Status> |
| 138 <SubmittedAt>2014-02-02T10:19:29.928Z</SubmittedAt> |
| 139 </ChangeInfo> |
| 140 <DelegationSet> |
| 141 <NameServers> |
| 142 <NameServer>ns-100.awsdns-01.com</NameServer> |
| 143 <NameServer>ns-1000.awsdns-01.co.uk</NameServer> |
| 144 <NameServer>ns-1000.awsdns-01.org</NameServer> |
| 145 <NameServer>ns-900.awsdns-01.net</NameServer> |
| 146 </NameServers> |
| 147 </DelegationSet> |
| 148 </CreateHostedZoneResponse> |
| 149 """ |
| 150 |
| 151 def test_create_zone(self): |
| 152 self.set_http_response(status_code=201) |
| 153 response = self.service_connection.create_zone("example.com.") |
| 154 |
| 155 self.assertTrue(isinstance(response, Zone)) |
| 156 self.assertEqual(response.id, "Z11111") |
| 157 self.assertEqual(response.name, "example.com.") |
| 158 |
| 159 def test_create_hosted_zone(self): |
| 160 self.set_http_response(status_code=201) |
| 161 response = self.service_connection.create_hosted_zone("example.com.", |
| 162 "my_ref", |
| 163 "a comment") |
| 164 |
| 165 self.assertEqual(response['CreateHostedZoneResponse'] |
| 166 ['DelegationSet']['NameServers'], |
| 167 ['ns-100.awsdns-01.com', |
| 168 'ns-1000.awsdns-01.co.uk', |
| 169 'ns-1000.awsdns-01.org', |
| 170 'ns-900.awsdns-01.net']) |
| 171 |
| 172 self.assertEqual(response['CreateHostedZoneResponse'] |
| 173 ['HostedZone']['Config']['PrivateZone'], |
| 174 u'false') |
| 175 |
| 176 |
| 177 @attr(route53=True) |
| 178 class TestCreatePrivateZoneRoute53(AWSMockServiceTestCase): |
| 179 connection_class = Route53Connection |
| 180 |
| 181 def setUp(self): |
| 182 super(TestCreatePrivateZoneRoute53, self).setUp() |
| 183 |
| 184 def default_body(self): |
| 185 return b""" |
| 186 <CreateHostedZoneResponse xmlns="https://route53.amazonaws.com/doc/2012-02-29/"> |
| 187 <HostedZone> |
| 188 <Id>/hostedzone/Z11111</Id> |
| 189 <Name>example.com.</Name> |
| 190 <VPC> |
| 191 <VPCId>vpc-1a2b3c4d</VPCId> |
| 192 <VPCRegion>us-east-1</VPCRegion> |
| 193 </VPC> |
| 194 <CallerReference>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</CallerReference> |
| 195 <Config> |
| 196 <Comment></Comment> |
| 197 <PrivateZone>true</PrivateZone> |
| 198 </Config> |
| 199 <ResourceRecordSetCount>2</ResourceRecordSetCount> |
| 200 </HostedZone> |
| 201 <ChangeInfo> |
| 202 <Id>/change/C1111111111111</Id> |
| 203 <Status>PENDING</Status> |
| 204 <SubmittedAt>2014-02-02T10:19:29.928Z</SubmittedAt> |
| 205 </ChangeInfo> |
| 206 <DelegationSet> |
| 207 <NameServers> |
| 208 <NameServer>ns-100.awsdns-01.com</NameServer> |
| 209 <NameServer>ns-1000.awsdns-01.co.uk</NameServer> |
| 210 <NameServer>ns-1000.awsdns-01.org</NameServer> |
| 211 <NameServer>ns-900.awsdns-01.net</NameServer> |
| 212 </NameServers> |
| 213 </DelegationSet> |
| 214 </CreateHostedZoneResponse> |
| 215 """ |
| 216 |
| 217 def test_create_private_zone(self): |
| 218 self.set_http_response(status_code=201) |
| 219 r = self.service_connection.create_hosted_zone("example.com.", |
| 220 private_zone=True, |
| 221 vpc_id='vpc-1a2b3c4d', |
| 222 vpc_region='us-east-1' |
| 223 ) |
| 224 |
| 225 self.assertEqual(r['CreateHostedZoneResponse']['HostedZone'] |
| 226 ['Config']['PrivateZone'], u'true') |
| 227 self.assertEqual(r['CreateHostedZoneResponse']['HostedZone'] |
| 228 ['VPC']['VPCId'], u'vpc-1a2b3c4d') |
| 229 self.assertEqual(r['CreateHostedZoneResponse']['HostedZone'] |
| 230 ['VPC']['VPCRegion'], u'us-east-1') |
| 231 |
| 232 |
| 233 @attr(route53=True) |
| 234 class TestGetZoneRoute53(AWSMockServiceTestCase): |
| 235 connection_class = Route53Connection |
| 236 |
| 237 def setUp(self): |
| 238 super(TestGetZoneRoute53, self).setUp() |
| 239 |
| 240 def default_body(self): |
| 241 return b""" |
| 242 <ListHostedZonesResponse xmlns="https://route53.amazonaws.com/doc/2012-02-29/"> |
| 243 <HostedZones> |
| 244 <HostedZone> |
| 245 <Id>/hostedzone/Z1111</Id> |
| 246 <Name>example2.com.</Name> |
| 247 <CallerReference>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</CallerReferen
ce> |
| 248 <Config/> |
| 249 <ResourceRecordSetCount>3</ResourceRecordSetCount> |
| 250 </HostedZone> |
| 251 <HostedZone> |
| 252 <Id>/hostedzone/Z2222</Id> |
| 253 <Name>example1.com.</Name> |
| 254 <CallerReference>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeef</CallerReferen
ce> |
| 255 <Config/> |
| 256 <ResourceRecordSetCount>6</ResourceRecordSetCount> |
| 257 </HostedZone> |
| 258 <HostedZone> |
| 259 <Id>/hostedzone/Z3333</Id> |
| 260 <Name>example.com.</Name> |
| 261 <CallerReference>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeg</CallerReferen
ce> |
| 262 <Config/> |
| 263 <ResourceRecordSetCount>6</ResourceRecordSetCount> |
| 264 </HostedZone> |
| 265 </HostedZones> |
| 266 <IsTruncated>false</IsTruncated> |
| 267 <MaxItems>100</MaxItems> |
| 268 </ListHostedZonesResponse> |
| 269 """ |
| 270 |
| 271 def test_list_zones(self): |
| 272 self.set_http_response(status_code=201) |
| 273 response = self.service_connection.get_all_hosted_zones() |
| 274 |
| 275 domains = ['example2.com.', 'example1.com.', 'example.com.'] |
| 276 print(response['ListHostedZonesResponse']['HostedZones'][0]) |
| 277 for d in response['ListHostedZonesResponse']['HostedZones']: |
| 278 print("Removing: %s" % d['Name']) |
| 279 domains.remove(d['Name']) |
| 280 |
| 281 self.assertEqual(domains, []) |
| 282 |
| 283 def test_get_zone(self): |
| 284 self.set_http_response(status_code=201) |
| 285 response = self.service_connection.get_zone('example.com.') |
| 286 |
| 287 self.assertTrue(isinstance(response, Zone)) |
| 288 self.assertEqual(response.name, "example.com.") |
| 289 |
| 290 |
| 291 @attr(route53=True) |
| 292 class TestGetHostedZoneRoute53(AWSMockServiceTestCase): |
| 293 connection_class = Route53Connection |
| 294 |
| 295 def setUp(self): |
| 296 super(TestGetHostedZoneRoute53, self).setUp() |
| 297 |
| 298 def default_body(self): |
| 299 return b""" |
| 300 <GetHostedZoneResponse xmlns="https://route53.amazonaws.com/doc/2012-02-29/"> |
| 301 <HostedZone> |
| 302 <Id>/hostedzone/Z1111</Id> |
| 303 <Name>example.com.</Name> |
| 304 <CallerReference>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</CallerReference> |
| 305 <Config/> |
| 306 <ResourceRecordSetCount>3</ResourceRecordSetCount> |
| 307 </HostedZone> |
| 308 <DelegationSet> |
| 309 <NameServers> |
| 310 <NameServer>ns-1000.awsdns-40.org</NameServer> |
| 311 <NameServer>ns-200.awsdns-30.com</NameServer> |
| 312 <NameServer>ns-900.awsdns-50.net</NameServer> |
| 313 <NameServer>ns-1000.awsdns-00.co.uk</NameServer> |
| 314 </NameServers> |
| 315 </DelegationSet> |
| 316 </GetHostedZoneResponse> |
| 317 """ |
| 318 |
| 319 def test_list_zones(self): |
| 320 self.set_http_response(status_code=201) |
| 321 response = self.service_connection.get_hosted_zone("Z1111") |
| 322 |
| 323 self.assertEqual(response['GetHostedZoneResponse'] |
| 324 ['HostedZone']['Id'], |
| 325 '/hostedzone/Z1111') |
| 326 self.assertEqual(response['GetHostedZoneResponse'] |
| 327 ['HostedZone']['Name'], |
| 328 'example.com.') |
| 329 self.assertEqual(response['GetHostedZoneResponse'] |
| 330 ['DelegationSet']['NameServers'], |
| 331 ['ns-1000.awsdns-40.org', 'ns-200.awsdns-30.com', |
| 332 'ns-900.awsdns-50.net', 'ns-1000.awsdns-00.co.uk']) |
| 333 |
| 334 |
| 335 @attr(route53=True) |
| 336 class TestGetAllRRSetsRoute53(AWSMockServiceTestCase): |
| 337 connection_class = Route53Connection |
| 338 |
| 339 def setUp(self): |
| 340 super(TestGetAllRRSetsRoute53, self).setUp() |
| 341 |
| 342 def default_body(self): |
| 343 return b""" |
| 344 <ListResourceRecordSetsResponse xmlns="https://route53.amazonaws.com/doc/2013-04
-01/"> |
| 345 <ResourceRecordSets> |
| 346 <ResourceRecordSet> |
| 347 <Name>test.example.com.</Name> |
| 348 <Type>A</Type> |
| 349 <TTL>60</TTL> |
| 350 <ResourceRecords> |
| 351 <ResourceRecord> |
| 352 <Value>10.0.0.1</Value> |
| 353 </ResourceRecord> |
| 354 </ResourceRecords> |
| 355 </ResourceRecordSet> |
| 356 <ResourceRecordSet> |
| 357 <Name>www.example.com.</Name> |
| 358 <Type>A</Type> |
| 359 <TTL>60</TTL> |
| 360 <ResourceRecords> |
| 361 <ResourceRecord> |
| 362 <Value>10.0.0.2</Value> |
| 363 </ResourceRecord> |
| 364 </ResourceRecords> |
| 365 </ResourceRecordSet> |
| 366 <ResourceRecordSet> |
| 367 <Name>us-west-2-evaluate-health.example.com.</Name> |
| 368 <Type>A</Type> |
| 369 <SetIdentifier>latency-example-us-west-2-evaluate-health</SetIdentif
ier> |
| 370 <Region>us-west-2</Region> |
| 371 <AliasTarget> |
| 372 <HostedZoneId>ABCDEFG123456</HostedZoneId> |
| 373 <EvaluateTargetHealth>true</EvaluateTargetHealth> |
| 374 <DNSName>example-123456-evaluate-health.us-west-2.elb.amazonaws.
com.</DNSName> |
| 375 </AliasTarget> |
| 376 <HealthCheckId>abcdefgh-abcd-abcd-abcd-abcdefghijkl</HealthCheckId> |
| 377 </ResourceRecordSet> |
| 378 <ResourceRecordSet> |
| 379 <Name>us-west-2-no-evaluate-health.example.com.</Name> |
| 380 <Type>A</Type> |
| 381 <SetIdentifier>latency-example-us-west-2-no-evaluate-health</SetIden
tifier> |
| 382 <Region>us-west-2</Region> |
| 383 <AliasTarget> |
| 384 <HostedZoneId>ABCDEFG567890</HostedZoneId> |
| 385 <EvaluateTargetHealth>false</EvaluateTargetHealth> |
| 386 <DNSName>example-123456-no-evaluate-health.us-west-2.elb.amazona
ws.com.</DNSName> |
| 387 </AliasTarget> |
| 388 <HealthCheckId>abcdefgh-abcd-abcd-abcd-abcdefghijkl</HealthCheckId> |
| 389 </ResourceRecordSet> |
| 390 <ResourceRecordSet> |
| 391 <Name>failover.example.com.</Name> |
| 392 <Type>A</Type> |
| 393 <SetIdentifier>failover-primary</SetIdentifier> |
| 394 <Failover>PRIMARY</Failover> |
| 395 <TTL>60</TTL> |
| 396 <ResourceRecords> |
| 397 <ResourceRecord> |
| 398 <Value>10.0.0.4</Value> |
| 399 </ResourceRecord> |
| 400 </ResourceRecords> |
| 401 </ResourceRecordSet> |
| 402 <ResourceRecordSet> |
| 403 <Name>us-west-2-evaluate-health-healthcheck.example.com.</Name> |
| 404 <Type>A</Type> |
| 405 <SetIdentifier>latency-example-us-west-2-evaluate-health-healthcheck
</SetIdentifier> |
| 406 <Region>us-west-2</Region> |
| 407 <AliasTarget> |
| 408 <HostedZoneId>ABCDEFG123456</HostedZoneId> |
| 409 <EvaluateTargetHealth>true</EvaluateTargetHealth> |
| 410 <DNSName>example-123456-evaluate-health-healthcheck.us-west-2.el
b.amazonaws.com.</DNSName> |
| 411 </AliasTarget> |
| 412 <HealthCheckId>076a32f8-86f7-4c9e-9fa2-c163d5be67d9</HealthCheckId> |
| 413 </ResourceRecordSet> |
| 414 </ResourceRecordSets> |
| 415 <IsTruncated>false</IsTruncated> |
| 416 <MaxItems>100</MaxItems> |
| 417 </ListResourceRecordSetsResponse> |
| 418 """ |
| 419 |
| 420 def test_get_all_rr_sets(self): |
| 421 self.set_http_response(status_code=200) |
| 422 response = self.service_connection.get_all_rrsets("Z1111", |
| 423 "A", |
| 424 "example.com.") |
| 425 |
| 426 self.assertIn(self.actual_request.path, |
| 427 ("/2013-04-01/hostedzone/Z1111/rrset?type=A&name=example.c
om.", |
| 428 "/2013-04-01/hostedzone/Z1111/rrset?name=example.com.&typ
e=A")) |
| 429 |
| 430 self.assertTrue(isinstance(response, ResourceRecordSets)) |
| 431 self.assertEqual(response.hosted_zone_id, "Z1111") |
| 432 self.assertTrue(isinstance(response[0], Record)) |
| 433 |
| 434 self.assertTrue(response[0].name, "test.example.com.") |
| 435 self.assertTrue(response[0].ttl, "60") |
| 436 self.assertTrue(response[0].type, "A") |
| 437 |
| 438 evaluate_record = response[2] |
| 439 self.assertEqual(evaluate_record.name, 'us-west-2-evaluate-health.exampl
e.com.') |
| 440 self.assertEqual(evaluate_record.type, 'A') |
| 441 self.assertEqual(evaluate_record.identifier, 'latency-example-us-west-2-
evaluate-health') |
| 442 self.assertEqual(evaluate_record.region, 'us-west-2') |
| 443 self.assertEqual(evaluate_record.alias_hosted_zone_id, 'ABCDEFG123456') |
| 444 self.assertTrue(evaluate_record.alias_evaluate_target_health) |
| 445 self.assertEqual(evaluate_record.alias_dns_name, 'example-123456-evaluat
e-health.us-west-2.elb.amazonaws.com.') |
| 446 evaluate_xml = evaluate_record.to_xml() |
| 447 self.assertTrue(evaluate_record.health_check, 'abcdefgh-abcd-abcd-abcd-a
bcdefghijkl') |
| 448 self.assertTrue('<EvaluateTargetHealth>true</EvaluateTargetHealth>' in e
valuate_xml) |
| 449 |
| 450 no_evaluate_record = response[3] |
| 451 self.assertEqual(no_evaluate_record.name, 'us-west-2-no-evaluate-health.
example.com.') |
| 452 self.assertEqual(no_evaluate_record.type, 'A') |
| 453 self.assertEqual(no_evaluate_record.identifier, 'latency-example-us-west
-2-no-evaluate-health') |
| 454 self.assertEqual(no_evaluate_record.region, 'us-west-2') |
| 455 self.assertEqual(no_evaluate_record.alias_hosted_zone_id, 'ABCDEFG567890
') |
| 456 self.assertFalse(no_evaluate_record.alias_evaluate_target_health) |
| 457 self.assertEqual(no_evaluate_record.alias_dns_name, 'example-123456-no-e
valuate-health.us-west-2.elb.amazonaws.com.') |
| 458 no_evaluate_xml = no_evaluate_record.to_xml() |
| 459 self.assertTrue(no_evaluate_record.health_check, 'abcdefgh-abcd-abcd-abc
d-abcdefghijkl') |
| 460 self.assertTrue('<EvaluateTargetHealth>false</EvaluateTargetHealth>' in
no_evaluate_xml) |
| 461 |
| 462 failover_record = response[4] |
| 463 self.assertEqual(failover_record.name, 'failover.example.com.') |
| 464 self.assertEqual(failover_record.type, 'A') |
| 465 self.assertEqual(failover_record.identifier, 'failover-primary') |
| 466 self.assertEqual(failover_record.failover, 'PRIMARY') |
| 467 self.assertEqual(failover_record.ttl, '60') |
| 468 |
| 469 healthcheck_record = response[5] |
| 470 self.assertEqual(healthcheck_record.health_check, '076a32f8-86f7-4c9e-9f
a2-c163d5be67d9') |
| 471 self.assertEqual(healthcheck_record.name, 'us-west-2-evaluate-health-hea
lthcheck.example.com.') |
| 472 self.assertEqual(healthcheck_record.identifier, 'latency-example-us-west
-2-evaluate-health-healthcheck') |
| 473 self.assertEqual(healthcheck_record.alias_dns_name, 'example-123456-eval
uate-health-healthcheck.us-west-2.elb.amazonaws.com.') |
| 474 |
| 475 |
| 476 @attr(route53=True) |
| 477 class TestTruncatedGetAllRRSetsRoute53(AWSMockServiceTestCase): |
| 478 connection_class = Route53Connection |
| 479 |
| 480 def setUp(self): |
| 481 super(TestTruncatedGetAllRRSetsRoute53, self).setUp() |
| 482 |
| 483 def default_body(self): |
| 484 return b""" |
| 485 <ListResourceRecordSetsResponse xmlns="https://route53.amazonaws.com/doc/2013-04
-01/"> |
| 486 <ResourceRecordSets> |
| 487 <ResourceRecordSet> |
| 488 <Name>example.com.</Name> |
| 489 <Type>NS</Type> |
| 490 <TTL>900</TTL> |
| 491 <ResourceRecords> |
| 492 <ResourceRecord> |
| 493 <Value>ns-91.awsdns-41.co.uk.</Value> |
| 494 </ResourceRecord> |
| 495 <ResourceRecord> |
| 496 <Value>ns-1929.awsdns-93.net.</Value> |
| 497 </ResourceRecord> |
| 498 <ResourceRecord> |
| 499 <Value>ns-12.awsdns-21.org.</Value> |
| 500 </ResourceRecord> |
| 501 <ResourceRecord> |
| 502 <Value>ns-102.awsdns-96.com.</Value> |
| 503 </ResourceRecord> |
| 504 </ResourceRecords> |
| 505 </ResourceRecordSet> |
| 506 <ResourceRecordSet> |
| 507 <Name>example.com.</Name> |
| 508 <Type>SOA</Type> |
| 509 <TTL>1800</TTL> |
| 510 <ResourceRecords> |
| 511 <ResourceRecord> |
| 512 <Value>ns-1929.awsdns-93.net. hostmaster.awsdns.net. 1 10800 3600 6048
00 1800</Value> |
| 513 </ResourceRecord> |
| 514 </ResourceRecords> |
| 515 </ResourceRecordSet> |
| 516 <ResourceRecordSet> |
| 517 <Name>wrr.example.com.</Name> |
| 518 <Type>A</Type> |
| 519 <SetIdentifier>primary</SetIdentifier> |
| 520 <Weight>100</Weight> |
| 521 <TTL>300</TTL> |
| 522 <ResourceRecords> |
| 523 <ResourceRecord><Value>127.0.0.1</Value></ResourceRecord> |
| 524 </ResourceRecords> |
| 525 </ResourceRecordSet> |
| 526 </ResourceRecordSets> |
| 527 <IsTruncated>true</IsTruncated> |
| 528 <NextRecordName>wrr.example.com.</NextRecordName> |
| 529 <NextRecordType>A</NextRecordType> |
| 530 <NextRecordIdentifier>secondary</NextRecordIdentifier> |
| 531 <MaxItems>3</MaxItems> |
| 532 </ListResourceRecordSetsResponse>""" |
| 533 |
| 534 def paged_body(self): |
| 535 return b""" |
| 536 <ListResourceRecordSetsResponse xmlns="https://route53.amazonaws.com/doc/2013-04
-01/"> |
| 537 <ResourceRecordSets> |
| 538 <ResourceRecordSet> |
| 539 <Name>wrr.example.com.</Name> |
| 540 <Type>A</Type> |
| 541 <SetIdentifier>secondary</SetIdentifier> |
| 542 <Weight>50</Weight> |
| 543 <TTL>300</TTL> |
| 544 <ResourceRecords> |
| 545 <ResourceRecord><Value>127.0.0.2</Value></ResourceRecord> |
| 546 </ResourceRecords> |
| 547 </ResourceRecordSet> |
| 548 </ResourceRecordSets> |
| 549 <IsTruncated>false</IsTruncated> |
| 550 <MaxItems>3</MaxItems> |
| 551 </ListResourceRecordSetsResponse>""" |
| 552 |
| 553 |
| 554 def test_get_all_rr_sets(self): |
| 555 self.set_http_response(status_code=200) |
| 556 response = self.service_connection.get_all_rrsets("Z1111", maxitems=3) |
| 557 |
| 558 # made first request |
| 559 self.assertEqual(self.actual_request.path, '/2013-04-01/hostedzone/Z1111
/rrset?maxitems=3') |
| 560 |
| 561 # anticipate a second request when we page it |
| 562 self.set_http_response(status_code=200, body=self.paged_body()) |
| 563 |
| 564 # this should trigger another call to get_all_rrsets |
| 565 self.assertEqual(len(list(response)), 4) |
| 566 |
| 567 url_parts = urllib.parse.urlparse(self.actual_request.path) |
| 568 self.assertEqual(url_parts.path, '/2013-04-01/hostedzone/Z1111/rrset') |
| 569 self.assertEqual(urllib.parse.parse_qs(url_parts.query), |
| 570 dict(type=['A'], name=['wrr.example.com.'], identifier=
['secondary'])) |
| 571 |
| 572 |
| 573 @attr(route53=True) |
| 574 class TestCreateHealthCheckRoute53IpAddress(AWSMockServiceTestCase): |
| 575 connection_class = Route53Connection |
| 576 |
| 577 def setUp(self): |
| 578 super(TestCreateHealthCheckRoute53IpAddress, self).setUp() |
| 579 |
| 580 def default_body(self): |
| 581 return b""" |
| 582 <CreateHealthCheckResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/"
> |
| 583 <HealthCheck> |
| 584 <Id>34778cf8-e31e-4974-bad0-b108bd1623d3</Id> |
| 585 <CallerReference>2fa48c8f-76ef-4253-9874-8bcb2b0d7694</CallerReference> |
| 586 <HealthCheckConfig> |
| 587 <IPAddress>74.125.228.81</IPAddress> |
| 588 <Port>443</Port> |
| 589 <Type>HTTPS_STR_MATCH</Type> |
| 590 <SearchString>OK</SearchString> |
| 591 <ResourcePath>/health_check</ResourcePath> |
| 592 <RequestInterval>30</RequestInterval> |
| 593 <FailureThreshold>3</FailureThreshold> |
| 594 </HealthCheckConfig> |
| 595 </HealthCheck> |
| 596 </CreateHealthCheckResponse> |
| 597 """ |
| 598 |
| 599 def test_create_health_check_ip_address(self): |
| 600 self.set_http_response(status_code=201) |
| 601 hc = HealthCheck(ip_addr='74.125.228.81', port=443, hc_type='HTTPS_STR_M
ATCH', resource_path='/health_check', string_match='OK') |
| 602 hc_xml = hc.to_xml() |
| 603 self.assertFalse('<FullyQualifiedDomainName>' in hc_xml) |
| 604 self.assertTrue('<IPAddress>' in hc_xml) |
| 605 |
| 606 response = self.service_connection.create_health_check(hc) |
| 607 hc_resp = response['CreateHealthCheckResponse']['HealthCheck']['HealthCh
eckConfig'] |
| 608 self.assertEqual(hc_resp['IPAddress'], '74.125.228.81') |
| 609 self.assertEqual(hc_resp['ResourcePath'], '/health_check') |
| 610 self.assertEqual(hc_resp['Type'], 'HTTPS_STR_MATCH') |
| 611 self.assertEqual(hc_resp['Port'], '443') |
| 612 self.assertEqual(hc_resp['ResourcePath'], '/health_check') |
| 613 self.assertEqual(hc_resp['SearchString'], 'OK') |
| 614 self.assertEqual(response['CreateHealthCheckResponse']['HealthCheck']['I
d'], '34778cf8-e31e-4974-bad0-b108bd1623d3') |
| 615 |
| 616 |
| 617 @attr(route53=True) |
| 618 class TestGetCheckerIpRanges(AWSMockServiceTestCase): |
| 619 connection_class = Route53Connection |
| 620 |
| 621 def default_body(self): |
| 622 return b""" |
| 623 <GetCheckerIpRangesResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/
"> |
| 624 <CheckerIpRanges> |
| 625 <member>54.183.255.128/26</member> |
| 626 <member>54.228.16.0/26</member> |
| 627 <member>54.232.40.64/26</member> |
| 628 <member>177.71.207.128/26</member> |
| 629 <member>176.34.159.192/26</member> |
| 630 </CheckerIpRanges> |
| 631 </GetCheckerIpRangesResponse> |
| 632 """ |
| 633 |
| 634 def test_get_checker_ip_ranges(self): |
| 635 self.set_http_response(status_code=200) |
| 636 response = self.service_connection.get_checker_ip_ranges() |
| 637 ip_ranges = response['GetCheckerIpRangesResponse']['CheckerIpRanges'] |
| 638 |
| 639 self.assertEqual(len(ip_ranges), 5) |
| 640 self.assertIn('54.183.255.128/26', ip_ranges) |
| 641 self.assertIn('54.228.16.0/26', ip_ranges) |
| 642 self.assertIn('54.232.40.64/26', ip_ranges) |
| 643 self.assertIn('177.71.207.128/26', ip_ranges) |
| 644 self.assertIn('176.34.159.192/26', ip_ranges) |
| 645 |
| 646 |
| 647 @attr(route53=True) |
| 648 class TestCreateHealthCheckRoute53FQDN(AWSMockServiceTestCase): |
| 649 connection_class = Route53Connection |
| 650 |
| 651 def setUp(self): |
| 652 super(TestCreateHealthCheckRoute53FQDN, self).setUp() |
| 653 |
| 654 def default_body(self): |
| 655 return b""" |
| 656 <CreateHealthCheckResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/"
> |
| 657 <HealthCheck> |
| 658 <Id>f9abfe10-8d2a-4bbd-8f35-796f0f8572f2</Id> |
| 659 <CallerReference>3246ac17-b651-4295-a5c8-c132a59693d7</CallerReference> |
| 660 <HealthCheckConfig> |
| 661 <Port>443</Port> |
| 662 <Type>HTTPS</Type> |
| 663 <ResourcePath>/health_check</ResourcePath> |
| 664 <FullyQualifiedDomainName>example.com</FullyQualifiedDomainName> |
| 665 <RequestInterval>30</RequestInterval> |
| 666 <FailureThreshold>3</FailureThreshold> |
| 667 </HealthCheckConfig> |
| 668 </HealthCheck> |
| 669 </CreateHealthCheckResponse> |
| 670 """ |
| 671 |
| 672 def test_create_health_check_fqdn(self): |
| 673 self.set_http_response(status_code=201) |
| 674 hc = HealthCheck(ip_addr='', port=443, hc_type='HTTPS', resource_path='/
health_check', fqdn='example.com') |
| 675 hc_xml = hc.to_xml() |
| 676 self.assertTrue('<FullyQualifiedDomainName>' in hc_xml) |
| 677 self.assertFalse('<IPAddress>' in hc_xml) |
| 678 |
| 679 response = self.service_connection.create_health_check(hc) |
| 680 hc_resp = response['CreateHealthCheckResponse']['HealthCheck']['HealthCh
eckConfig'] |
| 681 self.assertEqual(hc_resp['FullyQualifiedDomainName'], 'example.com') |
| 682 self.assertEqual(hc_resp['ResourcePath'], '/health_check') |
| 683 self.assertEqual(hc_resp['Type'], 'HTTPS') |
| 684 self.assertEqual(hc_resp['Port'], '443') |
| 685 self.assertEqual(hc_resp['ResourcePath'], '/health_check') |
| 686 self.assertEqual(response['CreateHealthCheckResponse']['HealthCheck']['I
d'], 'f9abfe10-8d2a-4bbd-8f35-796f0f8572f2') |
| 687 |
| 688 |
| 689 @attr(route53=True) |
| 690 class TestChangeResourceRecordSetsRoute53(AWSMockServiceTestCase): |
| 691 connection_class = Route53Connection |
| 692 |
| 693 def setUp(self): |
| 694 super(TestChangeResourceRecordSetsRoute53, self).setUp() |
| 695 |
| 696 def default_body(self): |
| 697 return b""" |
| 698 <ChangeResourceRecordSetsResponse xmlns="https://route53.amazonaws.com/doc/2013-
04-01/"> |
| 699 <ChangeInfo> |
| 700 <Id>/change/C1111111111111</Id> |
| 701 <Status>PENDING</Status> |
| 702 <SubmittedAt>2014-05-05T10:11:12.123Z</SubmittedAt> |
| 703 </ChangeInfo> |
| 704 </ChangeResourceRecordSetsResponse> |
| 705 """ |
| 706 |
| 707 def test_record_commit(self): |
| 708 rrsets = ResourceRecordSets(self.service_connection) |
| 709 rrsets.add_change_record('CREATE', Record('vanilla.example.com', 'A', 60
, ['1.2.3.4'])) |
| 710 rrsets.add_change_record('CREATE', Record('alias.example.com', 'AAAA', a
lias_hosted_zone_id='Z123OTHER', alias_dns_name='target.other', alias_evaluate_t
arget_health=True)) |
| 711 rrsets.add_change_record('CREATE', Record('wrr.example.com', 'CNAME', 60
, ['cname.target'], weight=10, identifier='weight-1')) |
| 712 rrsets.add_change_record('CREATE', Record('lbr.example.com', 'TXT', 60,
['text record'], region='us-west-2', identifier='region-1')) |
| 713 rrsets.add_change_record('CREATE', Record('failover.example.com', 'A', 6
0, ['2.2.2.2'], health_check='hc-1234', failover='PRIMARY', identifier='primary'
)) |
| 714 |
| 715 changes_xml = rrsets.to_xml() |
| 716 |
| 717 # the whitespacing doesn't match exactly, so we'll pretty print and drop
all new lines |
| 718 # not the best, but |
| 719 actual_xml = re.sub(r"\s*[\r\n]+", "\n", xml.dom.minidom.parseString(cha
nges_xml).toprettyxml()) |
| 720 expected_xml = re.sub(r"\s*[\r\n]+", "\n", xml.dom.minidom.parseString(b
""" |
| 721 <ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/2013-0
4-01/"> |
| 722 <ChangeBatch> |
| 723 <Comment>None</Comment> |
| 724 <Changes> |
| 725 <Change> |
| 726 <Action>CREATE</Action> |
| 727 <ResourceRecordSet> |
| 728 <Name>vanilla.example.com</Name> |
| 729 <Type>A</Type> |
| 730 <TTL>60</TTL> |
| 731 <ResourceRecords> |
| 732 <ResourceRecord> |
| 733 <Value>1.2.3.4</Value> |
| 734 </ResourceRecord> |
| 735 </ResourceRecords> |
| 736 </ResourceRecordSet> |
| 737 </Change> |
| 738 <Change> |
| 739 <Action>CREATE</Action> |
| 740 <ResourceRecordSet> |
| 741 <Name>alias.example.com</Name> |
| 742 <Type>AAAA</Type> |
| 743 <AliasTarget> |
| 744 <HostedZoneId>Z123OTHER</HostedZoneId> |
| 745 <DNSName>target.other</DNSName> |
| 746 <EvaluateTargetHealth>true</EvaluateTargetHealth> |
| 747 </AliasTarget> |
| 748 </ResourceRecordSet> |
| 749 </Change> |
| 750 <Change> |
| 751 <Action>CREATE</Action> |
| 752 <ResourceRecordSet> |
| 753 <Name>wrr.example.com</Name> |
| 754 <Type>CNAME</Type> |
| 755 <SetIdentifier>weight-1</SetIdentifier> |
| 756 <Weight>10</Weight> |
| 757 <TTL>60</TTL> |
| 758 <ResourceRecords> |
| 759 <ResourceRecord> |
| 760 <Value>cname.target</Value> |
| 761 </ResourceRecord> |
| 762 </ResourceRecords> |
| 763 </ResourceRecordSet> |
| 764 </Change> |
| 765 <Change> |
| 766 <Action>CREATE</Action> |
| 767 <ResourceRecordSet> |
| 768 <Name>lbr.example.com</Name> |
| 769 <Type>TXT</Type> |
| 770 <SetIdentifier>region-1</SetIdentifier> |
| 771 <Region>us-west-2</Region> |
| 772 <TTL>60</TTL> |
| 773 <ResourceRecords> |
| 774 <ResourceRecord> |
| 775 <Value>text record</Value> |
| 776 </ResourceRecord> |
| 777 </ResourceRecords> |
| 778 </ResourceRecordSet> |
| 779 </Change> |
| 780 <Change> |
| 781 <Action>CREATE</Action> |
| 782 <ResourceRecordSet> |
| 783 <Name>failover.example.com</Name> |
| 784 <Type>A</Type> |
| 785 <SetIdentifier>primary</SetIdentifier> |
| 786 <Failover>PRIMARY</Failover> |
| 787 <TTL>60</TTL> |
| 788 <ResourceRecords> |
| 789 <ResourceRecord> |
| 790 <Value>2.2.2.2</Value> |
| 791 </ResourceRecord> |
| 792 </ResourceRecords> |
| 793 <HealthCheckId>hc-1234</HealthCheckId> |
| 794 </ResourceRecordSet> |
| 795 </Change> |
| 796 </Changes> |
| 797 </ChangeBatch> |
| 798 </ChangeResourceRecordSetsRequest> |
| 799 """).toprettyxml()) |
| 800 |
| 801 # Note: the alias XML should not include the TTL, even if it's specified
in the object model |
| 802 self.assertEqual(actual_xml, expected_xml) |
OLD | NEW |