Upgraded variable support met with upgraded conditional support, see examples/playbooks/upgraded_vars.yml
for details!
This commit is contained in:
parent
38c2b14339
commit
f585c4cde7
6 changed files with 58 additions and 25 deletions
|
@ -8,7 +8,8 @@ Core Features:
|
|||
* capability to set 'all_errors_fatal: True' in a playbook to force any error to stop execution versus
|
||||
a whole group or serial block needing to fail
|
||||
usable, without breaking the ability to override in ansible
|
||||
* ability to use variables from {{ }} syntax in mainline playbooks (work in progress)
|
||||
* ability to use variables from {{ }} syntax in mainline playbooks, new 'when' conditional,
|
||||
see examples/playbooks/upgraded_vars.yml
|
||||
* can set ansible_private_key_file as an inventory variable (similar to ansible_ssh_host, etc)
|
||||
|
||||
Modules added
|
||||
|
|
24
examples/playbooks/upgraded_vars.yml
Normal file
24
examples/playbooks/upgraded_vars.yml
Normal file
|
@ -0,0 +1,24 @@
|
|||
# in Ansible 1.2 and later, the $foo variable syntax, which is friendly enough for simple things
|
||||
# has been upgraded to allow Jinja2 substitiutions as well, which is now the preferred Syntax.
|
||||
# here is an example. Note that Jinja2 conditionals belong only in templates. Use ansible conditionals
|
||||
# in playbooks.
|
||||
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
|
||||
tasks:
|
||||
- shell: echo 'hello {{ ansible_hostname.upper() }}'
|
||||
|
||||
- shell: echo 'match'
|
||||
when: 2 == 2
|
||||
|
||||
- shell: echo 'no match'
|
||||
when: 2 == 2 + 1
|
||||
|
||||
- shell: echo '{{ ansible_os_family }}'
|
||||
|
||||
- shell: echo 'Centos'
|
||||
when: ansible_os_family == 'RedHat'
|
||||
|
||||
|
|
@ -71,6 +71,8 @@ class Task(object):
|
|||
else:
|
||||
raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))
|
||||
|
||||
elif x == 'when':
|
||||
ds['when'] = "jinja2_compare %s" % (ds[x])
|
||||
elif x.startswith("when_"):
|
||||
if 'when' in ds:
|
||||
raise errors.AnsibleError("multiple when_* statements specified in task %s" % (ds.get('name', ds['action'])))
|
||||
|
|
|
@ -424,6 +424,7 @@ class Runner(object):
|
|||
handler = utils.plugins.action_loader.get('async', self)
|
||||
|
||||
conditional = utils.template(self.basedir, self.conditional, inject, expand_lists=False)
|
||||
|
||||
if not utils.check_conditional(conditional):
|
||||
result = utils.jsonify(dict(skipped=True))
|
||||
self.callbacks.on_skipped(host, inject.get('item',None))
|
||||
|
|
|
@ -155,13 +155,18 @@ def check_conditional(conditional):
|
|||
return conditional
|
||||
|
||||
def is_set(var):
|
||||
return not var.startswith("$")
|
||||
return not var.startswith("$") and not '{{' in var
|
||||
|
||||
def is_unset(var):
|
||||
return var.startswith("$")
|
||||
return var.startswith("$") or '{{' in var
|
||||
|
||||
try:
|
||||
return eval(conditional.replace("\n", "\\n"))
|
||||
conditional = conditional.replace("\n", "\\n")
|
||||
result = eval(conditional)
|
||||
if result not in [ True, False ]:
|
||||
raise errors.AnsibleError("Conditional expression must evaluate to True or False: %s" % conditional)
|
||||
return result
|
||||
|
||||
except (NameError, SyntaxError):
|
||||
raise errors.AnsibleError("Could not evaluate the expression: " + conditional)
|
||||
|
||||
|
@ -545,6 +550,7 @@ def compile_when_to_only_if(expression):
|
|||
# when: int $x in $alist
|
||||
# when: float $x > 2 and $y <= $z
|
||||
# when: str $x != $y
|
||||
# when: jinja2_compare asdf # implies {{ asdf }}
|
||||
|
||||
if type(expression) not in [ str, unicode ]:
|
||||
raise errors.AnsibleError("invalid usage of when_ operator: %s" % expression)
|
||||
|
@ -562,8 +568,6 @@ def compile_when_to_only_if(expression):
|
|||
tcopy[i] = t
|
||||
return " ".join(tcopy)
|
||||
|
||||
|
||||
|
||||
# when_failed / when_changed
|
||||
elif tokens[0] in [ 'failed', 'changed' ]:
|
||||
tcopy = tokens[1:]
|
||||
|
@ -574,8 +578,6 @@ def compile_when_to_only_if(expression):
|
|||
tcopy[i] = t
|
||||
return " ".join(tcopy)
|
||||
|
||||
|
||||
|
||||
# when_integer / when_float / when_string
|
||||
elif tokens[0] in [ 'integer', 'float', 'string' ]:
|
||||
cast = None
|
||||
|
@ -602,6 +604,11 @@ def compile_when_to_only_if(expression):
|
|||
tcopy[i] = "(is_set('''%s''') and '''%s'''.lower() not in ('false', 'no', 'n', 'none', '0', ''))" % (t, t)
|
||||
return " ".join(tcopy)
|
||||
|
||||
# the stock 'when' without qualification (new in 1.2), assumes Jinja2 terms
|
||||
elif tokens[0] == 'jinja2_compare':
|
||||
# a Jinja2 evaluation that results in something Python can eval!
|
||||
presented = "{% if " + " ".join(tokens[1:]).strip() + " %} True {% else %} False {% endif %}"
|
||||
return presented
|
||||
else:
|
||||
raise errors.AnsibleError("invalid usage of when_ operator: %s" % expression)
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ def template(basedir, varname, vars, lookup_fatal=True, depth=0, expand_lists=Tr
|
|||
''' templates a data structure by traversing it and substituting for other data structures '''
|
||||
|
||||
if isinstance(varname, basestring):
|
||||
if '{{' in varname:
|
||||
if '{{' in varname or '{%' in varname:
|
||||
return template_from_string(basedir, varname, vars)
|
||||
m = _varFind(basedir, varname, vars, lookup_fatal, depth, expand_lists)
|
||||
if not m:
|
||||
|
@ -403,22 +403,20 @@ def _get_filter_plugins():
|
|||
FILTER_PLUGINS.update(filters)
|
||||
return FILTER_PLUGINS
|
||||
|
||||
class J2Undefined(jinja2.runtime.Undefined):
|
||||
def __str__(self):
|
||||
return "{{ %s }}" % self._undefined_name
|
||||
def __unicode__(self):
|
||||
return "{{ %s }}" % self._undefined_name
|
||||
|
||||
def template_from_string(basedir, data, vars):
|
||||
''' run a file through the (Jinja2) templating engine '''
|
||||
if type(data) == str:
|
||||
data = unicode(data, 'utf-8')
|
||||
environment = jinja2.Environment(trim_blocks=True, undefined=J2Undefined)
|
||||
environment.filters.update(_get_filter_plugins())
|
||||
# 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
|
||||
t = environment.from_string(data)
|
||||
res = jinja2.utils.concat(t.root_render_func(t.new_context(_jinja2_vars(basedir, vars, t.globals), shared=True)))
|
||||
return res
|
||||
|
||||
try:
|
||||
if type(data) == str:
|
||||
data = unicode(data, 'utf-8')
|
||||
environment = jinja2.Environment(trim_blocks=True) # undefined=J2Undefined)
|
||||
environment.filters.update(_get_filter_plugins())
|
||||
# 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
|
||||
t = environment.from_string(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:
|
||||
return data
|
||||
|
||||
|
|
Loading…
Reference in a new issue