diff --git a/lib/ansible/utils.py b/lib/ansible/utils.py index 9518b3ae80..6c1e3be6a1 100644 --- a/lib/ansible/utils.py +++ b/lib/ansible/utils.py @@ -199,6 +199,8 @@ def parse_json(data): return { "failed" : True, "parsed" : False, "msg" : data } return results +_LISTRE = re.compile(r"(\w+)\[(\d+)\]") + def varLookup(name, vars): ''' find the contents of a possibly complex variable in vars. ''' path = name.split('.') @@ -206,11 +208,19 @@ def varLookup(name, vars): for part in path: if part in space: space = space[part] + elif "[" in part: + m = _LISTRE.search(part) + if not m: + return + try: + space = space[m.group(1)][int(m.group(2))] + except (KeyError, IndexError): + return else: return return space -_KEYCRE = re.compile(r"\$(?P\{){0,1}((?(complex)[\w\.]+|\w+))(?(complex)\})") +_KEYCRE = re.compile(r"\$(?P\{){0,1}((?(complex)[\w\.\[\]]+|\w+))(?(complex)\})") # if { -> complex if complex, allow . and need trailing } def varReplace(raw, vars): diff --git a/test/TestUtils.py b/test/TestUtils.py index 7f924da9b0..aeabdb0dbb 100644 --- a/test/TestUtils.py +++ b/test/TestUtils.py @@ -143,6 +143,56 @@ class TestUtils(unittest.TestCase): assert res == u'hello wórld' + def test_varReplace_list(self): + template = 'hello ${data[1]}' + vars = { + 'data': [ 'no-one', 'world' ] + } + + res = ansible.utils.varReplace(template, vars) + + assert res == 'hello world' + + def test_varReplace_invalid_list(self): + template = 'hello ${data[1}' + vars = { + 'data': [ 'no-one', 'world' ] + } + + res = ansible.utils.varReplace(template, vars) + + assert res == template + + def test_varReplace_list_oob(self): + template = 'hello ${data[2]}' + vars = { + 'data': [ 'no-one', 'world' ] + } + + res = ansible.utils.varReplace(template, vars) + + assert res == template + + def test_varReplace_list_nolist(self): + template = 'hello ${data[1]}' + vars = { + 'data': { 'no-one': 0, 'world': 1 } + } + + res = ansible.utils.varReplace(template, vars) + + assert res == template + + def test_varReplace_nested_list(self): + template = 'hello ${data[1].msg[0]}' + vars = { + 'data': [ 'no-one', {'msg': [ 'world'] } ] + } + + res = ansible.utils.varReplace(template, vars) + + assert res == 'hello world' + ##################################### ### Template function tests