summaryrefslogtreecommitdiff
path: root/lib/ansible/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/plugins')
-rw-r--r--lib/ansible/plugins/action/assert.py23
-rw-r--r--lib/ansible/plugins/callback/__init__.py4
-rw-r--r--lib/ansible/plugins/filter/core.py5
-rw-r--r--lib/ansible/plugins/lookup/first_found.py15
4 files changed, 43 insertions, 4 deletions
diff --git a/lib/ansible/plugins/action/assert.py b/lib/ansible/plugins/action/assert.py
index 7721a6b4..e8ab6a9a 100644
--- a/lib/ansible/plugins/action/assert.py
+++ b/lib/ansible/plugins/action/assert.py
@@ -63,8 +63,29 @@ class ActionModule(ActionBase):
quiet = boolean(self._task.args.get('quiet', False), strict=False)
+ # directly access 'that' via untemplated args from the task so we can intelligently trust embedded
+ # templates and preserve the original inputs/locations for better messaging on assert failures and
+ # errors.
+ # FIXME: even in devel, things like `that: item` don't always work properly (truthy string value
+ # is not really an embedded expression)
+ # we could fix that by doing direct var lookups on the inputs
+ # FIXME: some form of this code should probably be shared between debug, assert, and
+ # Task.post_validate, since they
+ # have a lot of overlapping needs
+ try:
+ thats = self._task.untemplated_args['that']
+ except KeyError:
+ # in the case of "we got our entire args dict from a template", we can just consult the
+ # post-templated dict (the damage has likely already been done for embedded templates anyway)
+ thats = self._task.args['that']
+
+ # FIXME: this is a case where we only want to resolve indirections, NOT recurse containers
+ # (and even then, the leaf-most expression being wrapped is at least suboptimal
+ # (since its expression will be "eaten").
+ if isinstance(thats, str):
+ thats = self._templar.template(thats)
+
# make sure the 'that' items are a list
- thats = self._task.args['that']
if not isinstance(thats, list):
thats = [thats]
diff --git a/lib/ansible/plugins/callback/__init__.py b/lib/ansible/plugins/callback/__init__.py
index d4fc347d..7646d293 100644
--- a/lib/ansible/plugins/callback/__init__.py
+++ b/lib/ansible/plugins/callback/__init__.py
@@ -38,7 +38,7 @@ from ansible.parsing.yaml.objects import AnsibleUnicode
from ansible.plugins import AnsiblePlugin
from ansible.utils.color import stringc
from ansible.utils.display import Display
-from ansible.utils.unsafe_proxy import AnsibleUnsafeText, NativeJinjaUnsafeText
+from ansible.utils.unsafe_proxy import AnsibleUnsafeText, NativeJinjaUnsafeText, _is_unsafe
from ansible.vars.clean import strip_internal_keys, module_response_deepcopy
import yaml
@@ -113,6 +113,8 @@ def _munge_data_for_lossy_yaml(scalar):
def _pretty_represent_str(self, data):
"""Uses block style for multi-line strings"""
+ if _is_unsafe(data):
+ data = data._strip_unsafe()
data = text_type(data)
if _should_use_block(data):
style = '|'
diff --git a/lib/ansible/plugins/filter/core.py b/lib/ansible/plugins/filter/core.py
index 52a2cd10..b7e2c11e 100644
--- a/lib/ansible/plugins/filter/core.py
+++ b/lib/ansible/plugins/filter/core.py
@@ -37,6 +37,7 @@ from ansible.utils.display import Display
from ansible.utils.encrypt import passlib_or_crypt
from ansible.utils.hashing import md5s, checksum_s
from ansible.utils.unicode import unicode_wrap
+from ansible.utils.unsafe_proxy import _is_unsafe
from ansible.utils.vars import merge_hash
display = Display()
@@ -215,6 +216,8 @@ def from_yaml(data):
# The ``text_type`` call here strips any custom
# string wrapper class, so that CSafeLoader can
# read the data
+ if _is_unsafe(data):
+ data = data._strip_unsafe()
return yaml_load(text_type(to_text(data, errors='surrogate_or_strict')))
return data
@@ -224,6 +227,8 @@ def from_yaml_all(data):
# The ``text_type`` call here strips any custom
# string wrapper class, so that CSafeLoader can
# read the data
+ if _is_unsafe(data):
+ data = data._strip_unsafe()
return yaml_load_all(text_type(to_text(data, errors='surrogate_or_strict')))
return data
diff --git a/lib/ansible/plugins/lookup/first_found.py b/lib/ansible/plugins/lookup/first_found.py
index 5b94b103..a882db01 100644
--- a/lib/ansible/plugins/lookup/first_found.py
+++ b/lib/ansible/plugins/lookup/first_found.py
@@ -136,7 +136,6 @@ RETURN = """
elements: path
"""
import os
-import re
from collections.abc import Mapping, Sequence
@@ -147,10 +146,22 @@ from ansible.module_utils.six import string_types
from ansible.plugins.lookup import LookupBase
+def _splitter(value, chars):
+ chars = set(chars)
+ v = ''
+ for c in value:
+ if c in chars:
+ yield v
+ v = ''
+ continue
+ v += c
+ yield v
+
+
def _split_on(terms, spliters=','):
termlist = []
if isinstance(terms, string_types):
- termlist = re.split(r'[%s]' % ''.join(map(re.escape, spliters)), terms)
+ termlist = list(_splitter(terms, spliters))
else:
# added since options will already listify
for t in terms: