diff --git a/changelogs/fragments/68515_include_role_vars_from.yml b/changelogs/fragments/68515_include_role_vars_from.yml new file mode 100644 index 00000000000..111ba2be5fa --- /dev/null +++ b/changelogs/fragments/68515_include_role_vars_from.yml @@ -0,0 +1,2 @@ +bugfixes: +- Strictly check string datatype for 'tasks_from', 'vars_from', 'defaults_from', and 'handlers_from' in include_role (https://github.com/ansible/ansible/issues/68515). diff --git a/lib/ansible/playbook/role_include.py b/lib/ansible/playbook/role_include.py index d1da3c94879..4e7530d7b4c 100644 --- a/lib/ansible/playbook/role_include.py +++ b/lib/ansible/playbook/role_include.py @@ -27,6 +27,7 @@ from ansible.playbook.task_include import TaskInclude from ansible.playbook.role import Role from ansible.playbook.role.include import RoleInclude from ansible.utils.display import Display +from ansible.module_utils.six import string_types __all__ = ['IncludeRole'] @@ -137,7 +138,10 @@ class IncludeRole(TaskInclude): # build options for role includes for key in my_arg_names.intersection(IncludeRole.FROM_ARGS): from_key = key.replace('_from', '') - ir._from_files[from_key] = basename(ir.args.get(key)) + args_value = ir.args.get(key) + if not isinstance(args_value, string_types): + raise AnsibleParserError('Expected a string for %s but got %s instead' % (key, type(args_value))) + ir._from_files[from_key] = basename(args_value) apply_attrs = ir.args.get('apply', {}) if apply_attrs and ir.action != 'include_role': diff --git a/test/integration/targets/include_import/role/test_include_role.yml b/test/integration/targets/include_import/role/test_include_role.yml index f3e695c1fba..e120bd8cbfc 100644 --- a/test/integration/targets/include_import/role/test_include_role.yml +++ b/test/integration/targets/include_import/role/test_include_role.yml @@ -153,13 +153,13 @@ include_role: name: "{{ host_var_role_name }}" - - name: assert that host varible for role name calls 2 diff roles + - name: assert that host variable for role name calls 2 diff roles assert: that: - _role2_result is not none when: inventory_hostname == 'testhost2' - - name: assert that host varible for role name calls 2 diff roles + - name: assert that host variable for role name calls 2 diff roles assert: that: - _role3_result is not none diff --git a/test/integration/targets/include_import/role/test_include_role_vars_from.yml b/test/integration/targets/include_import/role/test_include_role_vars_from.yml new file mode 100644 index 00000000000..f7bb4d76ef7 --- /dev/null +++ b/test/integration/targets/include_import/role/test_include_role_vars_from.yml @@ -0,0 +1,10 @@ +- name: Test include_role vars_from + hosts: testhost + vars: + role_name: role1 + tasks: + - name: Test vars_from + include_role: + name: role1 + vars_from: + - vars_1.yml diff --git a/test/integration/targets/include_import/runme.sh b/test/integration/targets/include_import/runme.sh index f72a6ebaddc..0a052a18228 100755 --- a/test/integration/targets/include_import/runme.sh +++ b/test/integration/targets/include_import/runme.sh @@ -42,6 +42,9 @@ ANSIBLE_STRATEGY='free' ansible-playbook tasks/test_include_tasks_tags.yml -i in ANSIBLE_STRATEGY='linear' ansible-playbook role/test_include_role.yml -i inventory "$@" ANSIBLE_STRATEGY='free' ansible-playbook role/test_include_role.yml -i inventory "$@" +# https://github.com/ansible/ansible/issues/68515 +ansible-playbook -v role/test_include_role_vars_from.yml 2>&1 | tee test_include_role_vars_from.out +test "$(grep -E -c 'Expected a string for vars_from but got' test_include_role_vars_from.out)" = 1 ## Max Recursion Depth # https://github.com/ansible/ansible/issues/23609