diff --git a/changelogs/fragments/fix_inventory_source_parse_error_handling.yml b/changelogs/fragments/fix_inventory_source_parse_error_handling.yml new file mode 100644 index 00000000000..6782a7529f7 --- /dev/null +++ b/changelogs/fragments/fix_inventory_source_parse_error_handling.yml @@ -0,0 +1,2 @@ +bugfixes: + - Correct the inventory source error parse handling, specifically make the config INVENTORY_ANY_UNPARSED_IS_FAILED work as expected. diff --git a/lib/ansible/inventory/manager.py b/lib/ansible/inventory/manager.py index 5606b2655ee..d908b74e734 100644 --- a/lib/ansible/inventory/manager.py +++ b/lib/ansible/inventory/manager.py @@ -305,19 +305,24 @@ class InventoryManager(object): failures.append({'src': source, 'plugin': plugin_name, 'exc': AnsibleError(e), 'tb': tb}) else: display.vvv("%s declined parsing %s as it did not pass its verify_file() method" % (plugin_name, source)) - else: - if not parsed and failures: + + if not parsed: + # only warn/error if NOT using the default or using it and the file is present + # TODO: handle 'non file' inventorya and detect vs hardcode default + if source != '/etc/ansible/hosts' or os.path.exists(source): + + if failures: # only if no plugin processed files should we show errors. for fail in failures: display.warning(u'\n* Failed to parse %s with %s plugin: %s' % (to_text(fail['src']), fail['plugin'], to_text(fail['exc']))) if 'tb' in fail: display.vvv(to_text(fail['tb'])) - if C.INVENTORY_ANY_UNPARSED_IS_FAILED: - raise AnsibleError(u'Completely failed to parse inventory source %s' % (source)) - if not parsed: - if source != '/etc/ansible/hosts' or os.path.exists(source): - # only warn if NOT using the default and if using it, only if the file is present - display.warning("Unable to parse %s as an inventory source" % source) + + # final erorr/warning on inventory source failure + if C.INVENTORY_ANY_UNPARSED_IS_FAILED: + raise AnsibleError(u'Completely failed to parse inventory source %s' % (source)) + else: + display.warning("Unable to parse %s as an inventory source" % source) # clear up, jic self._inventory.current_source = None diff --git a/test/integration/targets/inventory/runme.sh b/test/integration/targets/inventory/runme.sh index 3cd533cde7b..70565a99a3c 100755 --- a/test/integration/targets/inventory/runme.sh +++ b/test/integration/targets/inventory/runme.sh @@ -34,3 +34,15 @@ ansible-playbook -i ../../inventory --limit @"${empty_limit_file}" playbook.yml ansible-playbook -i ../../inventory "$@" strategy.yml ANSIBLE_TRANSFORM_INVALID_GROUP_CHARS=always ansible-playbook -i ../../inventory "$@" strategy.yml ANSIBLE_TRANSFORM_INVALID_GROUP_CHARS=never ansible-playbook -i ../../inventory "$@" strategy.yml + +# test parse inventory fail is not an error per config +ANSIBLE_INVENTORY_UNPARSED_FAILED=False ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED=False ansible -m ping localhost -i /idontexist "$@" + +# test no inventory parse is an error with var +[ "$(ANSIBLE_INVENTORY_UNPARSED_FAILED=True ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED=False ansible -m ping localhost -i /idontexist)" != "0" ] + +# test single inventory no parse is not an error with var +ANSIBLE_INVENTORY_UNPARSED_FAILED=True ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED=False ansible -m ping localhost -i /idontexist -i ../../invenotory "$@" + +# test single inventory no parse is an error with any var +[ "$(ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED=True ansible -m ping localhost -i /idontexist -i ../../invenotory)" != "0" ]