diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py index e15a5aa0ce..6acc30ced6 100644 --- a/lib/ansible/playbook/play.py +++ b/lib/ansible/playbook/play.py @@ -56,6 +56,9 @@ class Play(object): self.vars_prompt = ds.get('vars_prompt', {}) self.playbook = playbook self.vars = self._get_vars() + self.vars_files = ds.get('vars_files', []) + self.basedir = basedir + self._update_vars_files_for_host(None) self._ds = ds = utils.template(basedir, ds, self.vars) hosts = ds.get('hosts') @@ -65,9 +68,7 @@ class Play(object): hosts = ';'.join(hosts) self.serial = int(ds.get('serial', 0)) - self.basedir = basedir self.hosts = hosts - self.vars_files = ds.get('vars_files', []) self.name = ds.get('name', self.hosts) self._tasks = ds.get('tasks', []) self._handlers = ds.get('handlers', []) @@ -83,7 +84,6 @@ class Play(object): self.any_errors_fatal = ds.get('any_errors_fatal', False) self.roles = ds.get('roles', None) - self._update_vars_files_for_host(None) load_vars = {} if self.playbook.inventory.basedir() is not None: diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 25b8982da9..f9a65c99ca 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -138,7 +138,6 @@ class Runner(object): self.inventory = utils.default(inventory, lambda: ansible.inventory.Inventory(host_list)) self.module_vars = utils.default(module_vars, lambda: {}) - self.sudo_user = sudo_user self.connector = connection.Connection(self) self.conditional = conditional self.module_name = module_name @@ -152,6 +151,7 @@ class Runner(object): self.private_key_file = private_key_file self.background = background self.sudo = sudo + self.sudo_user = sudo_user self.sudo_pass = sudo_pass self.is_playbook = is_playbook self.environment = environment @@ -175,7 +175,7 @@ class Runner(object): # ensure we are using unique tmp paths random.seed() - + # ***************************************************** def _complex_args_hack(self, complex_args, module_args): diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py index 91a915648d..61edb2940e 100644 --- a/lib/ansible/utils/template.py +++ b/lib/ansible/utils/template.py @@ -19,6 +19,7 @@ import os import re import codecs import jinja2 +import jinja2.meta as jinja2_meta import yaml import json from ansible import errors @@ -233,7 +234,8 @@ def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=Tr if isinstance(varname, basestring): if '{{' in varname or '{%' in varname: - return template_from_string(basedir, varname, vars) + res = template_from_string(basedir, varname, vars) + return res m = _varFind(basedir, varname, vars, lookup_fatal, depth, expand_lists) if not m: return varname @@ -409,11 +411,19 @@ def template_from_string(basedir, data, vars): try: if type(data) == str: data = unicode(data, 'utf-8') - environment = jinja2.Environment(trim_blocks=True) # undefined=J2Undefined) + environment = jinja2.Environment(trim_blocks=True) environment.filters.update(_get_filter_plugins()) + environment.template_class = J2Template + + # perhaps a nicer way to do this + ast = environment.parse(data) + undeclared = jinja2_meta.find_undeclared_variables(ast) + for x in undeclared: + if x not in vars: + return data + # TODO: may need some way of using lookup plugins here seeing we aren't calling # the legacy engine, lookup() as a function, perhaps? - environment.template_class = J2Template try: t = environment.from_string(data) @@ -421,10 +431,11 @@ def template_from_string(basedir, data, vars): if 'recursion' in str(re): raise errors.AnsibleError("recursive loop detected in template string: %s" % data) else: - raise ree + return data res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals), shared=True))) return res except jinja2.exceptions.UndefinedError: + # this shouldn't happen due to undeclared check above return data