From 08ba838a8e54baa476c8c33d55e1adc41e1b83d6 Mon Sep 17 00:00:00 2001 From: Sloane Hertel <19572925+s-hertel@users.noreply.github.com> Date: Mon, 11 Jan 2021 18:20:48 -0500 Subject: [PATCH] [2.10] Pass the top level dictionaries to combine_vars (#72979) (#73146) combine_vars uses dict.update() to replace keys (cherry picked from commit 5e03e322de5b43b69c8aad5c0cb92e82ce0f3d17) * Add tests for merging and replacing vars from inventory sources (#73181) (cherry picked from commit 9de2da8a7ee1c0219b804b6afc7b090101106743) --- ...2979-fix-inventory-merge-hash-replace.yaml | 2 + lib/ansible/inventory/group.py | 2 +- lib/ansible/inventory/host.py | 2 +- test/integration/targets/hash/runme.sh | 3 ++ test/integration/targets/hash/test_inv1.yml | 10 +++++ test/integration/targets/hash/test_inv2.yml | 8 ++++ .../targets/hash/test_inventory_hash.yml | 41 +++++++++++++++++++ 7 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 changelogs/fragments/72979-fix-inventory-merge-hash-replace.yaml create mode 100644 test/integration/targets/hash/test_inv1.yml create mode 100644 test/integration/targets/hash/test_inv2.yml create mode 100644 test/integration/targets/hash/test_inventory_hash.yml diff --git a/changelogs/fragments/72979-fix-inventory-merge-hash-replace.yaml b/changelogs/fragments/72979-fix-inventory-merge-hash-replace.yaml new file mode 100644 index 00000000000..4b7b24720af --- /dev/null +++ b/changelogs/fragments/72979-fix-inventory-merge-hash-replace.yaml @@ -0,0 +1,2 @@ +bugfixes: + - inventory - pass the vars dictionary to combine_vars instead of an individual key's value (https://github.com/ansible/ansible/issues/72975). diff --git a/lib/ansible/inventory/group.py b/lib/ansible/inventory/group.py index 0dd91bb76dd..e7878d35951 100644 --- a/lib/ansible/inventory/group.py +++ b/lib/ansible/inventory/group.py @@ -248,7 +248,7 @@ class Group: self.set_priority(int(value)) else: if key in self.vars and isinstance(self.vars[key], MutableMapping) and isinstance(value, Mapping): - self.vars[key] = combine_vars(self.vars[key], value) + self.vars = combine_vars(self.vars, {key: value}) else: self.vars[key] = value diff --git a/lib/ansible/inventory/host.py b/lib/ansible/inventory/host.py index 7ad300790d0..a3e41f53b65 100644 --- a/lib/ansible/inventory/host.py +++ b/lib/ansible/inventory/host.py @@ -143,7 +143,7 @@ class Host: def set_variable(self, key, value): if key in self.vars and isinstance(self.vars[key], MutableMapping) and isinstance(value, Mapping): - self.vars[key] = combine_vars(self.vars[key], value) + self.vars = combine_vars(self.vars, {key: value}) else: self.vars[key] = value diff --git a/test/integration/targets/hash/runme.sh b/test/integration/targets/hash/runme.sh index 9448e4e098b..3689d83b8a1 100755 --- a/test/integration/targets/hash/runme.sh +++ b/test/integration/targets/hash/runme.sh @@ -6,3 +6,6 @@ JSON_ARG='{"test_hash":{"extra_args":"this is an extra arg"}}' ANSIBLE_HASH_BEHAVIOUR=replace ansible-playbook test_hash.yml -i ../../inventory -v "$@" -e "${JSON_ARG}" ANSIBLE_HASH_BEHAVIOUR=merge ansible-playbook test_hash.yml -i ../../inventory -v "$@" -e "${JSON_ARG}" + +ANSIBLE_HASH_BEHAVIOUR=replace ansible-playbook test_inventory_hash.yml -i test_inv1.yml -i test_inv2.yml -v "$@" +ANSIBLE_HASH_BEHAVIOUR=merge ansible-playbook test_inventory_hash.yml -i test_inv1.yml -i test_inv2.yml -v "$@" diff --git a/test/integration/targets/hash/test_inv1.yml b/test/integration/targets/hash/test_inv1.yml new file mode 100644 index 00000000000..02bd017f778 --- /dev/null +++ b/test/integration/targets/hash/test_inv1.yml @@ -0,0 +1,10 @@ +all: + hosts: + host1: + test_inventory_host_hash: + host_var1: "inventory 1" + host_var2: "inventory 1" + vars: + test_inventory_group_hash: + group_var1: "inventory 1" + group_var2: "inventory 1" diff --git a/test/integration/targets/hash/test_inv2.yml b/test/integration/targets/hash/test_inv2.yml new file mode 100644 index 00000000000..6529b9333ed --- /dev/null +++ b/test/integration/targets/hash/test_inv2.yml @@ -0,0 +1,8 @@ +all: + hosts: + host1: + test_inventory_host_hash: + host_var1: "inventory 2" + vars: + test_inventory_group_hash: + group_var1: "inventory 2" diff --git a/test/integration/targets/hash/test_inventory_hash.yml b/test/integration/targets/hash/test_inventory_hash.yml new file mode 100644 index 00000000000..1091b135025 --- /dev/null +++ b/test/integration/targets/hash/test_inventory_hash.yml @@ -0,0 +1,41 @@ +--- +- hosts: localhost + gather_facts: no + vars: + host_hash_merged: {'host_var1': 'inventory 2', 'host_var2': 'inventory 1'} + host_hash_replaced: {'host_var1': 'inventory 2'} + group_hash_merged: {'group_var1': 'inventory 2', 'group_var2': 'inventory 1'} + group_hash_replaced: {'group_var1': 'inventory 2'} + tasks: + + - name: debug hash behaviour result + debug: + var: "{{ lookup('env', 'ANSIBLE_HASH_BEHAVIOUR') }}" + verbosity: 2 + + - name: assert hash behaviour is merge or replace + assert: + that: + - lookup('env', 'ANSIBLE_HASH_BEHAVIOUR') in ('merge', 'replace') + + - name: debug test_inventory_host_hash + debug: + var: hostvars['host1']['test_inventory_host_hash'] + verbosity: 2 + + - name: debug test_inventory_group_hash + debug: + var: test_inventory_group_hash + verbosity: 2 + + - assert: + that: + - hostvars['host1']['test_inventory_host_hash'] == host_hash_replaced + - test_inventory_group_hash == group_hash_replaced + when: "lookup('env', 'ANSIBLE_HASH_BEHAVIOUR') == 'replace'" + + - assert: + that: + - hostvars['host1']['test_inventory_host_hash'] == host_hash_merged + - test_inventory_group_hash == group_hash_merged + when: "lookup('env', 'ANSIBLE_HASH_BEHAVIOUR') == 'merge'"