remove bare var handling in conditionals (#51030)

* remove bare var handling in conditionals

  this makes top level and multilevel vars (dicts keys) behave the same
  it will require adding |bool for 'string comparissons' in indirect templates

  - added new tests to ensure uniform handling
  - switched to 'is' testing for status
  - changed warning to 'conditional' as 'when:' is not only place it gets triggered

* updated to include toggle and deprecation

* fix deprecated

* updated tests to handle toggle

* fixed typo and added note about the future
This commit is contained in:
Brian Coca 2019-01-30 15:00:24 -05:00 committed by ansibot
commit 4a0fceaa3b
8 changed files with 589 additions and 374 deletions

View file

@ -318,6 +318,19 @@ COLOR_WARN:
env: [{name: ANSIBLE_COLOR_WARN}]
ini:
- {key: warn, section: colors}
CONDITINAL_BARE_VARS:
name: Allow bare variable evaluation in conditionals
default: True
type: boolean
description:
- With this setting on (True), runing conditional evaluation 'var' is treated differently 'var.subkey' as the first is evaluted
directly while the second goes though the Jinja2 parser. But 'false' strings in 'var' get evaluated as booleans.
- With this settting off they both evalutate the same but in cases in which 'var' was 'false' (a string) it won't get evaluated as a boolean anymore.
- Currently this setting defaults to 'True' but will soon change to 'False' and the setting itself will be removed in the future.
- Expect the default to change in version 2.10 and that this setting eventually will be deprecated after 2.12
env: [{name: ANSIBLE_CONDITIONAL_BARE_VARS}]
ini:
- {key: conditional_bare_variables, section: defaults}
ACTION_WARNINGS:
name: Toggle action warnings
default: True

View file

@ -25,6 +25,7 @@ import re
from jinja2.compiler import generate
from jinja2.exceptions import UndefinedError
from ansible import constants as C
from ansible.errors import AnsibleError, AnsibleUndefinedVariable
from ansible.module_utils.six import text_type
from ansible.module_utils._text import to_native
@ -113,21 +114,16 @@ class Conditional:
if isinstance(conditional, bool):
return conditional
if C.CONDITINAL_BARE_VARS:
if conditional in all_vars and VALID_VAR_REGEX.match(conditional):
display.deprecated('evaluating %s as a bare variable, this behaviour will go away and you might need to add |bool'
' to the expression in the future. Also see CONDITIONAL_BARE_VARS configuration toggle.' % conditional, "2.12")
conditional = all_vars[conditional]
if templar.is_template(conditional):
display.warning('when statements should not include jinja2 '
display.warning('conditional statements should not include jinja2 '
'templating delimiters such as {{ }} or {%% %%}. '
'Found: %s' % conditional)
# pull the "bare" var out, which allows for nested conditionals
# and things like:
# - assert:
# that:
# - item
# with_items:
# - 1 == 1
if conditional in all_vars and VALID_VAR_REGEX.match(conditional):
conditional = all_vars[conditional]
# make sure the templar is using the variables specified with this method
templar.set_available_variables(variables=all_vars)
@ -219,5 +215,5 @@ class Conditional:
# as nothing above matched the failed var name, re-raise here to
# trigger the AnsibleUndefinedVariable exception again below
raise
except Exception as new_e:
except Exception:
raise AnsibleUndefinedVariable("error while evaluating conditional (%s): %s" % (original, e))