From 276358c8850a19ba5d22108aba5fc7a898116d05 Mon Sep 17 00:00:00 2001 From: Abhijit Menon-Sen Date: Wed, 6 Jun 2018 09:28:58 +0530 Subject: [PATCH] Introduce inventory.any_unparsed_is_failed configuration setting (#41171) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the process of building up the inventory by parsing each inventory source with each available inventory plugin, there are three kinds of possible errors (listed in order from earliest to latest): 1. One source could not be parsed by a particular plugin. 2. One source could not be parsed by any available plugin. 3. ALL sources could not be parsed by any available plugin. The errors in (1) are a part of normal operation, e.g., the script plugin is expected to fail to parse an ini-format source, and we will ignore that error and try the next plugin. There is currently no way to control this, and no known compelling use-case for a setting to control it. This commit does not make any changes here. We implement "any_unparsed_is_failed" to handle (2) above. If enabled, this requires that every available source be parsed validly by at least one plugin. In an inventory comprising a static hosts file and ec2.py, this setting will cause a fatal error if ec2.py fails (a situation that attracted only a warning earlier). We clarify that the existing "unparsed_is_failed=true" setting causes a fatal error only in (3) above, i.e., if NO inventory source could be parsed. In other words, if there is ANY valid source in the inventory (e.g., an ini-format static file), no combination of errors and the setting will cause a fatal error. If you want to execute your playbooks when your inventory is… (a) complete, use "any_unparsed_is_failed=true". (b) not empty, use "unparsed_is_failed=true". The "unparsed_is_failed" setting should be renamed to "all_unparsed_is_failed", but this commit does not do so. Fixes #40512 Fixes #40996 --- .../fragments/any_unparsed_is_failed.yaml | 5 +++++ lib/ansible/config/base.yml | 17 ++++++++++++++++- lib/ansible/inventory/manager.py | 2 ++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/any_unparsed_is_failed.yaml diff --git a/changelogs/fragments/any_unparsed_is_failed.yaml b/changelogs/fragments/any_unparsed_is_failed.yaml new file mode 100644 index 0000000000..465f4e2772 --- /dev/null +++ b/changelogs/fragments/any_unparsed_is_failed.yaml @@ -0,0 +1,5 @@ +--- +minor_changes: + - Added inventory.any_unparsed_is_failed configuration setting. In an + inventory with a static hosts file and (say) ec2.py, enabling this + setting will cause a failure instead of a warning if ec2.py fails. diff --git a/lib/ansible/config/base.yml b/lib/ansible/config/base.yml index 9911f72f64..b555d6083b 100644 --- a/lib/ansible/config/base.yml +++ b/lib/ansible/config/base.yml @@ -1375,6 +1375,18 @@ HOST_KEY_CHECKING: ini: - {key: host_key_checking, section: defaults} type: boolean +INVENTORY_ANY_UNPARSED_IS_FAILED: + name: Controls whether any unparseable inventory source is a fatal error + default: False + description: > + If 'true', it is a fatal error when any given inventory source + cannot be successfully parsed by any available inventory plugin; + otherwise, this situation only attracts a warning. + type: boolean + env: [{name: ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED}] + ini: + - {key: any_unparsed_is_failed, section: inventory} + version_added: "2.7" INVENTORY_ENABLED: name: Active Inventory plugins default: ['host_list', 'script', 'yaml', 'ini', 'auto'] @@ -1412,7 +1424,10 @@ INVENTORY_IGNORE_PATTERNS: INVENTORY_UNPARSED_IS_FAILED: name: Unparsed Inventory failure default: False - description: If 'true' unparsed inventory sources become fatal errors, they are warnings otherwise. + description: > + If 'true' it is a fatal error if every single potential inventory + source fails to parse, otherwise this situation will only attract a + warning. env: [{name: ANSIBLE_INVENTORY_UNPARSED_FAILED}] ini: - {key: unparsed_is_failed, section: inventory} diff --git a/lib/ansible/inventory/manager.py b/lib/ansible/inventory/manager.py index 0772cff636..29f95de626 100644 --- a/lib/ansible/inventory/manager.py +++ b/lib/ansible/inventory/manager.py @@ -285,6 +285,8 @@ class InventoryManager(object): display.warning(u'\n* Failed to parse %s with %s plugin: %s' % (to_text(fail['src']), fail['plugin'], to_text(fail['exc']))) if hasattr(fail['exc'], 'tb'): display.vvv(to_text(fail['exc'].tb)) + if C.INVENTORY_ANY_UNPARSED_IS_FAILED: + raise AnsibleError(u'Completely failed to parse inventory source %s' % (to_text(source))) if not parsed: display.warning("Unable to parse %s as an inventory source" % to_text(source))