Ansible does not provide a way for users to register Jinja2 test plugins. Furthermore, many of Ansible’s filter plugins are logically tests, but they are not registered as such. I have submitted a Pull Request (there is some discussion there already, but I’ll repeat myself here):
https://github.com/ansible/ansible/pull/8217
Ansible has a concept of “filter_plugins” that are registered with Jinja2 in order to provide new functionality in variable templates. This enables custom filters to be applied with a | character. Users can even create their own custom ones.
Jinja2, though, actually has two separate notions: “tests” transform variables into booleans (used by is, is not, and some filters); all other transformations are “filters” (which use the | syntax). See http://jinja.pocoo.org/docs/templates/#builtin-filters … the Tests documentation immediately follows the Filters documentation.
Ansible conflates these two notions, registering all of its Jinja2 plugins only as filters, even the ones (like match and version_compare) that are logically tests. This means that Ansible’s boolean “filters” cannot be used as arguments to filter functions like reject. It also is the reason for the inconsistency between “var | success” and “var is defined”; the former is an Ansible filter, and the latter is a built-in Jinja2 one.
My proposal is for Ansible to have two separate Jinja2 plugin groups: tests and filters. For backwards compatibility, all tests must also be registered as filters. Additionally, users must be able to register new tests (as they currently can with filters).
My current implementation (the aforementioned Pull Request) does this. It places the plugins in two entirely separate groups (test_plugins and filter_plugins) because that seemed to me to offer the most clarity and flexibility for Ansible users, but there is no reason that the definitions could not be combined into a single file.
This change allows entirely new patterns of usage. For example, it can allow the user to pull certain lines from stdout_lines (e.g., those matching a pattern), and apply with_items to each of those. The user could even add new tests like “startswith(prefix)” for string matching. At present, none of this is possible (AFAICT) without using external scripts.
Again, I already have a working implementation at https://github.com/ansible/ansible/pull/8217 that’s ready to go (documentation and all), but I’m happy to discuss other approaches.
Cheers,
Brandon