We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Resources in mentioned in cloud formation template is not getting created.
Hi,
I am creating security group through cloud formation template and then trying to retrieve that through boto client but it says that security group does not exists. If i create security group through command line then i am able to fetch it.
It seems like resources in cloud formation does not get created when we deploy it.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `moto/route53/models.py`
Content:
```
1 from __future__ import unicode_literals
2 
3 from collections import defaultdict
4 
5 import string
6 import random
7 import uuid
8 from jinja2 import Template
9 
10 from moto.core import BaseBackend, BaseModel
11 
12 
13 ROUTE53_ID_CHOICE = string.ascii_uppercase + string.digits
14 
15 
16 def create_route53_zone_id():
17     # New ID's look like this Z1RWWTK7Y8UDDQ
18     return ''.join([random.choice(ROUTE53_ID_CHOICE) for _ in range(0, 15)])
19 
20 
21 class HealthCheck(BaseModel):
22 
23     def __init__(self, health_check_id, health_check_args):
24         self.id = health_check_id
25         self.ip_address = health_check_args.get("ip_address")
26         self.port = health_check_args.get("port", 80)
27         self._type = health_check_args.get("type")
28         self.resource_path = health_check_args.get("resource_path")
29         self.fqdn = health_check_args.get("fqdn")
30         self.search_string = health_check_args.get("search_string")
31         self.request_interval = health_check_args.get("request_interval", 30)
32         self.failure_threshold = health_check_args.get("failure_threshold", 3)
33 
34     @property
35     def physical_resource_id(self):
36         return self.id
37 
38     @classmethod
39     def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
40         properties = cloudformation_json['Properties']['HealthCheckConfig']
41         health_check_args = {
42             "ip_address": properties.get('IPAddress'),
43             "port": properties.get('Port'),
44             "type": properties['Type'],
45             "resource_path": properties.get('ResourcePath'),
46             "fqdn": properties.get('FullyQualifiedDomainName'),
47             "search_string": properties.get('SearchString'),
48             "request_interval": properties.get('RequestInterval'),
49             "failure_threshold": properties.get('FailureThreshold'),
50         }
51         health_check = route53_backend.create_health_check(health_check_args)
52         return health_check
53 
54     def to_xml(self):
55         template = Template("""<HealthCheck>
56             <Id>{{ health_check.id }}</Id>
57             <CallerReference>example.com 192.0.2.17</CallerReference>
58             <HealthCheckConfig>
59                 <IPAddress>{{ health_check.ip_address }}</IPAddress>
60                 <Port>{{ health_check.port }}</Port>
61                 <Type>{{ health_check._type }}</Type>
62                 <ResourcePath>{{ health_check.resource_path }}</ResourcePath>
63                 <FullyQualifiedDomainName>{{ health_check.fqdn }}</FullyQualifiedDomainName>
64                 <RequestInterval>{{ health_check.request_interval }}</RequestInterval>
65                 <FailureThreshold>{{ health_check.failure_threshold }}</FailureThreshold>
66                 {% if health_check.search_string %}
67                     <SearchString>{{ health_check.search_string }}</SearchString>
68                 {% endif %}
69             </HealthCheckConfig>
70             <HealthCheckVersion>1</HealthCheckVersion>
71         </HealthCheck>""")
72         return template.render(health_check=self)
73 
74 
75 class RecordSet(BaseModel):
76 
77     def __init__(self, kwargs):
78         self.name = kwargs.get('Name')
79         self._type = kwargs.get('Type')
80         self.ttl = kwargs.get('TTL')
81         self.records = kwargs.get('ResourceRecords', [])
82         self.set_identifier = kwargs.get('SetIdentifier')
83         self.weight = kwargs.get('Weight')
84         self.region = kwargs.get('Region')
85         self.health_check = kwargs.get('HealthCheckId')
86         self.hosted_zone_name = kwargs.get('HostedZoneName')
87         self.hosted_zone_id = kwargs.get('HostedZoneId')
88 
89     @classmethod
90     def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
91         properties = cloudformation_json['Properties']
92 
93         zone_name = properties.get("HostedZoneName")
94         if zone_name:
95             hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)
96         else:
97             hosted_zone = route53_backend.get_hosted_zone(
98                 properties["HostedZoneId"])
99         record_set = hosted_zone.add_rrset(properties)
100         return record_set
101 
102     @classmethod
103     def update_from_cloudformation_json(cls, original_resource, new_resource_name, cloudformation_json, region_name):
104         cls.delete_from_cloudformation_json(
105             original_resource.name, cloudformation_json, region_name)
106         return cls.create_from_cloudformation_json(new_resource_name, cloudformation_json, region_name)
107 
108     @classmethod
109     def delete_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
110         # this will break if you changed the zone the record is in,
111         # unfortunately
112         properties = cloudformation_json['Properties']
113 
114         zone_name = properties.get("HostedZoneName")
115         if zone_name:
116             hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)
117         else:
118             hosted_zone = route53_backend.get_hosted_zone(
119                 properties["HostedZoneId"])
120 
121         try:
122             hosted_zone.delete_rrset_by_name(resource_name)
123         except KeyError:
124             pass
125 
126     @property
127     def physical_resource_id(self):
128         return self.name
129 
130     def to_xml(self):
131         template = Template("""<ResourceRecordSet>
132                 <Name>{{ record_set.name }}</Name>
133                 <Type>{{ record_set._type }}</Type>
134                 {% if record_set.set_identifier %}
135                     <SetIdentifier>{{ record_set.set_identifier }}</SetIdentifier>
136                 {% endif %}
137                 {% if record_set.weight %}
138                     <Weight>{{ record_set.weight }}</Weight>
139                 {% endif %}
140                 {% if record_set.region %}
141                     <Region>{{ record_set.region }}</Region>
142                 {% endif %}
143                 <TTL>{{ record_set.ttl }}</TTL>
144                 <ResourceRecords>
145                     {% for record in record_set.records %}
146                     <ResourceRecord>
147                         <Value>{{ record }}</Value>
148                     </ResourceRecord>
149                     {% endfor %}
150                 </ResourceRecords>
151                 {% if record_set.health_check %}
152                     <HealthCheckId>{{ record_set.health_check }}</HealthCheckId>
153                 {% endif %}
154             </ResourceRecordSet>""")
155         return template.render(record_set=self)
156 
157     def delete(self, *args, **kwargs):
158         ''' Not exposed as part of the Route 53 API - used for CloudFormation. args are ignored '''
159         hosted_zone = route53_backend.get_hosted_zone_by_name(
160             self.hosted_zone_name)
161         if not hosted_zone:
162             hosted_zone = route53_backend.get_hosted_zone(self.hosted_zone_id)
163         hosted_zone.delete_rrset_by_name(self.name)
164 
165 
166 class FakeZone(BaseModel):
167 
168     def __init__(self, name, id_, private_zone, comment=None):
169         self.name = name
170         self.id = id_
171         if comment is not None:
172             self.comment = comment
173         self.private_zone = private_zone
174         self.rrsets = []
175 
176     def add_rrset(self, record_set):
177         record_set = RecordSet(record_set)
178         self.rrsets.append(record_set)
179         return record_set
180 
181     def upsert_rrset(self, record_set):
182         new_rrset = RecordSet(record_set)
183         for i, rrset in enumerate(self.rrsets):
184             if rrset.name == new_rrset.name:
185                 self.rrsets[i] = new_rrset
186                 break
187         else:
188             self.rrsets.append(new_rrset)
189         return new_rrset
190 
191     def delete_rrset_by_name(self, name):
192         self.rrsets = [
193             record_set for record_set in self.rrsets if record_set.name != name]
194 
195     def delete_rrset_by_id(self, set_identifier):
196         self.rrsets = [
197             record_set for record_set in self.rrsets if record_set.set_identifier != set_identifier]
198 
199     def get_record_sets(self, type_filter, name_filter):
200         record_sets = list(self.rrsets)  # Copy the list
201         if type_filter:
202             record_sets = [
203                 record_set for record_set in record_sets if record_set._type == type_filter]
204         if name_filter:
205             record_sets = [
206                 record_set for record_set in record_sets if record_set.name == name_filter]
207 
208         return record_sets
209 
210     @property
211     def physical_resource_id(self):
212         return self.name
213 
214     @classmethod
215     def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
216         properties = cloudformation_json['Properties']
217         name = properties["Name"]
218 
219         hosted_zone = route53_backend.create_hosted_zone(
220             name, private_zone=False)
221         return hosted_zone
222 
223 
224 class RecordSetGroup(BaseModel):
225 
226     def __init__(self, hosted_zone_id, record_sets):
227         self.hosted_zone_id = hosted_zone_id
228         self.record_sets = record_sets
229 
230     @property
231     def physical_resource_id(self):
232         return "arn:aws:route53:::hostedzone/{0}".format(self.hosted_zone_id)
233 
234     @classmethod
235     def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
236         properties = cloudformation_json['Properties']
237 
238         zone_name = properties.get("HostedZoneName")
239         if zone_name:
240             hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)
241         else:
242             hosted_zone = route53_backend.get_hosted_zone(properties["HostedZoneId"])
243         record_sets = properties["RecordSets"]
244         for record_set in record_sets:
245             hosted_zone.add_rrset(record_set)
246 
247         record_set_group = RecordSetGroup(hosted_zone.id, record_sets)
248         return record_set_group
249 
250 
251 class Route53Backend(BaseBackend):
252 
253     def __init__(self):
254         self.zones = {}
255         self.health_checks = {}
256         self.resource_tags = defaultdict(dict)
257 
258     def create_hosted_zone(self, name, private_zone, comment=None):
259         new_id = create_route53_zone_id()
260         new_zone = FakeZone(
261             name, new_id, private_zone=private_zone, comment=comment)
262         self.zones[new_id] = new_zone
263         return new_zone
264 
265     def change_tags_for_resource(self, resource_id, tags):
266         if 'Tag' in tags:
267             if isinstance(tags['Tag'], list):
268                 for tag in tags['Tag']:
269                     self.resource_tags[resource_id][tag['Key']] = tag['Value']
270             else:
271                 key, value = (tags['Tag']['Key'], tags['Tag']['Value'])
272                 self.resource_tags[resource_id][key] = value
273         else:
274             if 'Key' in tags:
275                 if isinstance(tags['Key'], list):
276                     for key in tags['Key']:
277                         del(self.resource_tags[resource_id][key])
278                 else:
279                     del(self.resource_tags[resource_id][tags['Key']])
280 
281     def list_tags_for_resource(self, resource_id):
282         if resource_id in self.resource_tags:
283             return self.resource_tags[resource_id]
284 
285     def get_all_hosted_zones(self):
286         return self.zones.values()
287 
288     def get_hosted_zone(self, id_):
289         return self.zones.get(id_.replace("/hostedzone/", ""))
290 
291     def get_hosted_zone_by_name(self, name):
292         for zone in self.get_all_hosted_zones():
293             if zone.name == name:
294                 return zone
295 
296     def delete_hosted_zone(self, id_):
297         return self.zones.pop(id_.replace("/hostedzone/", ""), None)
298 
299     def create_health_check(self, health_check_args):
300         health_check_id = str(uuid.uuid4())
301         health_check = HealthCheck(health_check_id, health_check_args)
302         self.health_checks[health_check_id] = health_check
303         return health_check
304 
305     def get_health_checks(self):
306         return self.health_checks.values()
307 
308     def delete_health_check(self, health_check_id):
309         return self.health_checks.pop(health_check_id, None)
310 
311 
312 route53_backend = Route53Backend()
313
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/moto/route53/models.py b/moto/route53/models.py
--- a/moto/route53/models.py
+++ b/moto/route53/models.py
@@ -209,7 +209,7 @@
 
     @property
     def physical_resource_id(self):
-        return self.name
+        return self.id
 
     @classmethod
     def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):

{"golden_diff": "diff --git a/moto/route53/models.py b/moto/route53/models.py\n--- a/moto/route53/models.py\n+++ b/moto/route53/models.py\n@@ -209,7 +209,7 @@\n \n     @property\n     def physical_resource_id(self):\n-        return self.name\n+        return self.id\n \n     @classmethod\n     def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n", "issue": "Resources in mentioned in cloud formation template is not getting created.\nHi,\r\nI am creating security group through cloud formation template and then trying to retrieve that through boto client but it says that security group does not exists. If i create security group through command line then i am able to fetch it.\r\nIt seems like resources in cloud formation does not get created when we deploy it.\r\n\n", "before_files": [{"content": "from __future__ import unicode_literals\n\nfrom collections import defaultdict\n\nimport string\nimport random\nimport uuid\nfrom jinja2 import Template\n\nfrom moto.core import BaseBackend, BaseModel\n\n\nROUTE53_ID_CHOICE = string.ascii_uppercase + string.digits\n\n\ndef create_route53_zone_id():\n    # New ID's look like this Z1RWWTK7Y8UDDQ\n    return ''.join([random.choice(ROUTE53_ID_CHOICE) for _ in range(0, 15)])\n\n\nclass HealthCheck(BaseModel):\n\n    def __init__(self, health_check_id, health_check_args):\n        self.id = health_check_id\n        self.ip_address = health_check_args.get(\"ip_address\")\n        self.port = health_check_args.get(\"port\", 80)\n        self._type = health_check_args.get(\"type\")\n        self.resource_path = health_check_args.get(\"resource_path\")\n        self.fqdn = health_check_args.get(\"fqdn\")\n        self.search_string = health_check_args.get(\"search_string\")\n        self.request_interval = health_check_args.get(\"request_interval\", 30)\n        self.failure_threshold = health_check_args.get(\"failure_threshold\", 3)\n\n    @property\n    def physical_resource_id(self):\n        return self.id\n\n    @classmethod\n    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        properties = cloudformation_json['Properties']['HealthCheckConfig']\n        health_check_args = {\n            \"ip_address\": properties.get('IPAddress'),\n            \"port\": properties.get('Port'),\n            \"type\": properties['Type'],\n            \"resource_path\": properties.get('ResourcePath'),\n            \"fqdn\": properties.get('FullyQualifiedDomainName'),\n            \"search_string\": properties.get('SearchString'),\n            \"request_interval\": properties.get('RequestInterval'),\n            \"failure_threshold\": properties.get('FailureThreshold'),\n        }\n        health_check = route53_backend.create_health_check(health_check_args)\n        return health_check\n\n    def to_xml(self):\n        template = Template(\"\"\"<HealthCheck>\n            <Id>{{ health_check.id }}</Id>\n            <CallerReference>example.com 192.0.2.17</CallerReference>\n            <HealthCheckConfig>\n                <IPAddress>{{ health_check.ip_address }}</IPAddress>\n                <Port>{{ health_check.port }}</Port>\n                <Type>{{ health_check._type }}</Type>\n                <ResourcePath>{{ health_check.resource_path }}</ResourcePath>\n                <FullyQualifiedDomainName>{{ health_check.fqdn }}</FullyQualifiedDomainName>\n                <RequestInterval>{{ health_check.request_interval }}</RequestInterval>\n                <FailureThreshold>{{ health_check.failure_threshold }}</FailureThreshold>\n                {% if health_check.search_string %}\n                    <SearchString>{{ health_check.search_string }}</SearchString>\n                {% endif %}\n            </HealthCheckConfig>\n            <HealthCheckVersion>1</HealthCheckVersion>\n        </HealthCheck>\"\"\")\n        return template.render(health_check=self)\n\n\nclass RecordSet(BaseModel):\n\n    def __init__(self, kwargs):\n        self.name = kwargs.get('Name')\n        self._type = kwargs.get('Type')\n        self.ttl = kwargs.get('TTL')\n        self.records = kwargs.get('ResourceRecords', [])\n        self.set_identifier = kwargs.get('SetIdentifier')\n        self.weight = kwargs.get('Weight')\n        self.region = kwargs.get('Region')\n        self.health_check = kwargs.get('HealthCheckId')\n        self.hosted_zone_name = kwargs.get('HostedZoneName')\n        self.hosted_zone_id = kwargs.get('HostedZoneId')\n\n    @classmethod\n    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        properties = cloudformation_json['Properties']\n\n        zone_name = properties.get(\"HostedZoneName\")\n        if zone_name:\n            hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)\n        else:\n            hosted_zone = route53_backend.get_hosted_zone(\n                properties[\"HostedZoneId\"])\n        record_set = hosted_zone.add_rrset(properties)\n        return record_set\n\n    @classmethod\n    def update_from_cloudformation_json(cls, original_resource, new_resource_name, cloudformation_json, region_name):\n        cls.delete_from_cloudformation_json(\n            original_resource.name, cloudformation_json, region_name)\n        return cls.create_from_cloudformation_json(new_resource_name, cloudformation_json, region_name)\n\n    @classmethod\n    def delete_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        # this will break if you changed the zone the record is in,\n        # unfortunately\n        properties = cloudformation_json['Properties']\n\n        zone_name = properties.get(\"HostedZoneName\")\n        if zone_name:\n            hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)\n        else:\n            hosted_zone = route53_backend.get_hosted_zone(\n                properties[\"HostedZoneId\"])\n\n        try:\n            hosted_zone.delete_rrset_by_name(resource_name)\n        except KeyError:\n            pass\n\n    @property\n    def physical_resource_id(self):\n        return self.name\n\n    def to_xml(self):\n        template = Template(\"\"\"<ResourceRecordSet>\n                <Name>{{ record_set.name }}</Name>\n                <Type>{{ record_set._type }}</Type>\n                {% if record_set.set_identifier %}\n                    <SetIdentifier>{{ record_set.set_identifier }}</SetIdentifier>\n                {% endif %}\n                {% if record_set.weight %}\n                    <Weight>{{ record_set.weight }}</Weight>\n                {% endif %}\n                {% if record_set.region %}\n                    <Region>{{ record_set.region }}</Region>\n                {% endif %}\n                <TTL>{{ record_set.ttl }}</TTL>\n                <ResourceRecords>\n                    {% for record in record_set.records %}\n                    <ResourceRecord>\n                        <Value>{{ record }}</Value>\n                    </ResourceRecord>\n                    {% endfor %}\n                </ResourceRecords>\n                {% if record_set.health_check %}\n                    <HealthCheckId>{{ record_set.health_check }}</HealthCheckId>\n                {% endif %}\n            </ResourceRecordSet>\"\"\")\n        return template.render(record_set=self)\n\n    def delete(self, *args, **kwargs):\n        ''' Not exposed as part of the Route 53 API - used for CloudFormation. args are ignored '''\n        hosted_zone = route53_backend.get_hosted_zone_by_name(\n            self.hosted_zone_name)\n        if not hosted_zone:\n            hosted_zone = route53_backend.get_hosted_zone(self.hosted_zone_id)\n        hosted_zone.delete_rrset_by_name(self.name)\n\n\nclass FakeZone(BaseModel):\n\n    def __init__(self, name, id_, private_zone, comment=None):\n        self.name = name\n        self.id = id_\n        if comment is not None:\n            self.comment = comment\n        self.private_zone = private_zone\n        self.rrsets = []\n\n    def add_rrset(self, record_set):\n        record_set = RecordSet(record_set)\n        self.rrsets.append(record_set)\n        return record_set\n\n    def upsert_rrset(self, record_set):\n        new_rrset = RecordSet(record_set)\n        for i, rrset in enumerate(self.rrsets):\n            if rrset.name == new_rrset.name:\n                self.rrsets[i] = new_rrset\n                break\n        else:\n            self.rrsets.append(new_rrset)\n        return new_rrset\n\n    def delete_rrset_by_name(self, name):\n        self.rrsets = [\n            record_set for record_set in self.rrsets if record_set.name != name]\n\n    def delete_rrset_by_id(self, set_identifier):\n        self.rrsets = [\n            record_set for record_set in self.rrsets if record_set.set_identifier != set_identifier]\n\n    def get_record_sets(self, type_filter, name_filter):\n        record_sets = list(self.rrsets)  # Copy the list\n        if type_filter:\n            record_sets = [\n                record_set for record_set in record_sets if record_set._type == type_filter]\n        if name_filter:\n            record_sets = [\n                record_set for record_set in record_sets if record_set.name == name_filter]\n\n        return record_sets\n\n    @property\n    def physical_resource_id(self):\n        return self.name\n\n    @classmethod\n    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        properties = cloudformation_json['Properties']\n        name = properties[\"Name\"]\n\n        hosted_zone = route53_backend.create_hosted_zone(\n            name, private_zone=False)\n        return hosted_zone\n\n\nclass RecordSetGroup(BaseModel):\n\n    def __init__(self, hosted_zone_id, record_sets):\n        self.hosted_zone_id = hosted_zone_id\n        self.record_sets = record_sets\n\n    @property\n    def physical_resource_id(self):\n        return \"arn:aws:route53:::hostedzone/{0}\".format(self.hosted_zone_id)\n\n    @classmethod\n    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        properties = cloudformation_json['Properties']\n\n        zone_name = properties.get(\"HostedZoneName\")\n        if zone_name:\n            hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)\n        else:\n            hosted_zone = route53_backend.get_hosted_zone(properties[\"HostedZoneId\"])\n        record_sets = properties[\"RecordSets\"]\n        for record_set in record_sets:\n            hosted_zone.add_rrset(record_set)\n\n        record_set_group = RecordSetGroup(hosted_zone.id, record_sets)\n        return record_set_group\n\n\nclass Route53Backend(BaseBackend):\n\n    def __init__(self):\n        self.zones = {}\n        self.health_checks = {}\n        self.resource_tags = defaultdict(dict)\n\n    def create_hosted_zone(self, name, private_zone, comment=None):\n        new_id = create_route53_zone_id()\n        new_zone = FakeZone(\n            name, new_id, private_zone=private_zone, comment=comment)\n        self.zones[new_id] = new_zone\n        return new_zone\n\n    def change_tags_for_resource(self, resource_id, tags):\n        if 'Tag' in tags:\n            if isinstance(tags['Tag'], list):\n                for tag in tags['Tag']:\n                    self.resource_tags[resource_id][tag['Key']] = tag['Value']\n            else:\n                key, value = (tags['Tag']['Key'], tags['Tag']['Value'])\n                self.resource_tags[resource_id][key] = value\n        else:\n            if 'Key' in tags:\n                if isinstance(tags['Key'], list):\n                    for key in tags['Key']:\n                        del(self.resource_tags[resource_id][key])\n                else:\n                    del(self.resource_tags[resource_id][tags['Key']])\n\n    def list_tags_for_resource(self, resource_id):\n        if resource_id in self.resource_tags:\n            return self.resource_tags[resource_id]\n\n    def get_all_hosted_zones(self):\n        return self.zones.values()\n\n    def get_hosted_zone(self, id_):\n        return self.zones.get(id_.replace(\"/hostedzone/\", \"\"))\n\n    def get_hosted_zone_by_name(self, name):\n        for zone in self.get_all_hosted_zones():\n            if zone.name == name:\n                return zone\n\n    def delete_hosted_zone(self, id_):\n        return self.zones.pop(id_.replace(\"/hostedzone/\", \"\"), None)\n\n    def create_health_check(self, health_check_args):\n        health_check_id = str(uuid.uuid4())\n        health_check = HealthCheck(health_check_id, health_check_args)\n        self.health_checks[health_check_id] = health_check\n        return health_check\n\n    def get_health_checks(self):\n        return self.health_checks.values()\n\n    def delete_health_check(self, health_check_id):\n        return self.health_checks.pop(health_check_id, None)\n\n\nroute53_backend = Route53Backend()\n", "path": "moto/route53/models.py"}], "after_files": [{"content": "from __future__ import unicode_literals\n\nfrom collections import defaultdict\n\nimport string\nimport random\nimport uuid\nfrom jinja2 import Template\n\nfrom moto.core import BaseBackend, BaseModel\n\n\nROUTE53_ID_CHOICE = string.ascii_uppercase + string.digits\n\n\ndef create_route53_zone_id():\n    # New ID's look like this Z1RWWTK7Y8UDDQ\n    return ''.join([random.choice(ROUTE53_ID_CHOICE) for _ in range(0, 15)])\n\n\nclass HealthCheck(BaseModel):\n\n    def __init__(self, health_check_id, health_check_args):\n        self.id = health_check_id\n        self.ip_address = health_check_args.get(\"ip_address\")\n        self.port = health_check_args.get(\"port\", 80)\n        self._type = health_check_args.get(\"type\")\n        self.resource_path = health_check_args.get(\"resource_path\")\n        self.fqdn = health_check_args.get(\"fqdn\")\n        self.search_string = health_check_args.get(\"search_string\")\n        self.request_interval = health_check_args.get(\"request_interval\", 30)\n        self.failure_threshold = health_check_args.get(\"failure_threshold\", 3)\n\n    @property\n    def physical_resource_id(self):\n        return self.id\n\n    @classmethod\n    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        properties = cloudformation_json['Properties']['HealthCheckConfig']\n        health_check_args = {\n            \"ip_address\": properties.get('IPAddress'),\n            \"port\": properties.get('Port'),\n            \"type\": properties['Type'],\n            \"resource_path\": properties.get('ResourcePath'),\n            \"fqdn\": properties.get('FullyQualifiedDomainName'),\n            \"search_string\": properties.get('SearchString'),\n            \"request_interval\": properties.get('RequestInterval'),\n            \"failure_threshold\": properties.get('FailureThreshold'),\n        }\n        health_check = route53_backend.create_health_check(health_check_args)\n        return health_check\n\n    def to_xml(self):\n        template = Template(\"\"\"<HealthCheck>\n            <Id>{{ health_check.id }}</Id>\n            <CallerReference>example.com 192.0.2.17</CallerReference>\n            <HealthCheckConfig>\n                <IPAddress>{{ health_check.ip_address }}</IPAddress>\n                <Port>{{ health_check.port }}</Port>\n                <Type>{{ health_check._type }}</Type>\n                <ResourcePath>{{ health_check.resource_path }}</ResourcePath>\n                <FullyQualifiedDomainName>{{ health_check.fqdn }}</FullyQualifiedDomainName>\n                <RequestInterval>{{ health_check.request_interval }}</RequestInterval>\n                <FailureThreshold>{{ health_check.failure_threshold }}</FailureThreshold>\n                {% if health_check.search_string %}\n                    <SearchString>{{ health_check.search_string }}</SearchString>\n                {% endif %}\n            </HealthCheckConfig>\n            <HealthCheckVersion>1</HealthCheckVersion>\n        </HealthCheck>\"\"\")\n        return template.render(health_check=self)\n\n\nclass RecordSet(BaseModel):\n\n    def __init__(self, kwargs):\n        self.name = kwargs.get('Name')\n        self._type = kwargs.get('Type')\n        self.ttl = kwargs.get('TTL')\n        self.records = kwargs.get('ResourceRecords', [])\n        self.set_identifier = kwargs.get('SetIdentifier')\n        self.weight = kwargs.get('Weight')\n        self.region = kwargs.get('Region')\n        self.health_check = kwargs.get('HealthCheckId')\n        self.hosted_zone_name = kwargs.get('HostedZoneName')\n        self.hosted_zone_id = kwargs.get('HostedZoneId')\n\n    @classmethod\n    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        properties = cloudformation_json['Properties']\n\n        zone_name = properties.get(\"HostedZoneName\")\n        if zone_name:\n            hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)\n        else:\n            hosted_zone = route53_backend.get_hosted_zone(\n                properties[\"HostedZoneId\"])\n        record_set = hosted_zone.add_rrset(properties)\n        return record_set\n\n    @classmethod\n    def update_from_cloudformation_json(cls, original_resource, new_resource_name, cloudformation_json, region_name):\n        cls.delete_from_cloudformation_json(\n            original_resource.name, cloudformation_json, region_name)\n        return cls.create_from_cloudformation_json(new_resource_name, cloudformation_json, region_name)\n\n    @classmethod\n    def delete_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        # this will break if you changed the zone the record is in,\n        # unfortunately\n        properties = cloudformation_json['Properties']\n\n        zone_name = properties.get(\"HostedZoneName\")\n        if zone_name:\n            hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)\n        else:\n            hosted_zone = route53_backend.get_hosted_zone(\n                properties[\"HostedZoneId\"])\n\n        try:\n            hosted_zone.delete_rrset_by_name(resource_name)\n        except KeyError:\n            pass\n\n    @property\n    def physical_resource_id(self):\n        return self.name\n\n    def to_xml(self):\n        template = Template(\"\"\"<ResourceRecordSet>\n                <Name>{{ record_set.name }}</Name>\n                <Type>{{ record_set._type }}</Type>\n                {% if record_set.set_identifier %}\n                    <SetIdentifier>{{ record_set.set_identifier }}</SetIdentifier>\n                {% endif %}\n                {% if record_set.weight %}\n                    <Weight>{{ record_set.weight }}</Weight>\n                {% endif %}\n                {% if record_set.region %}\n                    <Region>{{ record_set.region }}</Region>\n                {% endif %}\n                <TTL>{{ record_set.ttl }}</TTL>\n                <ResourceRecords>\n                    {% for record in record_set.records %}\n                    <ResourceRecord>\n                        <Value>{{ record }}</Value>\n                    </ResourceRecord>\n                    {% endfor %}\n                </ResourceRecords>\n                {% if record_set.health_check %}\n                    <HealthCheckId>{{ record_set.health_check }}</HealthCheckId>\n                {% endif %}\n            </ResourceRecordSet>\"\"\")\n        return template.render(record_set=self)\n\n    def delete(self, *args, **kwargs):\n        ''' Not exposed as part of the Route 53 API - used for CloudFormation. args are ignored '''\n        hosted_zone = route53_backend.get_hosted_zone_by_name(\n            self.hosted_zone_name)\n        if not hosted_zone:\n            hosted_zone = route53_backend.get_hosted_zone(self.hosted_zone_id)\n        hosted_zone.delete_rrset_by_name(self.name)\n\n\nclass FakeZone(BaseModel):\n\n    def __init__(self, name, id_, private_zone, comment=None):\n        self.name = name\n        self.id = id_\n        if comment is not None:\n            self.comment = comment\n        self.private_zone = private_zone\n        self.rrsets = []\n\n    def add_rrset(self, record_set):\n        record_set = RecordSet(record_set)\n        self.rrsets.append(record_set)\n        return record_set\n\n    def upsert_rrset(self, record_set):\n        new_rrset = RecordSet(record_set)\n        for i, rrset in enumerate(self.rrsets):\n            if rrset.name == new_rrset.name:\n                self.rrsets[i] = new_rrset\n                break\n        else:\n            self.rrsets.append(new_rrset)\n        return new_rrset\n\n    def delete_rrset_by_name(self, name):\n        self.rrsets = [\n            record_set for record_set in self.rrsets if record_set.name != name]\n\n    def delete_rrset_by_id(self, set_identifier):\n        self.rrsets = [\n            record_set for record_set in self.rrsets if record_set.set_identifier != set_identifier]\n\n    def get_record_sets(self, type_filter, name_filter):\n        record_sets = list(self.rrsets)  # Copy the list\n        if type_filter:\n            record_sets = [\n                record_set for record_set in record_sets if record_set._type == type_filter]\n        if name_filter:\n            record_sets = [\n                record_set for record_set in record_sets if record_set.name == name_filter]\n\n        return record_sets\n\n    @property\n    def physical_resource_id(self):\n        return self.id\n\n    @classmethod\n    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        properties = cloudformation_json['Properties']\n        name = properties[\"Name\"]\n\n        hosted_zone = route53_backend.create_hosted_zone(\n            name, private_zone=False)\n        return hosted_zone\n\n\nclass RecordSetGroup(BaseModel):\n\n    def __init__(self, hosted_zone_id, record_sets):\n        self.hosted_zone_id = hosted_zone_id\n        self.record_sets = record_sets\n\n    @property\n    def physical_resource_id(self):\n        return \"arn:aws:route53:::hostedzone/{0}\".format(self.hosted_zone_id)\n\n    @classmethod\n    def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):\n        properties = cloudformation_json['Properties']\n\n        zone_name = properties.get(\"HostedZoneName\")\n        if zone_name:\n            hosted_zone = route53_backend.get_hosted_zone_by_name(zone_name)\n        else:\n            hosted_zone = route53_backend.get_hosted_zone(properties[\"HostedZoneId\"])\n        record_sets = properties[\"RecordSets\"]\n        for record_set in record_sets:\n            hosted_zone.add_rrset(record_set)\n\n        record_set_group = RecordSetGroup(hosted_zone.id, record_sets)\n        return record_set_group\n\n\nclass Route53Backend(BaseBackend):\n\n    def __init__(self):\n        self.zones = {}\n        self.health_checks = {}\n        self.resource_tags = defaultdict(dict)\n\n    def create_hosted_zone(self, name, private_zone, comment=None):\n        new_id = create_route53_zone_id()\n        new_zone = FakeZone(\n            name, new_id, private_zone=private_zone, comment=comment)\n        self.zones[new_id] = new_zone\n        return new_zone\n\n    def change_tags_for_resource(self, resource_id, tags):\n        if 'Tag' in tags:\n            if isinstance(tags['Tag'], list):\n                for tag in tags['Tag']:\n                    self.resource_tags[resource_id][tag['Key']] = tag['Value']\n            else:\n                key, value = (tags['Tag']['Key'], tags['Tag']['Value'])\n                self.resource_tags[resource_id][key] = value\n        else:\n            if 'Key' in tags:\n                if isinstance(tags['Key'], list):\n                    for key in tags['Key']:\n                        del(self.resource_tags[resource_id][key])\n                else:\n                    del(self.resource_tags[resource_id][tags['Key']])\n\n    def list_tags_for_resource(self, resource_id):\n        if resource_id in self.resource_tags:\n            return self.resource_tags[resource_id]\n\n    def get_all_hosted_zones(self):\n        return self.zones.values()\n\n    def get_hosted_zone(self, id_):\n        return self.zones.get(id_.replace(\"/hostedzone/\", \"\"))\n\n    def get_hosted_zone_by_name(self, name):\n        for zone in self.get_all_hosted_zones():\n            if zone.name == name:\n                return zone\n\n    def delete_hosted_zone(self, id_):\n        return self.zones.pop(id_.replace(\"/hostedzone/\", \"\"), None)\n\n    def create_health_check(self, health_check_args):\n        health_check_id = str(uuid.uuid4())\n        health_check = HealthCheck(health_check_id, health_check_args)\n        self.health_checks[health_check_id] = health_check\n        return health_check\n\n    def get_health_checks(self):\n        return self.health_checks.values()\n\n    def delete_health_check(self, health_check_id):\n        return self.health_checks.pop(health_check_id, None)\n\n\nroute53_backend = Route53Backend()\n", "path": "moto/route53/models.py"}]}