From fc71cde7d3f5393e402bee7e8e4f6fc7d22afdad Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 30 Nov 2018 22:04:39 -0500 Subject: [PATCH] Yaml inventory more tolerant (#48883) * make yaml inv more tolerant to comments * add tests for bad inventory processing fixes #47254 --- .../yaml_inventory_more_tolerant.yml | 2 + lib/ansible/plugins/inventory/yaml.py | 8 ++- .../targets/inventory_yaml/aliases | 1 + .../targets/inventory_yaml/empty.json | 10 +++ .../targets/inventory_yaml/runme.sh | 4 ++ .../targets/inventory_yaml/success.json | 61 +++++++++++++++++++ .../targets/inventory_yaml/test.yml | 27 ++++++++ 7 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/yaml_inventory_more_tolerant.yml create mode 100644 test/integration/targets/inventory_yaml/aliases create mode 100644 test/integration/targets/inventory_yaml/empty.json create mode 100755 test/integration/targets/inventory_yaml/runme.sh create mode 100644 test/integration/targets/inventory_yaml/success.json create mode 100644 test/integration/targets/inventory_yaml/test.yml diff --git a/changelogs/fragments/yaml_inventory_more_tolerant.yml b/changelogs/fragments/yaml_inventory_more_tolerant.yml new file mode 100644 index 00000000000..e301fa3bd92 --- /dev/null +++ b/changelogs/fragments/yaml_inventory_more_tolerant.yml @@ -0,0 +1,2 @@ +bugfixes: + - make YAML inventory more tolerant to comments/empty/None entries diff --git a/lib/ansible/plugins/inventory/yaml.py b/lib/ansible/plugins/inventory/yaml.py index da8cbfafaef..d013fc48374 100644 --- a/lib/ansible/plugins/inventory/yaml.py +++ b/lib/ansible/plugins/inventory/yaml.py @@ -135,7 +135,13 @@ class InventoryModule(BaseFileInventoryPlugin): for key in group_data: - if key == 'vars': + if not isinstance(group_data[key], (MutableMapping, NoneType)): + self.display.warning('Skipping key (%s) in group (%s) as it is not a mapping, it is a %s' % (key, group, type(group_data[key]))) + continue + + if isinstance(group_data[key], NoneType): + self.display.vvv('Skipping empty key (%s) in group (%s)' % (key, group)) + elif key == 'vars': for var in group_data[key]: self.inventory.set_variable(group, var, group_data[key][var]) elif key == 'children': diff --git a/test/integration/targets/inventory_yaml/aliases b/test/integration/targets/inventory_yaml/aliases new file mode 100644 index 00000000000..a6dafcf8cd8 --- /dev/null +++ b/test/integration/targets/inventory_yaml/aliases @@ -0,0 +1 @@ +shippable/posix/group1 diff --git a/test/integration/targets/inventory_yaml/empty.json b/test/integration/targets/inventory_yaml/empty.json new file mode 100644 index 00000000000..e1ae0684631 --- /dev/null +++ b/test/integration/targets/inventory_yaml/empty.json @@ -0,0 +1,10 @@ +{ + "_meta": { + "hostvars": {} + }, + "all": { + "children": [ + "ungrouped" + ] + } +} diff --git a/test/integration/targets/inventory_yaml/runme.sh b/test/integration/targets/inventory_yaml/runme.sh new file mode 100755 index 00000000000..b82f499d162 --- /dev/null +++ b/test/integration/targets/inventory_yaml/runme.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# handle empty/commented out group keys correctly https://github.com/ansible/ansible/issues/47254 +ANSIBLE_VERBOSITY=0 diff -w <(ansible-inventory -i ./test.yml --list) success.json diff --git a/test/integration/targets/inventory_yaml/success.json b/test/integration/targets/inventory_yaml/success.json new file mode 100644 index 00000000000..a8b15f96c34 --- /dev/null +++ b/test/integration/targets/inventory_yaml/success.json @@ -0,0 +1,61 @@ +{ + "_meta": { + "hostvars": { + "alice": { + "status": "single" + }, + "bobby": { + "in_trouble": true, + "popular": false + }, + "cindy": { + "in_trouble": true, + "popular": true + }, + "greg": { + "in_trouble": true, + "popular": true + }, + "jan": { + "in_trouble": true, + "popular": false + }, + "marcia": { + "in_trouble": true, + "popular": true + }, + "peter": { + "in_trouble": true, + "popular": false + } + } + }, + "all": { + "children": [ + "cousins", + "kids", + "the-maid", + "ungrouped" + ] + }, + "cousins": { + "children": [ + "redheads" + ] + }, + "kids": { + "hosts": [ + "bobby", + "cindy", + "greg", + "jan", + "marcia", + "peter" + ] + }, + "the-maid": { + "hosts": [ + "alice" + ] + } +} diff --git a/test/integration/targets/inventory_yaml/test.yml b/test/integration/targets/inventory_yaml/test.yml new file mode 100644 index 00000000000..9755396aae0 --- /dev/null +++ b/test/integration/targets/inventory_yaml/test.yml @@ -0,0 +1,27 @@ +all: + children: + kids: + hosts: + marcia: + popular: True + jan: + popular: False + cindy: + popular: True + greg: + popular: True + peter: + popular: False + bobby: + popular: False + vars: + in_trouble: True + cousins: + children: + redheads: + hosts: + #oliver: # this used to cause an error and deliver incomplete inventory + the-maid: + hosts: + alice: + status: single