From 224e20ca605db1fb84e691f00871926f24cf80b7 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Thu, 25 Apr 2013 21:10:54 -0400 Subject: [PATCH] complex_arg templating should be smarter. Make it so! --- lib/ansible/runner/__init__.py | 24 +++++++++++++++--------- lib/ansible/utils/template.py | 11 +++++++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 146fec3502e..c38356474a1 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -239,9 +239,8 @@ class Runner(object): if not self.environment: return "" - enviro = template.template(self.basedir, self.environment, inject) - if isinstance(enviro, basestring) and enviro in inject: - enviro = inject[enviro] + enviro = template.template(self.basedir, self.environment, inject, convert_bare=True) + enviro = utils.safe_eval(enviro) if type(enviro) != dict: raise errors.AnsibleError("environment must be a dictionary, received %s" % enviro) result = "" @@ -406,15 +405,14 @@ class Runner(object): # logic to replace complex args if possible complex_args = self.complex_args - if isinstance(complex_args, basestring): - if complex_args in inject: - complex_args = inject[complex_args] - else: - complex_args = template.template(self.basedir, complex_args, inject) - complex_args = utils.safe_eval(complex_args) # logic to decide how to run things depends on whether with_items is used if items is None: + if isinstance(complex_args, basestring): + complex_args = template.template(self.basedir, complex_args, inject, convert_bare=True) + complex_args = utils.safe_eval(complex_args) + if type(complex_args) != dict: + raise errors.AnsibleError("args must be a dictionary, received %s" % complex_args) return self._executor_internal_inner(host, self.module_name, self.module_args, inject, port, complex_args=complex_args) elif len(items) > 0: @@ -428,6 +426,14 @@ class Runner(object): results = [] for x in items: inject['item'] = x + + # TODO: this idiom should be replaced with an up-conversion to a Jinja2 template evaluation + if isinstance(complex_args, basestring): + complex_args = template.template(self.basedir, complex_args, inject, convert_bare=True) + complex_args = utils.safe_eval(complex_args) + if type(complex_args) != dict: + raise errors.AnsibleError("args must be a dictionary, received %s" % complex_args) + result = self._executor_internal_inner( host, self.module_name, diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py index fc5582d535f..88837cc08ea 100644 --- a/lib/ansible/utils/template.py +++ b/lib/ansible/utils/template.py @@ -266,9 +266,16 @@ def legacy_varReplace(basedir, raw, vars, lookup_fatal=True, depth=0, expand_lis return ''.join(done) -def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=True): +# TODO: varname is misnamed here + +def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=True, convert_bare=False): ''' templates a data structure by traversing it and substituting for other data structures ''' + if convert_bare and isinstance(varname, basestring): + first_part = varname.split(".")[0].split("[")[0] + if first_part in vars and '{{' not in varname and '$' not in varname: + varname = "{{%s}}" % varname + if isinstance(varname, basestring): if '{{' in varname or '{%' in varname: varname = template_from_string(basedir, varname, vars) @@ -439,7 +446,7 @@ def template_from_file(basedir, path, vars): def template_from_string(basedir, data, vars): ''' run a file through the (Jinja2) templating engine ''' - + try: if type(data) == str: data = unicode(data, 'utf-8')