diff --git a/moto/route53/models.py b/moto/route53/models.py
index f87b32820..cd500afeb 100644
--- a/moto/route53/models.py
+++ b/moto/route53/models.py
@@ -1,8 +1,39 @@
from __future__ import unicode_literals
+
+from jinja2 import Template
+
from moto.core import BaseBackend
from moto.core.utils import get_random_hex
+class RecordSet(object):
+ def __init__(self, kwargs):
+ self.name = kwargs.get('Name')
+ self.type = kwargs.get('Type')
+ self.ttl = kwargs.get('TTL')
+ self.records = kwargs.get('ResourceRecords', [])
+ self.set_identifier = kwargs.get('SetIdentifier')
+ self.weight = kwargs.get('Weight')
+
+ def to_xml(self):
+ template = Template("""
+ {{ record_set.name }}
+ {{ record_set.type }}
+ {{ record_set.set_identifier }}
+ {{ record_set.weight }}
+ {{ record_set.ttl }}
+
+ {% for record in record_set.records %}
+
+ {{ record }}
+
+ {% endfor %}
+
+
+ """)
+ return template.render(record_set=self)
+
+
class FakeZone(object):
def __init__(self, name, id_):
@@ -10,11 +41,21 @@ class FakeZone(object):
self.id = id_
self.rrsets = []
- def add_rrset(self, name, rrset):
- self.rrsets.append(rrset)
+ def add_rrset(self, record_set):
+ record_set = RecordSet(record_set)
+ self.rrsets.append(record_set)
def delete_rrset(self, name):
- self.rrsets = [record_set for record_set in self.rrsets if record_set['Name'] != name]
+ self.rrsets = [record_set for record_set in self.rrsets if record_set.name != name]
+
+ def get_record_sets(self, type_filter, name_filter):
+ record_sets = list(self.rrsets) # Copy the list
+ if type_filter:
+ record_sets = [record_set for record_set in record_sets if record_set.type == type_filter]
+ if name_filter:
+ record_sets = [record_set for record_set in record_sets if record_set.name == name_filter]
+
+ return record_sets
@property
def physical_resource_id(self):
@@ -30,9 +71,14 @@ class FakeZone(object):
class RecordSetGroup(object):
- def __init__(self, record_sets):
+ def __init__(self, hosted_zone_id, record_sets):
+ self.hosted_zone_id = hosted_zone_id
self.record_sets = record_sets
+ @property
+ def physical_resource_id(self):
+ return "arn:aws:route53:::hostedzone/{0}".format(self.hosted_zone_id)
+
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
@@ -41,9 +87,9 @@ class RecordSetGroup(object):
hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)
record_sets = properties["RecordSets"]
for record_set in record_sets:
- hosted_zone.add_rrset(record_set["Name"], record_set)
+ hosted_zone.add_rrset(record_set)
- record_set_group = RecordSetGroup(record_sets)
+ record_set_group = RecordSetGroup(hosted_zone.id, record_sets)
return record_set_group
diff --git a/moto/route53/responses.py b/moto/route53/responses.py
index 71a2acd7d..d110ebd55 100644
--- a/moto/route53/responses.py
+++ b/moto/route53/responses.py
@@ -3,7 +3,6 @@ from jinja2 import Template
from six.moves.urllib.parse import parse_qs, urlparse
from .models import route53_backend
import xmltodict
-import dicttoxml
def list_or_create_hostzone_response(request, full_url, headers):
@@ -53,33 +52,28 @@ def rrset_response(request, full_url, headers):
for value in change_list:
action = value['Action']
- rrset = value['ResourceRecordSet']
-
+ record_set = value['ResourceRecordSet']
if action == 'CREATE':
- the_zone.add_rrset(rrset["Name"], rrset)
+ record_set['ResourceRecords'] = [x['Value'] for x in record_set['ResourceRecords'].values()]
+ the_zone.add_rrset(record_set)
elif action == "DELETE":
- the_zone.delete_rrset(rrset["Name"])
+ the_zone.delete_rrset(record_set["Name"])
return 200, headers, CHANGE_RRSET_RESPONSE
elif method == "GET":
querystring = parse_qs(parsed_url.query)
template = Template(LIST_RRSET_REPONSE)
- rrset_list = []
- for record_set in the_zone.rrsets:
- if 'type' in querystring and querystring["type"][0] != record_set["Type"]:
- continue
- if 'name' in querystring and querystring["name"][0] != record_set["Name"]:
- continue
- rrset_list.append(dicttoxml.dicttoxml({"ResourceRecordSet": record_set}, root=False))
-
- return 200, headers, template.render(rrsets=rrset_list)
+ type_filter = querystring.get("type", [None])[0]
+ name_filter = querystring.get("name", [None])[0]
+ record_sets = the_zone.get_record_sets(type_filter, name_filter)
+ return 200, headers, template.render(record_sets=record_sets)
LIST_RRSET_REPONSE = """
- {% for rrset in rrsets %}
- {{ rrset }}
+ {% for record_set in record_sets %}
+ {{ record_set.to_xml() }}
{% endfor %}
"""
diff --git a/tests/test_cloudformation/test_cloudformation_stack_integration.py b/tests/test_cloudformation/test_cloudformation_stack_integration.py
index a138a4963..614203eec 100644
--- a/tests/test_cloudformation/test_cloudformation_stack_integration.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_integration.py
@@ -780,7 +780,7 @@ def test_route53_roundrobin():
template_json = json.dumps(route53_roundrobin.template)
conn = boto.cloudformation.connect_to_region("us-west-1")
- conn.create_stack(
+ stack = conn.create_stack(
"test_stack",
template_body=template_json,
)
@@ -798,7 +798,7 @@ def test_route53_roundrobin():
record_set1.type.should.equal('CNAME')
record_set1.ttl.should.equal('900')
record_set1.weight.should.equal('3')
- # FIXME record_set1.resource_records[0].should.equal("aws.amazon.com")
+ record_set1.resource_records[0].should.equal("aws.amazon.com")
record_set2 = rrsets[1]
record_set2.name.should.equal('test_stack.us-west-1.my_zone.')
@@ -806,4 +806,9 @@ def test_route53_roundrobin():
record_set2.type.should.equal('CNAME')
record_set2.ttl.should.equal('900')
record_set2.weight.should.equal('1')
- # FIXME record_set2.resource_records[0].should.equal("www.amazon.com")
+ record_set2.resource_records[0].should.equal("www.amazon.com")
+
+ stack = conn.describe_stacks()[0]
+ output = stack.outputs[0]
+ output.key.should.equal('DomainName')
+ output.value.should.equal('arn:aws:route53:::hostedzone/{0}'.format(zone_id))