+class Cfn(object):
+
+ base_template = {
+ 'HeatTemplateFormatVersion': '2012-12-12',
+ 'Description': []
+ }
+ get_resource = 'Ref'
+ get_param = 'Ref'
+ description = 'Description'
+ parameters = 'Parameters'
+ outputs = 'Outputs'
+ resources = 'Resources'
+ type = 'Type'
+ properties = 'Properties'
+ metadata = 'Metadata'
+ depends_on = 'DependsOn'
+ get_attr = 'Fn::GetAtt'
+
+
+class Hot(object):
+
+ base_template = {
+ 'heat_template_version': '2013-05-23',
+ 'description': []
+ }
+ get_resource = 'get_resource'
+ get_param = 'get_param'
+ description = 'description'
+ parameters = 'parameters'
+ outputs = 'outputs'
+ resources = 'resources'
+ type = 'type'
+ properties = 'properties'
+ metadata = 'metadata'
+ depends_on = 'depends_on'
+ get_attr = 'get_attr'
+
+
+lang = Cfn()
+
+
+def apply_maps(template):
+ """Apply Merge::Map within template.
+
+ Any dict {'Merge::Map': {'Foo': 'Bar', 'Baz': 'Quux'}}
+ will resolve to ['Bar', 'Quux'] - that is a dict with key
+ 'Merge::Map' is replaced entirely by that dict['Merge::Map'].values().
+ """
+ if isinstance(template, dict):
+ if 'Merge::Map' in template:
+ return sorted(
+ apply_maps(value) for value in template['Merge::Map'].values()
+ )
+ else:
+ return dict((key, apply_maps(value))
+ for key, value in template.items())
+ elif isinstance(template, list):
+ return [apply_maps(item) for item in template]
+ else:
+ return template
+
+