From a79373f6b278f61c5c2fb8c46b84147d56d02c96 Mon Sep 17 00:00:00 2001 From: Daniel Hokka Zakrisson Date: Sat, 2 Feb 2013 12:29:28 +0100 Subject: [PATCH] Make template_ds the only templater Instead of having to remember when to use which one, rename template_ds to template and move the last bit of code from template to varReplace (which gets used for all string replacements, in the end). This means that you can template any data type without worrying about whether it's a string or not, and the right thing will happen. --- lib/ansible/playbook/__init__.py | 4 ++-- lib/ansible/playbook/play.py | 10 ++++------ lib/ansible/runner/__init__.py | 2 +- lib/ansible/utils/template.py | 27 ++++++++++----------------- test/TestUtils.py | 8 ++++---- 5 files changed, 21 insertions(+), 30 deletions(-) diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py index 2fa5fb48453..1131f7589a9 100644 --- a/lib/ansible/playbook/__init__.py +++ b/lib/ansible/playbook/__init__.py @@ -151,7 +151,7 @@ class PlayBook(object): plugin_name = k[5:] if plugin_name not in utils.plugins.lookup_loader: raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name)) - terms = utils.template_ds(basedir, play[k], vars) + terms = utils.template(basedir, play[k], vars) items = utils.plugins.lookup_loader.get(plugin_name, basedir=basedir, runner=None).run(terms, inject=vars) for item in items: @@ -165,7 +165,7 @@ class PlayBook(object): incvars.update(v) for t in tokens[1:]: (k,v) = t.split("=", 1) - incvars[k] = utils.template_ds(basedir, v, incvars) + incvars[k] = utils.template(basedir, v, incvars) included_path = utils.path_dwim(basedir, tokens[0]) (plays, basedirs) = self._load_playbook_from_file(included_path, incvars) for p in plays: diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py index e709c97e221..f02730d6d49 100644 --- a/lib/ansible/playbook/play.py +++ b/lib/ansible/playbook/play.py @@ -75,10 +75,8 @@ class Play(object): self.transport = ds.get('connection', self.playbook.transport) self.tags = ds.get('tags', None) self.gather_facts = ds.get('gather_facts', None) - self.serial = int(utils.template_ds(basedir, ds.get('serial', 0), self.vars)) - - if isinstance(self.remote_port, basestring): - self.remote_port = utils.template(basedir, self.remote_port, self.vars) + self.serial = int(utils.template(basedir, ds.get('serial', 0), self.vars)) + self.remote_port = utils.template(basedir, self.remote_port, self.vars) self._update_vars_files_for_host(None) @@ -117,7 +115,7 @@ class Play(object): plugin_name = k[5:] if plugin_name not in utils.plugins.lookup_loader: raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name)) - terms = utils.template_ds(self.basedir, x[k], task_vars) + terms = utils.template(self.basedir, x[k], task_vars) items = utils.plugins.lookup_loader.get(plugin_name, basedir=self.basedir, runner=None).run(terms, inject=task_vars) elif k.startswith("when_"): included_additional_conditions.append(utils.compile_when_to_only_if("%s %s" % (k[5:], x[k]))) @@ -136,7 +134,7 @@ class Play(object): mv['item'] = item for t in tokens[1:]: (k,v) = t.split("=", 1) - mv[k] = utils.template_ds(self.basedir, v, mv) + mv[k] = utils.template(self.basedir, v, mv) include_file = utils.template(self.basedir, tokens[0], mv) data = utils.parse_yaml_from_file(utils.path_dwim(self.basedir, include_file)) results += self._load_tasks(data, mv, included_additional_conditions) diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 6aa4e78ccc7..bd35c7557dc 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -277,7 +277,7 @@ class Runner(object): items_plugin = self.module_vars.get('items_lookup_plugin', None) if items_plugin is not None and items_plugin in utils.plugins.lookup_loader: items_terms = self.module_vars.get('items_lookup_terms', '') - items_terms = utils.template_ds(self.basedir, items_terms, inject) + items_terms = utils.template(self.basedir, items_terms, inject) items = utils.plugins.lookup_loader.get(items_plugin, runner=self, basedir=self.basedir).run(items_terms, inject=inject) if type(items) != list: raise errors.AnsibleError("lookup plugins have to return a list: %r" % items) diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py index e5db9e53dda..fce2861903c 100644 --- a/lib/ansible/utils/template.py +++ b/lib/ansible/utils/template.py @@ -66,7 +66,7 @@ def _varFindLimitSpace(basedir, vars, space, part, lookup_fatal, depth): # if space is a string, check if it's a reference to another variable if isinstance(space, basestring): - space = template_ds(basedir, space, vars, lookup_fatal, depth) + space = template(basedir, space, vars, lookup_fatal, depth) return space @@ -187,6 +187,9 @@ def varReplace(basedir, raw, vars, lookup_fatal=True, depth=0, expand_lists=Fals ''' Perform variable replacement of $variables in string raw using vars dictionary ''' # this code originally from yum + if not isinstance(raw, unicode): + raw = raw.decode("utf-8") + if (depth > 20): raise errors.AnsibleError("template recursion depth exceeded") @@ -216,7 +219,7 @@ def varReplace(basedir, raw, vars, lookup_fatal=True, depth=0, expand_lists=Fals return ''.join(done) -def template_ds(basedir, varname, vars, lookup_fatal=True, depth=0): +def template(basedir, varname, vars, lookup_fatal=True, expand_lists=True, depth=0): ''' templates a data structure by traversing it and substituting for other data structures ''' if isinstance(varname, basestring): @@ -225,31 +228,21 @@ def template_ds(basedir, varname, vars, lookup_fatal=True, depth=0): return varname if m['start'] == 0 and m['end'] == len(varname): if m['replacement'] is not None: - return template_ds(basedir, m['replacement'], vars, lookup_fatal, depth) + return template(basedir, m['replacement'], vars, lookup_fatal, expand_lists, depth) else: return varname else: - return template(basedir, varname, vars, lookup_fatal) + return varReplace(basedir, varname, vars, lookup_fatal, depth=depth, expand_lists=expand_lists) elif isinstance(varname, (list, tuple)): - return [template_ds(basedir, v, vars, lookup_fatal, depth) for v in varname] + return [template(basedir, v, vars, lookup_fatal, expand_lists, depth) for v in varname] elif isinstance(varname, dict): d = {} for (k, v) in varname.iteritems(): - d[k] = template_ds(basedir, v, vars, lookup_fatal, depth) + d[k] = template(basedir, v, vars, lookup_fatal, expand_lists, depth) return d else: return varname -def template(basedir, text, vars, lookup_fatal=True, expand_lists=False): - ''' run a text buffer through the templating engine until it no longer changes ''' - - try: - text = text.decode('utf-8') - except UnicodeEncodeError: - pass # already unicode - text = varReplace(basedir, unicode(text), vars, lookup_fatal=lookup_fatal, expand_lists=expand_lists) - return text - class _jinja2_vars(object): ''' Helper class to template all variable content before jinja2 sees it. @@ -288,7 +281,7 @@ class _jinja2_vars(object): if isinstance(var, dict) and type(var) != dict: return var else: - return template_ds(self.basedir, var, self.vars) + return template(self.basedir, var, self.vars) def add_locals(self, locals): ''' If locals are provided, create a copy of self containing those diff --git a/test/TestUtils.py b/test/TestUtils.py index 1b91aa07966..24a9569f38d 100644 --- a/test/TestUtils.py +++ b/test/TestUtils.py @@ -324,19 +324,19 @@ class TestUtils(unittest.TestCase): } template = '${data.var}' - res = ansible.utils.template_ds(None, template, vars) + res = ansible.utils.template(None, template, vars) assert sorted(res) == sorted(vars['data']['var']) template = '${data.types}' - res = ansible.utils.template_ds(None, template, vars) + res = ansible.utils.template(None, template, vars) assert sorted(res) == sorted(vars['data']['types']) template = '${data.alphas}' - res = ansible.utils.template_ds(None, template, vars) + res = ansible.utils.template(None, template, vars) assert sorted(res) == sorted(vars['alphas']) template = '${data.nonexisting}' - res = ansible.utils.template_ds(None, template, vars) + res = ansible.utils.template(None, template, vars) assert res == template #####################################