diff --git a/changelogs/fragments/contains-test.yaml b/changelogs/fragments/contains-test.yaml new file mode 100644 index 00000000000..087257918c7 --- /dev/null +++ b/changelogs/fragments/contains-test.yaml @@ -0,0 +1,2 @@ +minor_changes: +- '``contains`` jinja2 test - Add a ``contains`` jinja2 test designed for use in ``map`` and ``selectattr`` filters (https://github.com/ansible/ansible/pull/45798)' diff --git a/docs/docsite/rst/user_guide/playbooks_tests.rst b/docs/docsite/rst/user_guide/playbooks_tests.rst index 0eb11f3b069..f7fbdf03a1a 100644 --- a/docs/docsite/rst/user_guide/playbooks_tests.rst +++ b/docs/docsite/rst/user_guide/playbooks_tests.rst @@ -113,6 +113,41 @@ To see if a list includes or is included by another list, you can use 'subset' a msg: "B is included in A" when: b is subset(a) +.. _contains_test: + +Test if a list contains a value +``````````````````````````````` + +.. versionadded:: 2.8 + +Ansible includes a ``contains`` test which operates similarly, but in reverse of the Jinja2 provided ``in`` test. +This is designed with the ability to allow use of ``contains`` with filters such as ``map`` and ``selectattr``:: + + vars: + lacp_groups: + - master: lacp0 + network: 10.65.100.0/24 + gateway: 10.65.100.1 + dns4: + - 10.65.100.10 + - 10.65.100.11 + interfaces: + - em1 + - em2 + + - master: lacp1 + network: 10.65.120.0/24 + gateway: 10.65.120.1 + dns4: + - 10.65.100.10 + - 10.65.100.11 + interfaces: + - em3 + - em4 + + tasks: + - debug: + msg: "{{ (lacp_groups|selectattr('interfaces', 'contains', 'em1')|first).master }}" .. _path_tests: diff --git a/lib/ansible/plugins/test/mathstuff.py b/lib/ansible/plugins/test/mathstuff.py index b8251ad42ca..952562cc171 100644 --- a/lib/ansible/plugins/test/mathstuff.py +++ b/lib/ansible/plugins/test/mathstuff.py @@ -36,6 +36,14 @@ def isnotanumber(x): return False +def contains(seq, value): + '''Opposite of the ``in`` test, allowing use as a test in filters like ``selectattr`` + + .. versionadded:: 2.8 + ''' + return value in seq + + class TestModule: ''' Ansible math jinja2 tests ''' @@ -46,6 +54,9 @@ class TestModule: 'subset': issubset, 'issuperset': issuperset, 'superset': issuperset, + 'contains': contains, + + # numbers 'isnan': isnotanumber, 'nan': isnotanumber, }