diff --git a/changelogs/fragments/varloaderror.yml b/changelogs/fragments/varloaderror.yml new file mode 100644 index 00000000000..1d5a706da69 --- /dev/null +++ b/changelogs/fragments/varloaderror.yml @@ -0,0 +1,2 @@ +bugfixes: + - Variable loading now uses file source instead of variables when invalidly formmated vars file is loaded. diff --git a/lib/ansible/plugins/vars/host_group_vars.py b/lib/ansible/plugins/vars/host_group_vars.py index 546ffed402c..4ece1e77c1c 100644 --- a/lib/ansible/plugins/vars/host_group_vars.py +++ b/lib/ansible/plugins/vars/host_group_vars.py @@ -53,7 +53,7 @@ DOCUMENTATION = """ """ import os -from ansible.errors import AnsibleParserError +from ansible.errors import AnsibleError, AnsibleParserError from ansible.module_utils.common.text.converters import to_native from ansible.plugins.vars import BaseVarsPlugin from ansible.utils.path import basedir @@ -74,7 +74,10 @@ class VarsModule(BaseVarsPlugin): for found in found_files: new_data = loader.load_from_file(found, cache='all', unsafe=True, trusted_as_template=True) if new_data: # ignore empty files - data = combine_vars(data, new_data) + try: + data = combine_vars(data, new_data) + except AnsibleError as e: + raise AnsibleParserError(f"Could not process {found!r}.") from e return data def get_vars(self, loader, path, entities, cache=True): diff --git a/lib/ansible/utils/vars.py b/lib/ansible/utils/vars.py index 363b4c2777f..c6bba3e8304 100644 --- a/lib/ansible/utils/vars.py +++ b/lib/ansible/utils/vars.py @@ -72,9 +72,7 @@ def _validate_mutable_mappings(a, b): myvars.append(dumps(x)) except Exception: myvars.append(to_native(x)) - raise AnsibleError("failed to combine variables, expected dicts but got a '{0}' and a '{1}': \n{2}\n{3}".format( - a.__class__.__name__, b.__class__.__name__, myvars[0], myvars[1]) - ) + raise AnsibleError(f"failed to combine variables, expected dicts but got a '{a.__class__.__name__}' and a '{b.__class__.__name__}'.") def combine_vars(a, b, merge=None): diff --git a/lib/ansible/vars/manager.py b/lib/ansible/vars/manager.py index 7af718e558b..2709ef54fb0 100644 --- a/lib/ansible/vars/manager.py +++ b/lib/ansible/vars/manager.py @@ -345,18 +345,16 @@ class VariableManager: data = preprocess_vars(self._loader.load_from_file(found_file, unsafe=True, cache='vaulted', trusted_as_template=True)) if data is not None: for item in data: - all_vars = _combine_and_track(all_vars, item, "play vars_files from '%s'" % vars_file) + all_vars = _combine_and_track(all_vars, item, f"play vars_files from {vars_file!r}") display.vvv(f"Read `vars_file` {found_file!r}.") break except AnsibleFileNotFound: # we continue on loader failures continue - except AnsibleParserError: + except (AnsibleParserError, AnsibleUndefinedVariable): raise - except AnsibleUndefinedVariable: - raise - except Exception as ex: - raise AnsibleParserError(f"Error reading `vars_files` file {vars_file!r}.", obj=vars_file) from ex + except AnsibleError as e: + raise AnsibleError(f"Invalid vars_files file {found_file!r}.") from e except AnsibleUndefinedVariable as ex: if host is not None: diff --git a/test/integration/targets/var_blending/error_handling.yml b/test/integration/targets/var_blending/error_handling.yml new file mode 100644 index 00000000000..f30070acea2 --- /dev/null +++ b/test/integration/targets/var_blending/error_handling.yml @@ -0,0 +1,14 @@ +- hosts: all + name: test vault errors + gather_facts: false + tasks: + + - name: bad included vault + include_vars: + file: vars/bad_vault.yml + tags: includevault, never + no_log: false + + - name: Show bad vault contents ... if i get here, it was a good vault! + debug: + msg: "{{ test_password }} {{ jdbc_test_password }} {{ api_test_password }}" diff --git a/test/integration/targets/var_blending/group_vars/local b/test/integration/targets/var_blending/group_vars/local/main.yml similarity index 100% rename from test/integration/targets/var_blending/group_vars/local rename to test/integration/targets/var_blending/group_vars/local/main.yml diff --git a/test/integration/targets/var_blending/runme.sh b/test/integration/targets/var_blending/runme.sh index d0cf7f090cb..4454e470a70 100755 --- a/test/integration/targets/var_blending/runme.sh +++ b/test/integration/targets/var_blending/runme.sh @@ -3,3 +3,12 @@ set -eux ansible-playbook test_var_blending.yml -i inventory -e @test_vars.yml -v "$@" + +# check bad vault file erros +[ "$(ansible-playbook error_handling.yml -i inventory --vault-password-file supersecretvaultsecret -e @vars/bad_vault.yml 2>&1 | grep -c 'dummy')" -eq "0" ] +[ "$(ansible-playbook error_handling.yml -i inventory --vault-password-file supersecretvaultsecret --tags includevault 2>&1 | grep -c 'dummy')" -eq "0" ] + +# setup group file for bad vault tests +trap 'rm group_vars/local/bad_vault.yml' EXIT +ln -s "${PWD}/vars/bad_vault.yml" group_vars/local/ +[ "$(ansible-playbook error_handling.yml -i inventory --vault-password-file supersecretvaultsecret 2>&1 | grep -c 'dummy')" -eq "0" ] diff --git a/test/integration/targets/var_blending/supersecretvaultsecret b/test/integration/targets/var_blending/supersecretvaultsecret new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/test/integration/targets/var_blending/supersecretvaultsecret @@ -0,0 +1 @@ +test diff --git a/test/integration/targets/var_blending/vars/bad_vault.yml b/test/integration/targets/var_blending/vars/bad_vault.yml new file mode 100644 index 00000000000..3a79cd284a1 --- /dev/null +++ b/test/integration/targets/var_blending/vars/bad_vault.yml @@ -0,0 +1,10 @@ +$ANSIBLE_VAULT;1.1;AES256 +65616232393566313961313431386633366639386133383230656230333934656366363636393730 +3266313739663639636161373033333865303461343936370a356463393635623664316464353061 +63396639643331303231616336663562303764653733326532316139643036336436396565653531 +3836383032626262620a316666363164626537346663383333376330623339633762363932613537 +32663462613532646139633364363136656132346661373331363164356162313762343337393666 +38653864363938316534333438643761623264376535336233656630376430346366333262313532 +33366662663137306431623464303561383730336466613166386136656364306436343032343631 +37396234633230626263373435623731616664653939343630393935626461396230663734373861 +3634