[functools.partial(template.resolve_param_refs,
parameters=parameters),
template.resolve_availability_zones,
- template.resolve_find_in_map])
+ template.resolve_find_in_map,
+ template.reduce_joins])
def resolve_runtime_data(template, resources, snippet):
return _resolve(lambda k, v: k == 'Fn::GetAtt', handle_getatt, s)
+ @staticmethod
+ def reduce_joins(s):
+ '''
+ Reduces contiguous strings in Fn::Join to a single joined string
+ eg the following
+ { "Fn::Join" : [ " ", [ "str1", "str2", {"f": "b"}, "str3", "str4"]}
+ is reduced to
+ { "Fn::Join" : [ " ", [ "str1 str2", {"f": "b"}, "str3 str4"]}
+ '''
+ def handle_join(args):
+ if not isinstance(args, (list, tuple)):
+ raise TypeError('Arguments to "Fn::Join" must be a list')
+ delim, items = args
+ if not isinstance(items, (list, tuple)):
+ raise TypeError('Arguments to "Fn::Join" not fully resolved')
+ reduced = []
+ contiguous = []
+ for item in items:
+ if isinstance(item, (str, unicode)):
+ contiguous.append(item)
+ else:
+ if contiguous:
+ reduced.append(delim.join(contiguous))
+ contiguous = []
+ reduced.append(item)
+ if contiguous:
+ reduced.append(delim.join(contiguous))
+ return {'Fn::Join': [delim, reduced]}
+
+ return _resolve(lambda k, v: k == 'Fn::Join', handle_join, s)
+
@staticmethod
def resolve_joins(s):
'''
from nose.plugins.attrib import attr
import mox
import json
+import sys
from heat.common import context
from heat.common import exception
def join(raw):
- def handle_join(args):
- delim, strs = args
- return delim.join(strs)
-
- return template._resolve(lambda k, v: k == 'Fn::Join', handle_join, raw)
+ return parser.Template.resolve_joins(raw)
@attr(tag=['unit', 'parser'])
resources),
p_snippet)
+ def test_join_reduce(self):
+ join = {"Fn::Join": [" ", ["foo", "bar", "baz", {'Ref': 'baz'},
+ "bink", "bonk"]]}
+ self.assertEqual(parser.Template.reduce_joins(join),
+ {"Fn::Join": [" ", ["foo bar baz", {'Ref': 'baz'},
+ "bink bonk"]]})
+
+ join = {"Fn::Join": [" ", ["foo", {'Ref': 'baz'},
+ "bink"]]}
+ self.assertEqual(parser.Template.reduce_joins(join),
+ {"Fn::Join": [" ", ["foo", {'Ref': 'baz'},
+ "bink"]]})
+
+ join = {"Fn::Join": [" ", [{'Ref': 'baz'}]]}
+ self.assertEqual(parser.Template.reduce_joins(join),
+ {"Fn::Join": [" ", [{'Ref': 'baz'}]]})
+
def test_join(self):
join = {"Fn::Join": [" ", ["foo", "bar"]]}
self.assertEqual(parser.Template.resolve_joins(join), "foo bar")