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 28b42131ed1..1b806029664 100644 --- a/lib/ansible/plugins/vars/host_group_vars.py +++ b/lib/ansible/plugins/vars/host_group_vars.py @@ -54,7 +54,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 @@ -76,7 +76,10 @@ class VarsModule(BaseVarsPlugin): for found in found_files: new_data = loader.load_from_file(found, cache=True, unsafe=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("Could not process '%s'." % found, orig_exc=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 5e21cb36133..b12ad9980dd 100644 --- a/lib/ansible/utils/vars.py +++ b/lib/ansible/utils/vars.py @@ -73,9 +73,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("failed to combine variables, expected dicts but got a '{0}' and a '{1}'.".format(a.__class__.__name__, 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 8282190e4e0..a450f36fdf1 100644 --- a/lib/ansible/vars/manager.py +++ b/lib/ansible/vars/manager.py @@ -63,7 +63,7 @@ def preprocess_vars(a): for item in data: if not isinstance(item, MutableMapping): - raise AnsibleError("variable files must contain either a dictionary of variables, or a list of dictionaries. Got: %s (%s)" % (a, type(a))) + raise AnsibleError("variable files must contain either a dictionary of variables, or a list of dictionaries. Got: %s " % (type(a))) return data @@ -364,6 +364,8 @@ class VariableManager: continue except AnsibleParserError: raise + except AnsibleError as e: + raise AnsibleError("Invalid vars_file '%s'." % found_file, orig_exc=e) else: # if include_delegate_to is set to False or we don't have a host, we ignore the missing # vars file here because we're working on a delegated host or require host vars, see NOTE above 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