From 8fa53c14532609889ca9e53584936dd183aff6ef Mon Sep 17 00:00:00 2001 From: hummus Date: Fri, 3 Jun 2016 09:57:33 -0400 Subject: [PATCH] support route53 HostedZone PrivateZone=True #627 --- moto/route53/models.py | 10 +++---- moto/route53/responses.py | 15 +++++++++- tests/test_route53/test_route53.py | 45 ++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/moto/route53/models.py b/moto/route53/models.py index 845991c5a..a20867b54 100644 --- a/moto/route53/models.py +++ b/moto/route53/models.py @@ -147,12 +147,12 @@ class RecordSet(object): class FakeZone(object): - def __init__(self, name, id_, comment=None): + def __init__(self, name, id_, private_zone, comment=None): self.name = name self.id = id_ if comment is not None: self.comment = comment - self.private_zone = False + self.private_zone = private_zone self.rrsets = [] def add_rrset(self, record_set): @@ -194,7 +194,7 @@ class FakeZone(object): properties = cloudformation_json['Properties'] name = properties["Name"] - hosted_zone = route53_backend.create_hosted_zone(name) + hosted_zone = route53_backend.create_hosted_zone(name, private_zone=False) return hosted_zone @@ -227,9 +227,9 @@ class Route53Backend(BaseBackend): self.zones = {} self.health_checks = {} - def create_hosted_zone(self, name, comment=None): + def create_hosted_zone(self, name, private_zone, comment=None): new_id = get_random_hex() - new_zone = FakeZone(name, new_id, comment=comment) + new_zone = FakeZone(name, new_id, private_zone=private_zone, comment=comment) self.zones[new_id] = new_zone return new_zone diff --git a/moto/route53/responses.py b/moto/route53/responses.py index 25c5d05cc..db520df5a 100644 --- a/moto/route53/responses.py +++ b/moto/route53/responses.py @@ -11,9 +11,21 @@ def list_or_create_hostzone_response(request, full_url, headers): elements = xmltodict.parse(request.body) if "HostedZoneConfig" in elements["CreateHostedZoneRequest"]: comment = elements["CreateHostedZoneRequest"]["HostedZoneConfig"]["Comment"] + try: + # in boto3, this field is set directly in the xml + private_zone = elements["CreateHostedZoneRequest"]["HostedZoneConfig"]["PrivateZone"] + except KeyError: + # if a VPC subsection is only included in xmls params when private_zone=True, + # see boto: boto/route53/connection.py + private_zone = 'VPC' in elements["CreateHostedZoneRequest"] else: comment = None - new_zone = route53_backend.create_hosted_zone(elements["CreateHostedZoneRequest"]["Name"], comment=comment) + private_zone = False + new_zone = route53_backend.create_hosted_zone( + elements["CreateHostedZoneRequest"]["Name"], + comment=comment, + private_zone=private_zone, + ) template = Template(CREATE_HOSTED_ZONE_RESPONSE) return 201, headers, template.render(zone=new_zone) @@ -32,6 +44,7 @@ def get_or_delete_hostzone_response(request, full_url, headers): if request.method == "GET": template = Template(GET_HOSTED_ZONE_RESPONSE) + return 200, headers, template.render(zone=the_zone) elif request.method == "DELETE": route53_backend.delete_hosted_zone(zoneid) diff --git a/tests/test_route53/test_route53.py b/tests/test_route53/test_route53.py index 08c2382b2..c6c36ce35 100644 --- a/tests/test_route53/test_route53.py +++ b/tests/test_route53/test_route53.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals import boto +import boto3 from boto.route53.healthcheck import HealthCheck from boto.route53.record import ResourceRecordSets @@ -283,3 +284,47 @@ def test_deleting_latency_route(): # When get_cname only had one result, it returns just that result instead of a list. cname.identifier.should.equal('success-test-bar') cname.region.should.equal('us-west-1') + + +@mock_route53 +def test_hosted_zone_private_zone_preserved(): + conn = boto.connect_route53('the_key', 'the_secret') + + firstzone = conn.create_hosted_zone("testdns.aws.com.", private_zone=True, vpc_id='vpc-fake', vpc_region='us-east-1') + zone_id = firstzone["CreateHostedZoneResponse"]["HostedZone"]["Id"].split("/")[-1] + + hosted_zone = conn.get_hosted_zone(zone_id) + # in (original) boto, these bools returned as strings. + hosted_zone["GetHostedZoneResponse"]["HostedZone"]["Config"]["PrivateZone"].should.equal('True') + + hosted_zones = conn.get_all_hosted_zones() + hosted_zones["ListHostedZonesResponse"]["HostedZones"][0]["Config"]["PrivateZone"].should.equal('True') + + zone = conn.get_zone("testdns.aws.com.") + zone.config["PrivateZone"].should.equal('True') + + +@mock_route53 +def test_hosted_zone_private_zone_preserved_boto3(): + conn = boto3.client('route53') + # TODO: actually create_hosted_zone statements with PrivateZone=True, but without + # a _valid_ vpc-id should fail. + firstzone = conn.create_hosted_zone( + Name="testdns.aws.com.", + CallerReference=str(hash('foo')), + HostedZoneConfig=dict( + PrivateZone=True, + Comment="Test", + ) + ) + + zone_id = firstzone["HostedZone"]["Id"].split("/")[-1] + + hosted_zone = conn.get_hosted_zone(Id=zone_id) + hosted_zone["HostedZone"]["Config"]["PrivateZone"].should.equal(True) + + hosted_zones = conn.list_hosted_zones() + hosted_zones["HostedZones"][0]["Config"]["PrivateZone"].should.equal(True) + + # zone = conn.list_hosted_zones_by_name(DNSName="testdns.aws.com.") + # zone.config["PrivateZone"].should.equal(True)