Make lookups being fatal up to the caller

Fixes #1769.
This commit is contained in:
Daniel Hokka Zakrisson 2012-12-19 19:10:24 +01:00
parent eb57c9c430
commit 3a36c024da
2 changed files with 22 additions and 18 deletions

View file

@ -294,7 +294,7 @@ class PlayBook(object):
def _run_task(self, play, task, is_handler): def _run_task(self, play, task, is_handler):
''' run a single task in the playbook and recursively run any subtasks. ''' ''' run a single task in the playbook and recursively run any subtasks. '''
self.callbacks.on_task_start(utils.template(play.basedir, task.name, task.module_vars), is_handler) self.callbacks.on_task_start(utils.template(play.basedir, task.name, task.module_vars, lookup_fatal=False), is_handler)
# load up an appropriate ansible runner to run the task in parallel # load up an appropriate ansible runner to run the task in parallel
results = self._run_task_internal(task) results = self._run_task_internal(task)

View file

@ -33,7 +33,7 @@ import pwd
_LISTRE = re.compile(r"(\w+)\[(\d+)\]") _LISTRE = re.compile(r"(\w+)\[(\d+)\]")
JINJA2_OVERRIDE='#jinja2:' JINJA2_OVERRIDE='#jinja2:'
def _varFindLimitSpace(basedir, vars, space, part, depth): def _varFindLimitSpace(basedir, vars, space, part, lookup_fatal, depth):
''' limits the search space of space to part ''' limits the search space of space to part
basically does space.get(part, None), but with basically does space.get(part, None), but with
@ -47,7 +47,7 @@ def _varFindLimitSpace(basedir, vars, space, part, depth):
if part[0] == '{' and part[-1] == '}': if part[0] == '{' and part[-1] == '}':
part = part[1:-1] part = part[1:-1]
# Template part to resolve variables within (${var$var2}) # Template part to resolve variables within (${var$var2})
part = varReplace(basedir, part, vars, depth=depth + 1) part = varReplace(basedir, part, vars, lookup_fatal, depth=depth + 1)
# Now find it # Now find it
if part in space: if part in space:
@ -66,7 +66,7 @@ def _varFindLimitSpace(basedir, vars, space, part, depth):
return space return space
def _varFind(basedir, text, vars, depth=0): def _varFind(basedir, text, vars, lookup_fatal, depth=0):
''' Searches for a variable in text and finds its replacement in vars ''' Searches for a variable in text and finds its replacement in vars
The variables can have two formats; The variables can have two formats;
@ -135,7 +135,7 @@ def _varFind(basedir, text, vars, depth=0):
pass pass
elif is_complex and text[end] == '.': elif is_complex and text[end] == '.':
if brace_level == 1: if brace_level == 1:
space = _varFindLimitSpace(basedir, vars, space, text[part_start:end], depth) space = _varFindLimitSpace(basedir, vars, space, text[part_start:end], lookup_fatal, depth)
part_start = end + 1 part_start = end + 1
else: else:
# This breaks out of the loop on non-variable name characters # This breaks out of the loop on non-variable name characters
@ -161,7 +161,11 @@ def _varFind(basedir, text, vars, depth=0):
args = varReplace(basedir, args, vars, depth=depth+1, expand_lists=True) args = varReplace(basedir, args, vars, depth=depth+1, expand_lists=True)
instance = utils.plugins.lookup_loader.get(lookup_plugin_name.lower(), basedir=basedir) instance = utils.plugins.lookup_loader.get(lookup_plugin_name.lower(), basedir=basedir)
if instance is not None: if instance is not None:
replacement = instance.run(args, inject=vars) try:
replacement = instance.run(args, inject=vars)
except errors.AnsibleError:
if not lookup_fatal:
replacement = None
else: else:
replacement = None replacement = None
return {'replacement': replacement, 'start': start, 'end': end} return {'replacement': replacement, 'start': start, 'end': end}
@ -170,10 +174,10 @@ def _varFind(basedir, text, vars, depth=0):
var_end -= 1 var_end -= 1
if text[var_end] != '}' or brace_level != 0: if text[var_end] != '}' or brace_level != 0:
return None return None
space = _varFindLimitSpace(basedir, vars, space, text[part_start:var_end], depth) space = _varFindLimitSpace(basedir, vars, space, text[part_start:var_end], lookup_fatal, depth)
return {'replacement': space, 'start': start, 'end': end} return {'replacement': space, 'start': start, 'end': end}
def varReplace(basedir, raw, vars, depth=0, expand_lists=False): def varReplace(basedir, raw, vars, lookup_fatal=True, depth=0, expand_lists=False):
''' Perform variable replacement of $variables in string raw using vars dictionary ''' ''' Perform variable replacement of $variables in string raw using vars dictionary '''
# this code originally from yum # this code originally from yum
@ -183,7 +187,7 @@ def varReplace(basedir, raw, vars, depth=0, expand_lists=False):
done = [] # Completed chunks to return done = [] # Completed chunks to return
while raw: while raw:
m = _varFind(basedir, raw, vars, depth) m = _varFind(basedir, raw, vars, lookup_fatal, depth)
if not m: if not m:
done.append(raw) done.append(raw)
break break
@ -195,7 +199,7 @@ def varReplace(basedir, raw, vars, depth=0, expand_lists=False):
if expand_lists and isinstance(replacement, (list, tuple)): if expand_lists and isinstance(replacement, (list, tuple)):
replacement = ",".join(replacement) replacement = ",".join(replacement)
if isinstance(replacement, (str, unicode)): if isinstance(replacement, (str, unicode)):
replacement = varReplace(basedir, replacement, vars, depth=depth+1, expand_lists=expand_lists) replacement = varReplace(basedir, replacement, vars, lookup_fatal, depth=depth+1, expand_lists=expand_lists)
if replacement is None: if replacement is None:
replacement = raw[m['start']:m['end']] replacement = raw[m['start']:m['end']]
@ -206,38 +210,38 @@ def varReplace(basedir, raw, vars, depth=0, expand_lists=False):
return ''.join(done) return ''.join(done)
def template_ds(basedir, varname, vars): def template_ds(basedir, varname, vars, lookup_fatal=True):
''' templates a data structure by traversing it and substituting for other data structures ''' ''' templates a data structure by traversing it and substituting for other data structures '''
if isinstance(varname, basestring): if isinstance(varname, basestring):
m = _varFind(basedir, varname, vars) m = _varFind(basedir, varname, vars, lookup_fatal)
if not m: if not m:
return varname return varname
if m['start'] == 0 and m['end'] == len(varname): if m['start'] == 0 and m['end'] == len(varname):
if m['replacement'] is not None: if m['replacement'] is not None:
return template_ds(basedir, m['replacement'], vars) return template_ds(basedir, m['replacement'], vars, lookup_fatal)
else: else:
return varname return varname
else: else:
return template(basedir, varname, vars) return template(basedir, varname, vars, lookup_fatal)
elif isinstance(varname, (list, tuple)): elif isinstance(varname, (list, tuple)):
return [template_ds(basedir, v, vars) for v in varname] return [template_ds(basedir, v, vars, lookup_fatal) for v in varname]
elif isinstance(varname, dict): elif isinstance(varname, dict):
d = {} d = {}
for (k, v) in varname.iteritems(): for (k, v) in varname.iteritems():
d[k] = template_ds(basedir, v, vars) d[k] = template_ds(basedir, v, vars, lookup_fatal)
return d return d
else: else:
return varname return varname
def template(basedir, text, vars, expand_lists=False): def template(basedir, text, vars, lookup_fatal=True, expand_lists=False):
''' run a text buffer through the templating engine until it no longer changes ''' ''' run a text buffer through the templating engine until it no longer changes '''
try: try:
text = text.decode('utf-8') text = text.decode('utf-8')
except UnicodeEncodeError: except UnicodeEncodeError:
pass # already unicode pass # already unicode
text = varReplace(basedir, unicode(text), vars, expand_lists=expand_lists) text = varReplace(basedir, unicode(text), vars, lookup_fatal=lookup_fatal, expand_lists=expand_lists)
return text return text
class _jinja2_vars(object): class _jinja2_vars(object):