Merge pull request #346 from jhoekx/improve-varreplace
Support nested variables in varReplace
This commit is contained in:
commit
cb6f0f4284
3 changed files with 173 additions and 5 deletions
|
@ -545,7 +545,7 @@ class Runner(object):
|
||||||
source_data = codecs.open(utils.path_dwim(self.basedir, source), encoding="utf8").read()
|
source_data = codecs.open(utils.path_dwim(self.basedir, source), encoding="utf8").read()
|
||||||
resultant = ''
|
resultant = ''
|
||||||
try:
|
try:
|
||||||
resultant = utils.template(source_data, inject, self.setup_cache)
|
resultant = utils.template(source_data, inject, self.setup_cache, no_engine=False)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
return (host, False, dict(failed=True, msg=str(e)), '')
|
return (host, False, dict(failed=True, msg=str(e)), '')
|
||||||
xfered = self._transfer_str(conn, tmp, 'source', resultant)
|
xfered = self._transfer_str(conn, tmp, 'source', resultant)
|
||||||
|
|
|
@ -199,7 +199,19 @@ def parse_json(data):
|
||||||
return { "failed" : True, "parsed" : False, "msg" : data }
|
return { "failed" : True, "parsed" : False, "msg" : data }
|
||||||
return results
|
return results
|
||||||
|
|
||||||
_KEYCRE = re.compile(r"\$(\w+)")
|
def varLookup(name, vars):
|
||||||
|
''' find the contents of a possibly complex variable in vars. '''
|
||||||
|
path = name.split('.')
|
||||||
|
space = vars
|
||||||
|
for part in path:
|
||||||
|
if part in space:
|
||||||
|
space = space[part]
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
return space
|
||||||
|
|
||||||
|
_KEYCRE = re.compile(r"\$(?P<complex>\{){0,1}((?(complex)[\w\.]+|\w+))(?(complex)\})")
|
||||||
|
# if { -> complex if complex, allow . and need trailing }
|
||||||
|
|
||||||
def varReplace(raw, vars):
|
def varReplace(raw, vars):
|
||||||
'''Perform variable replacement of $vars
|
'''Perform variable replacement of $vars
|
||||||
|
@ -221,8 +233,9 @@ def varReplace(raw, vars):
|
||||||
|
|
||||||
# Determine replacement value (if unknown variable then preserve
|
# Determine replacement value (if unknown variable then preserve
|
||||||
# original)
|
# original)
|
||||||
varname = m.group(1).lower()
|
varname = m.group(2).lower()
|
||||||
replacement = str(vars.get(varname, m.group()))
|
|
||||||
|
replacement = str(varLookup(varname, vars) or m.group())
|
||||||
|
|
||||||
start, end = m.span()
|
start, end = m.span()
|
||||||
done.append(raw[:start]) # Keep stuff leading up to token
|
done.append(raw[:start]) # Keep stuff leading up to token
|
||||||
|
@ -231,7 +244,7 @@ def varReplace(raw, vars):
|
||||||
|
|
||||||
return ''.join(done)
|
return ''.join(done)
|
||||||
|
|
||||||
def template(text, vars, setup_cache, no_engine=False):
|
def template(text, vars, setup_cache, no_engine=True):
|
||||||
''' run a text buffer through the templating engine '''
|
''' run a text buffer through the templating engine '''
|
||||||
vars = vars.copy()
|
vars = vars.copy()
|
||||||
text = varReplace(unicode(text), vars)
|
text = varReplace(unicode(text), vars)
|
||||||
|
|
155
test/TestUtils.py
Normal file
155
test/TestUtils.py
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import ansible.utils
|
||||||
|
|
||||||
|
class TestUtils(unittest.TestCase):
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
### varLookup function tests
|
||||||
|
|
||||||
|
def test_varLookup_list(self):
|
||||||
|
vars = {
|
||||||
|
'data': {
|
||||||
|
'who': ['joe', 'jack', 'jeff']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varLookup('data.who', vars)
|
||||||
|
|
||||||
|
assert sorted(res) == sorted(vars['data']['who'])
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
### varReplace function tests
|
||||||
|
|
||||||
|
def test_varReplace_simple(self):
|
||||||
|
template = 'hello $who'
|
||||||
|
vars = {
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == 'hello world'
|
||||||
|
|
||||||
|
def test_varReplace_multiple(self):
|
||||||
|
template = '$what $who'
|
||||||
|
vars = {
|
||||||
|
'what': 'hello',
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == 'hello world'
|
||||||
|
|
||||||
|
def test_varReplace_middle(self):
|
||||||
|
template = 'hello $who!'
|
||||||
|
vars = {
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == 'hello world!'
|
||||||
|
|
||||||
|
def test_varReplace_alternative(self):
|
||||||
|
template = 'hello ${who}'
|
||||||
|
vars = {
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == 'hello world'
|
||||||
|
|
||||||
|
def test_varReplace_almost_alternative(self):
|
||||||
|
template = 'hello $who}'
|
||||||
|
vars = {
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == 'hello world}'
|
||||||
|
|
||||||
|
def test_varReplace_almost_alternative2(self):
|
||||||
|
template = 'hello ${who'
|
||||||
|
vars = {
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == template
|
||||||
|
|
||||||
|
def test_varReplace_alternative_greed(self):
|
||||||
|
template = 'hello ${who} }'
|
||||||
|
vars = {
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == 'hello world }'
|
||||||
|
|
||||||
|
def test_varReplace_notcomplex(self):
|
||||||
|
template = 'hello $mydata.who'
|
||||||
|
vars = {
|
||||||
|
'data': {
|
||||||
|
'who': 'world',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
print res
|
||||||
|
assert res == template
|
||||||
|
|
||||||
|
def test_varReplace_nested(self):
|
||||||
|
template = 'hello ${data.who}'
|
||||||
|
vars = {
|
||||||
|
'data': {
|
||||||
|
'who': 'world'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == 'hello world'
|
||||||
|
|
||||||
|
def test_varReplace_nested_int(self):
|
||||||
|
template = '$what ${data.who}'
|
||||||
|
vars = {
|
||||||
|
'data': {
|
||||||
|
'who': 2
|
||||||
|
},
|
||||||
|
'what': 'hello',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.varReplace(template, vars)
|
||||||
|
|
||||||
|
assert res == 'hello 2'
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
### Template function tests
|
||||||
|
|
||||||
|
def test_template_basic(self):
|
||||||
|
template = 'hello {{ who }}'
|
||||||
|
vars = {
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.template(template, vars, {}, no_engine=False)
|
||||||
|
|
||||||
|
assert res == 'hello world'
|
||||||
|
|
||||||
|
def test_template_whitespace(self):
|
||||||
|
template = 'hello {{ who }}\n'
|
||||||
|
vars = {
|
||||||
|
'who': 'world',
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ansible.utils.template(template, vars, {}, no_engine=False)
|
||||||
|
|
||||||
|
assert res == 'hello world\n'
|
Loading…
Reference in a new issue