diff --git a/changelogs/fragments/79021-dont-squash-in-validate.yml b/changelogs/fragments/79021-dont-squash-in-validate.yml new file mode 100644 index 00000000000..52a1e30e03c --- /dev/null +++ b/changelogs/fragments/79021-dont-squash-in-validate.yml @@ -0,0 +1,3 @@ +bugfixes: +- keyword inheritance - Ensure that we do not squash keywords in validate + (https://github.com/ansible/ansible/issues/79021) diff --git a/lib/ansible/playbook/base.py b/lib/ansible/playbook/base.py index 9daccbbd714..5504645a126 100644 --- a/lib/ansible/playbook/base.py +++ b/lib/ansible/playbook/base.py @@ -211,7 +211,7 @@ class FieldAttributeBase: method(attribute, name, getattr(self, name)) else: # and make sure the attribute is of the type it should be - value = getattr(self, name) + value = getattr(self, f'_{name}', Sentinel) if value is not None: if attribute.isa == 'string' and isinstance(value, (list, dict)): raise AnsibleParserError( diff --git a/lib/ansible/playbook/block.py b/lib/ansible/playbook/block.py index 216d04e856e..fabaf7f7688 100644 --- a/lib/ansible/playbook/block.py +++ b/lib/ansible/playbook/block.py @@ -298,8 +298,10 @@ class Block(Base, Conditional, CollectionSearch, Taggable): ''' Generic logic to get the attribute or parent attribute for a block value. ''' - extend = self.fattributes.get(attr).extend - prepend = self.fattributes.get(attr).prepend + fattr = self.fattributes[attr] + + extend = fattr.extend + prepend = fattr.prepend try: # omit self, and only get parent values diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py index d0a4c6ecc8d..50ac5df7f48 100644 --- a/lib/ansible/playbook/task.py +++ b/lib/ansible/playbook/task.py @@ -461,8 +461,10 @@ class Task(Base, Conditional, Taggable, CollectionSearch): ''' Generic logic to get the attribute or parent attribute for a task value. ''' - extend = self.fattributes.get(attr).extend - prepend = self.fattributes.get(attr).prepend + fattr = self.fattributes[attr] + + extend = fattr.extend + prepend = fattr.prepend try: # omit self, and only get parent values diff --git a/test/integration/targets/keyword_inheritance/aliases b/test/integration/targets/keyword_inheritance/aliases new file mode 100644 index 00000000000..a6a33411a34 --- /dev/null +++ b/test/integration/targets/keyword_inheritance/aliases @@ -0,0 +1,3 @@ +shippable/posix/group4 +context/controller +needs/target/setup_test_user diff --git a/test/integration/targets/keyword_inheritance/roles/whoami/tasks/main.yml b/test/integration/targets/keyword_inheritance/roles/whoami/tasks/main.yml new file mode 100644 index 00000000000..80252c0354a --- /dev/null +++ b/test/integration/targets/keyword_inheritance/roles/whoami/tasks/main.yml @@ -0,0 +1,3 @@ +- command: whoami + register: result + failed_when: result.stdout_lines|first != 'ansibletest0' diff --git a/test/integration/targets/keyword_inheritance/runme.sh b/test/integration/targets/keyword_inheritance/runme.sh new file mode 100755 index 00000000000..6b78a06dc4f --- /dev/null +++ b/test/integration/targets/keyword_inheritance/runme.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -eux + +ANSIBLE_ROLES_PATH=../ ansible-playbook -i ../../inventory test.yml "$@" diff --git a/test/integration/targets/keyword_inheritance/test.yml b/test/integration/targets/keyword_inheritance/test.yml new file mode 100644 index 00000000000..886f9858ff2 --- /dev/null +++ b/test/integration/targets/keyword_inheritance/test.yml @@ -0,0 +1,8 @@ +- hosts: testhost + gather_facts: false + become_user: ansibletest0 + become: yes + roles: + - role: setup_test_user + become_user: root + - role: whoami diff --git a/test/integration/targets/omit/75692.yml b/test/integration/targets/omit/75692.yml index eaabd978819..5ba8a2df1b7 100644 --- a/test/integration/targets/omit/75692.yml +++ b/test/integration/targets/omit/75692.yml @@ -2,9 +2,11 @@ hosts: testhost gather_facts: false become: yes + # become_user needed at play level for testing this behavior become_user: nobody roles: - name: setup_test_user + become_user: root tasks: - shell: whoami register: inherited