import argparse
+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
+
+
def apply_scaling(template, scaling, in_copies=None):
"""Apply a set of scaling operations to template.
Values are handled via scale_value.
- Keys in dicts are always copied per the scaling rule.
+ Keys in dicts are copied per the scaling rule.
Values are either replaced or copied depending on whether the given
scaling rule is in in_copies.
+
+ in_copies is reset to None when a dict {'Merge::Map': someobject} is
+ encountered.
"""
in_copies = dict(in_copies or {})
# Shouldn't be needed but to avoid unexpected side effects/bugs we short
if not scaling:
return template
if isinstance(template, dict):
+ if 'Merge::Map' in template:
+ in_copies = None
new_template = {}
for key, value in template.items():
for prefix, copy_num, new_key in scale_value(
end_template['Resources'][r] = rbody
end_template = apply_scaling(end_template, scaling)
+ end_template = apply_maps(end_template)
def fix_ref(item, old, new):
if isinstance(item, dict):