Improve variable smushing so it only has to be done in one place. This is related to shlex.split being called

on untemplated variables in some rare cases.
pull/2764/merge
Michael DeHaan 12 years ago
parent af2fb56a10
commit 6fdfbb1a34

@ -18,7 +18,7 @@
import ansible.inventory import ansible.inventory
import ansible.constants as C import ansible.constants as C
import ansible.runner import ansible.runner
from ansible.utils.template import template, smush_braces from ansible.utils.template import template
from ansible import utils from ansible import utils
from ansible import errors from ansible import errors
import ansible.callbacks import ansible.callbacks
@ -159,7 +159,7 @@ class PlayBook(object):
# a playbook (list of plays) decided to include some other list of plays # a playbook (list of plays) decided to include some other list of plays
# from another file. The result is a flat list of plays in the end. # from another file. The result is a flat list of plays in the end.
tokens = shlex.split(smush_braces(play['include'])) tokens = shlex.split(play['include'])
incvars = vars.copy() incvars = vars.copy()
if 'vars' in play: if 'vars' in play:

@ -17,7 +17,7 @@
############################################# #############################################
from ansible.utils.template import template, smush_braces from ansible.utils.template import template
from ansible import utils from ansible import utils
from ansible import errors from ansible import errors
from ansible.playbook.task import Task from ansible.playbook.task import Task
@ -239,7 +239,7 @@ class Play(object):
task_vars['_original_file'] = original_file task_vars['_original_file'] = original_file
if 'include' in x: if 'include' in x:
tokens = shlex.split(smush_braces(str(x['include']))) tokens = shlex.split(str(x['include']))
items = [''] items = ['']
included_additional_conditions = list(additional_conditions) included_additional_conditions = list(additional_conditions)
for k in x: for k in x:

@ -58,9 +58,6 @@ class Task(object):
# code to allow for saying "modulename: args" versus "action: modulename args" # code to allow for saying "modulename: args" versus "action: modulename args"
if x in utils.plugins.module_finder: if x in utils.plugins.module_finder:
if 'include' in ds and isinstance(ds, basestring):
ds['include'] = template.smush_braces(ds['include'])
if 'action' in ds: if 'action' in ds:
raise errors.AnsibleError("multiple actions specified in task %s" % (ds.get('name', ds['action']))) raise errors.AnsibleError("multiple actions specified in task %s" % (ds.get('name', ds['action'])))
if isinstance(ds[x], dict): if isinstance(ds[x], dict):

@ -255,9 +255,31 @@ def parse_json(raw_data):
return { "failed" : True, "parsed" : False, "msg" : orig_data } return { "failed" : True, "parsed" : False, "msg" : orig_data }
return results return results
def smush_braces(data):
''' smush Jinaj2 braces so unresolved templates like {{ foo }} don't get parsed weird by key=value code '''
while data.find('{{ ') != -1:
data = data.replace('{{ ', '{{')
while data.find(' }}') != -1:
data = data.replace(' }}', '}}')
return data
def smush_ds(data):
# things like key={{ foo }} are not handled by shlex.split well, so preprocess any YAML we load
# so we do not have to call smush elsewhere
if type(data) == list:
return [ smush_ds(x) for x in data ]
elif type(data) == dict:
for (k,v) in data.items():
data[k] = smush_ds(v)
return data
elif isinstance(data, basestring):
return smush_braces(data)
else:
return data
def parse_yaml(data): def parse_yaml(data):
''' convert a yaml string to a data structure ''' ''' convert a yaml string to a data structure '''
return yaml.safe_load(data) return smush_ds(yaml.safe_load(data))
def process_yaml_error(exc, data, path=None): def process_yaml_error(exc, data, path=None):
if hasattr(exc, 'problem_mark'): if hasattr(exc, 'problem_mark'):

@ -437,19 +437,9 @@ def template_from_file(basedir, path, vars):
res = res + '\n' res = res + '\n'
return template(basedir, res, vars) return template(basedir, res, vars)
def smush_braces(data):
''' smush Jinaj2 braces so unresolved templates like {{ foo }} don't get parsed weird by key=value code '''
while data.find('{{ ') != -1:
data = data.replace('{{ ', '{{')
while data.find(' }}') != -1:
data = data.replace(' }}', '}}')
return data
def template_from_string(basedir, data, vars): def template_from_string(basedir, data, vars):
''' run a file through the (Jinja2) templating engine ''' ''' run a file through the (Jinja2) templating engine '''
data = smush_braces(data)
try: try:
if type(data) == str: if type(data) == str:
data = unicode(data, 'utf-8') data = unicode(data, 'utf-8')

Loading…
Cancel
Save