Fix rekey_on_member when key is undefined (#75131)

* Fix rekey_on_member when key is undefined and add a test case

* Add documentation about error handling in filter and test plugin sections
pull/75603/head
Sloane Hertel 3 years ago committed by GitHub
parent 051a257092
commit e5f6c2d141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- rekey_on_member - handle undefined positional arguments better.

@ -36,7 +36,10 @@ You should return errors encountered during plugin execution by raising ``Ansibl
except Exception as e:
raise AnsibleError('Something happened, this was original exception: %s' % to_native(e))
Since Ansible evaluates variables only when they are needed, filter and test plugins should propagate the exceptions ``jinja2.exceptions.UndefinedError`` and ``AnsibleUndefinedVariable`` to ensure undefined variables are only fatal when necessary.
Check the different `AnsibleError objects <https://github.com/ansible/ansible/blob/devel/lib/ansible/errors/__init__.py>`_ and see which one applies best to your situation.
Check the section on the specific plugin type you're developing for type-specific error handling details.
String encoding
===============
@ -306,6 +309,17 @@ Filter plugins manipulate data. They are a feature of Jinja2 and are also availa
Filter plugins do not use the standard configuration and documentation system described above.
Since Ansible evaluates variables only when they are needed, filter plugins should propagate the exceptions ``jinja2.exceptions.UndefinedError`` and ``AnsibleUndefinedVariable`` to ensure undefined variables are only fatal when necessary.
.. code-block:: python
try:
cause_an_exception(with_undefined_variable)
except jinja2.exceptions.UndefinedError as e:
raise AnsibleUndefinedVariable("Something happened, this was the original exception: %s" % to_native(e))
except Exception as e:
raise AnsibleFilterError("Something happened, this was the original exception: %s" % to_native(e))
For example filter plugins, see the source code for the `filter plugins included with Ansible Core <https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/filter>`_.
.. _developing_inventory_plugins:
@ -433,6 +447,17 @@ Test plugins verify data. They are a feature of Jinja2 and are also available in
Test plugins do not use the standard configuration and documentation system described above.
Since Ansible evaluates variables only when they are needed, test plugins should propagate the exceptions ``jinja2.exceptions.UndefinedError`` and ``AnsibleUndefinedVariable`` to ensure undefined variables are only fatal when necessary.
.. code-block:: python
try:
cause_an_exception(with_undefined_variable)
except jinja2.exceptions.UndefinedError as e:
raise AnsibleUndefinedVariable("Something happened, this was the original exception: %s" % to_native(e))
except Exception as e:
raise AnsibleFilterError("Something happened, this was the original exception: %s" % to_native(e))
For example test plugins, see the source code for the `test plugins included with Ansible Core <https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/test>`_.
.. _developing_vars_plugins:

@ -210,6 +210,9 @@ def rekey_on_member(data, key, duplicates='error'):
new_obj = {}
# Ensure the positional args are defined - raise jinja2.exceptions.UndefinedError if not
bool(data) and bool(key)
if isinstance(data, Mapping):
iterate_over = data.values()
elif isinstance(data, Iterable) and not isinstance(data, (text_type, binary_type)):

@ -301,6 +301,18 @@
- rekey_on_member_exc5_res is failed
- '"is not unique, cannot correctly turn into dict" in rekey_on_member_exc5_res.msg'
- name: test undefined positional args for rekey_on_member are properly handled
vars:
all_vars: "{{ hostvars[inventory_hostname] }}"
test_var: "{{ all_vars.foo }}"
block:
- include_vars:
file: defined_later.yml
- assert:
that: "test_var == 'test'"
- assert:
that: "rekeyed == {'value': {'test': 'value'}}"
# TODO: For some reason, the coverage tool isn't accounting for the last test
# so add another "last test" to fake it...
- assert:

@ -0,0 +1,3 @@
do_rekey:
- test: value
rekeyed: "{{ do_rekey | rekey_on_member(defined_later) }}"
Loading…
Cancel
Save