fix using templated values for include/import role FA (#80320)

* fix using templated values for include/import role options 'public', 'allow_duplicates', and 'rolespec_validate'

* pass templated values without changing the instance

* Fix templating by setting always_post_validate to True and calling IncludeRole.post_validate() instead

ci_complete

* add changelog
pull/80375/head
Sloane Hertel 2 years ago committed by GitHub
parent a45dd2a01c
commit 666188892e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- roles - Fix templating ``public``, ``allow_duplicates`` and ``rolespec_validate`` (https://github.com/ansible/ansible/issues/80304).

@ -307,6 +307,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
# template the role name now, if needed # template the role name now, if needed
all_vars = variable_manager.get_vars(play=play, task=ir) all_vars = variable_manager.get_vars(play=play, task=ir)
templar = Templar(loader=loader, variables=all_vars) templar = Templar(loader=loader, variables=all_vars)
ir.post_validate(templar=templar)
ir._role_name = templar.template(ir._role_name) ir._role_name = templar.template(ir._role_name)
# uses compiled list from object # uses compiled list from object

@ -187,6 +187,7 @@ class IncludedFile:
role_name = templar.template(role_name) role_name = templar.template(role_name)
new_task = original_task.copy() new_task = original_task.copy()
new_task.post_validate(templar=templar)
new_task._role_name = role_name new_task._role_name = role_name
for from_arg in new_task.FROM_ARGS: for from_arg in new_task.FROM_ARGS:
if from_arg in include_args: if from_arg in include_args:

@ -51,9 +51,9 @@ class IncludeRole(TaskInclude):
# ATTRIBUTES # ATTRIBUTES
# private as this is a 'module options' vs a task property # private as this is a 'module options' vs a task property
allow_duplicates = NonInheritableFieldAttribute(isa='bool', default=True, private=True) allow_duplicates = NonInheritableFieldAttribute(isa='bool', default=True, private=True, always_post_validate=True)
public = NonInheritableFieldAttribute(isa='bool', default=False, private=True) public = NonInheritableFieldAttribute(isa='bool', default=False, private=True, always_post_validate=True)
rolespec_validate = NonInheritableFieldAttribute(isa='bool', default=True) rolespec_validate = NonInheritableFieldAttribute(isa='bool', default=True, private=True, always_post_validate=True)
def __init__(self, block=None, role=None, task_include=None): def __init__(self, block=None, role=None, task_include=None):

@ -0,0 +1,7 @@
argument_specs:
main:
short_description: The main entry point for dup_allowed_role
options:
optional_int:
type: int
description: An integer value

@ -121,6 +121,11 @@ ansible-playbook valid_include_keywords/playbook.yml "$@"
ansible-playbook tasks/test_allow_single_role_dup.yml 2>&1 | tee test_allow_single_role_dup.out ansible-playbook tasks/test_allow_single_role_dup.yml 2>&1 | tee test_allow_single_role_dup.out
test "$(grep -c 'ok=3' test_allow_single_role_dup.out)" = 1 test "$(grep -c 'ok=3' test_allow_single_role_dup.out)" = 1
# test templating public, allow_duplicates, and rolespec_validate
ansible-playbook tasks/test_templating_IncludeRole_FA.yml 2>&1 | tee IncludeRole_FA_template.out
test "$(grep -c 'ok=4' IncludeRole_FA_template.out)" = 1
test "$(grep -c 'failed=0' IncludeRole_FA_template.out)" = 1
# https://github.com/ansible/ansible/issues/66764 # https://github.com/ansible/ansible/issues/66764
ANSIBLE_HOST_PATTERN_MISMATCH=error ansible-playbook empty_group_warning/playbook.yml ANSIBLE_HOST_PATTERN_MISMATCH=error ansible-playbook empty_group_warning/playbook.yml

@ -0,0 +1,28 @@
---
- name: test templating allow_duplicates, public, and rolespec_validate
hosts: localhost
gather_facts: false
tasks:
- name: prevent duplicate roles with a templated value
block:
- import_role:
name: dup_allowed_role
allow_duplicates: "{{ False | bool }}"
- import_role:
name: dup_allowed_role
allow_duplicates: "{{ False | bool }}"
- name: prevent leaky vars with a templated value
include_role:
name: role1
public: "{{ False | bool }}"
- assert:
that:
- where_am_i_defined is undefined
- name: skip role argspec validation with a templated value
include_role:
name: role_with_argspec
rolespec_validate: "{{ False | bool }}"
vars:
optional_int: wrong_type
Loading…
Cancel
Save