Added 'when' as a shortcut around only_if.
This commit is contained in:
parent
a768e9a9ff
commit
21258dcc66
3 changed files with 143 additions and 31 deletions
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
# this is a demo of conditional executions using 'only_if', which can skip
|
# this is a demo of conditional executions using 'when' statements, which can skip
|
||||||
# certain tasks on machines/platforms/etc where they do not apply.
|
# certain tasks on machines/platforms/etc where they do not apply.
|
||||||
|
|
||||||
- hosts: all
|
- hosts: all
|
||||||
|
@ -7,41 +7,44 @@
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
favcolor: "red"
|
favcolor: "red"
|
||||||
|
dog: "fido"
|
||||||
|
cat: "whiskers"
|
||||||
ssn: 8675309
|
ssn: 8675309
|
||||||
|
|
||||||
# Below we're going to define some expressions.
|
# These are the types of when statemnets available
|
||||||
|
# when_set: $variable_name
|
||||||
|
# when_unset: $variable_name
|
||||||
|
# when_str: $x == "test"
|
||||||
|
# when_int: $y > 2
|
||||||
|
# when_float: $z => 2.3
|
||||||
#
|
#
|
||||||
# Not only can we assign variables for reuse, but we can also assign conditional
|
# when using 'when', take care to make sure any variables given are surrounded by spaces
|
||||||
# expressions. By keeping these in 'vars', the task section remains
|
# as an example, $z>3 will not do what you want, use "$z > 3"
|
||||||
# extraordinarily clean, and not littered with programming language
|
|
||||||
# constructs -- so it's easily skimmed by humans.
|
|
||||||
#
|
|
||||||
# Remember to quote any variables if they are not numbers!
|
|
||||||
#
|
|
||||||
# Interesting fact: aside from the $variables, these expressions are actually
|
|
||||||
# tiny bits of Python. They are evaluated in the context of each host, so different
|
|
||||||
# steps can be skipped on different hosts! They should evaluate to either True
|
|
||||||
# or False
|
|
||||||
|
|
||||||
is_favcolor_blue: "'$favcolor' == 'blue'"
|
|
||||||
is_centos: "'$facter_operatingsystem' == 'CentOS'"
|
|
||||||
|
|
||||||
# NOTE:
|
|
||||||
#
|
|
||||||
# facter and ohai variables can be used in only_if statements too
|
|
||||||
# ex: "'$facter_operatingsystem' == 'CentOS'", which bubble up automatically
|
|
||||||
# from the managed machines
|
|
||||||
#
|
|
||||||
# this example won't do that though, as you might not have facter or ohai,
|
|
||||||
# but you get the idea...
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
|
||||||
- name: "do this if my favcolor is blue"
|
- name: "do this if my favcolor is blue, and my dog is named fido"
|
||||||
action: shell /bin/false
|
action: shell /bin/false
|
||||||
only_if: '$is_favcolor_blue'
|
when_string: $favcolor == 'blue' and $dog == 'fido'
|
||||||
|
|
||||||
- name: "do this if my favcolor is not blue"
|
- name: "do this if my favcolor is not blue, and my dog is named fido"
|
||||||
action: shell /bin/true
|
action: shell /bin/true
|
||||||
only_if: 'not ($is_favcolor_blue)'
|
when_string: $favcolor != 'blue' and $dog == 'fido'
|
||||||
|
|
||||||
|
- name: "do this if my SSN is over 9000"
|
||||||
|
action: shell /bin/true
|
||||||
|
when_integer: $ssn > 9000
|
||||||
|
|
||||||
|
- name: "do this if I have one of these SSNs"
|
||||||
|
action: shell /bin/true
|
||||||
|
when_integer: $ssn in [ 8675309, 8675310, 8675311 ]
|
||||||
|
|
||||||
|
- name: "do this if a variable named hippo is NOT defined"
|
||||||
|
action: shell /bin/true
|
||||||
|
when_unset: $hippo
|
||||||
|
|
||||||
|
- name: "do this if a variable named hippo is defined"
|
||||||
|
action: shell /bin/true
|
||||||
|
when_set: $hippo
|
||||||
|
|
||||||
|
|
||||||
|
|
47
examples/playbooks/conditionals_part3.yml
Normal file
47
examples/playbooks/conditionals_part3.yml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
# this is a demo of conditional executions using 'only_if', which can skip
|
||||||
|
# certain tasks on machines/platforms/etc where they do not apply. This is
|
||||||
|
# the more 'raw' version of the 'when' statement, most users will be able to
|
||||||
|
# use 'when' directly. 'only_if' is an older feature, and useful for when
|
||||||
|
# you need more advanced expression control.
|
||||||
|
|
||||||
|
- hosts: all
|
||||||
|
user: root
|
||||||
|
|
||||||
|
vars:
|
||||||
|
favcolor: "red"
|
||||||
|
ssn: 8675309
|
||||||
|
|
||||||
|
# Below we're going to define some expressions.
|
||||||
|
#
|
||||||
|
# Not only can we assign variables for reuse, but we can also assign conditional
|
||||||
|
# expressions. By keeping these in 'vars', the task section remains
|
||||||
|
# extraordinarily clean, and not littered with programming language
|
||||||
|
# constructs -- so it's easily skimmed by humans.
|
||||||
|
#
|
||||||
|
# Remember to quote any variables if they are not numbers!
|
||||||
|
#
|
||||||
|
# Interesting fact: aside from the $variables, these expressions are actually
|
||||||
|
# tiny bits of Python. They are evaluated in the context of each host, so different
|
||||||
|
# steps can be skipped on different hosts! They should evaluate to either True
|
||||||
|
# or False
|
||||||
|
|
||||||
|
is_favcolor_blue: "'$favcolor' == 'blue'"
|
||||||
|
is_centos: "'$facter_operatingsystem' == 'CentOS'"
|
||||||
|
|
||||||
|
# NOTE:
|
||||||
|
#
|
||||||
|
# setup module values, facter and ohai variables can be used in only_if statements too
|
||||||
|
# ex: "'$facter_operatingsystem' == 'CentOS'", which bubble up automatically
|
||||||
|
# from the managed machines. This example doesn't do that though.
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
- name: "do this if my favcolor is blue"
|
||||||
|
action: shell /bin/false
|
||||||
|
only_if: '$is_favcolor_blue'
|
||||||
|
|
||||||
|
- name: "do this if my favcolor is not blue"
|
||||||
|
action: shell /bin/true
|
||||||
|
only_if: 'not ($is_favcolor_blue)'
|
||||||
|
|
|
@ -22,7 +22,7 @@ from ansible import utils
|
||||||
class Task(object):
|
class Task(object):
|
||||||
|
|
||||||
__slots__ = [
|
__slots__ = [
|
||||||
'name', 'action', 'only_if', 'async_seconds', 'async_poll_interval',
|
'name', 'action', 'only_if', 'when', 'async_seconds', 'async_poll_interval',
|
||||||
'notify', 'module_name', 'module_args', 'module_vars',
|
'notify', 'module_name', 'module_args', 'module_vars',
|
||||||
'play', 'notified_by', 'tags', 'register',
|
'play', 'notified_by', 'tags', 'register',
|
||||||
'delegate_to', 'first_available_file', 'ignore_errors',
|
'delegate_to', 'first_available_file', 'ignore_errors',
|
||||||
|
@ -58,6 +58,11 @@ class Task(object):
|
||||||
else:
|
else:
|
||||||
raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))
|
raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))
|
||||||
|
|
||||||
|
elif x.startswith("when_"):
|
||||||
|
when_name = x.replace("when_","")
|
||||||
|
ds['when'] = "%s %s" % (when_name, ds[x])
|
||||||
|
ds.pop(x)
|
||||||
|
|
||||||
elif not x in Task.VALID_KEYS:
|
elif not x in Task.VALID_KEYS:
|
||||||
raise errors.AnsibleError("%s is not a legal parameter in an Ansible task or handler" % x)
|
raise errors.AnsibleError("%s is not a legal parameter in an Ansible task or handler" % x)
|
||||||
|
|
||||||
|
@ -109,6 +114,8 @@ class Task(object):
|
||||||
|
|
||||||
# load various attributes
|
# load various attributes
|
||||||
self.only_if = ds.get('only_if', 'True')
|
self.only_if = ds.get('only_if', 'True')
|
||||||
|
self.when = ds.get('when', None)
|
||||||
|
|
||||||
self.async_seconds = int(ds.get('async', 0)) # not async by default
|
self.async_seconds = int(ds.get('async', 0)) # not async by default
|
||||||
self.async_poll_interval = int(ds.get('poll', 10)) # default poll = 10 seconds
|
self.async_poll_interval = int(ds.get('poll', 10)) # default poll = 10 seconds
|
||||||
self.notify = ds.get('notify', [])
|
self.notify = ds.get('notify', [])
|
||||||
|
@ -169,3 +176,58 @@ class Task(object):
|
||||||
self.tags.extend(apply_tags)
|
self.tags.extend(apply_tags)
|
||||||
self.tags.extend(import_tags)
|
self.tags.extend(import_tags)
|
||||||
|
|
||||||
|
if self.when is not None:
|
||||||
|
if self.only_if != 'True':
|
||||||
|
raise errors.AnsibleError('when obsoletes only_if, only use one or the other')
|
||||||
|
self.only_if = self.compile_when_to_only_if(self.when)
|
||||||
|
|
||||||
|
def compile_when_to_only_if(self, expression):
|
||||||
|
'''
|
||||||
|
when is a shorthand for writing only_if conditionals. It requires less quoting
|
||||||
|
magic. only_if is retained for backwards compatibility.
|
||||||
|
'''
|
||||||
|
|
||||||
|
# when: set $variable
|
||||||
|
# when: unset $variable
|
||||||
|
# when: int $x >= $z and $y < 3
|
||||||
|
# when: int $x in $alist
|
||||||
|
# when: float $x > 2 and $y <= $z
|
||||||
|
# when: str $x != $y
|
||||||
|
|
||||||
|
if type(expression) not in [ str, unicode ]:
|
||||||
|
raise errors.AnsibleError("invalid usage of when_ operator: %s" % expression)
|
||||||
|
tokens = expression.split()
|
||||||
|
if len(tokens) < 2:
|
||||||
|
raise errors.AnsibleError("invalid usage of when_ operator: %s" % expression)
|
||||||
|
|
||||||
|
# when_set / when_unset
|
||||||
|
if tokens[0] in [ 'set', 'unset' ]:
|
||||||
|
if len(tokens) != 2:
|
||||||
|
raise errors.AnsibleError("usage: when: <set|unset> <$variableName>")
|
||||||
|
return "is_%s('%s')" % (tokens[0], tokens[1])
|
||||||
|
|
||||||
|
# when_integer / when_float / when_string
|
||||||
|
elif tokens[0] in [ 'integer', 'float', 'string' ]:
|
||||||
|
cast = None
|
||||||
|
if tokens[0] == 'integer':
|
||||||
|
cast = 'int'
|
||||||
|
elif tokens[0] == 'string':
|
||||||
|
cast = 'str'
|
||||||
|
elif tokens[0] == 'float':
|
||||||
|
cast = 'float'
|
||||||
|
tcopy = tokens[1:]
|
||||||
|
for (i,t) in enumerate(tokens[1:]):
|
||||||
|
if t.find("$") != -1:
|
||||||
|
# final variable substitution will happen in Runner code
|
||||||
|
tcopy[i] = "%s('%s')" % (cast, t)
|
||||||
|
else:
|
||||||
|
tcopy[i] = t
|
||||||
|
return " ".join(tcopy)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise errors.AnsibleError("invalid usage of when_ operator: %s" % expression)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue