diff --git a/CHANGELOG.md b/CHANGELOG.md index b4c7059431..c1cbb913fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ Ansible Changes By Release * Fix the issue SSL verification can not be disabled for Tower modules * Use safe_load instead on load to read a yaml document * Fix for win_file to respect check mode when deleting directories +* Include_role now complains about invalid arguments diff --git a/lib/ansible/playbook/role_include.py b/lib/ansible/playbook/role_include.py index fbcc313278..454f445435 100644 --- a/lib/ansible/playbook/role_include.py +++ b/lib/ansible/playbook/role_include.py @@ -43,13 +43,17 @@ class IncludeRole(Task): circumstances related to the `- include_role: ...` """ + BASE = frozenset(['name', 'role']) # directly assigned + FROM_ARGS = frozenset(['tasks_from', 'vars_from', 'defaults_from']) # used to populate from dict in role + OTHER_ARGS = frozenset(['private', 'allow_duplicates']) # assigned to matching property + VALID_ARGS = frozenset(BASE.union(FROM_ARGS.union(OTHER_ARGS))) # all valid args + # ================================================================================= # ATTRIBUTES # private as this is a 'module options' vs a task property _allow_duplicates = FieldAttribute(isa='bool', default=True, private=True) _private = FieldAttribute(isa='bool', default=None, private=True) - _static = FieldAttribute(isa='bool', default=None) def __init__(self, block=None, role=None, task_include=None): @@ -98,23 +102,27 @@ class IncludeRole(Task): ir = IncludeRole(block, role, task_include=task_include).load_data(data, variable_manager=variable_manager, loader=loader) - ### Process options + # Validate options + my_arg_names = frozenset(ir.args.keys()) + # name is needed, or use role as alias ir._role_name = ir.args.get('name', ir.args.get('role')) if ir._role_name is None: raise AnsibleParserError("'name' is a required field for include_role.") - # build options for role includes - for key in ['tasks', 'vars', 'defaults']: - from_key ='%s_from' % key - if ir.args.get(from_key): - ir._from_files[key] = basename(ir.args.get(from_key)) + # validate bad args, otherwise we silently ignore + bad_opts = my_arg_names.difference(IncludeRole.VALID_ARGS) + if bad_opts: + raise AnsibleParserError('Invalid options for include_role: %s' % ','.join(list(bad_opts))) + + # build options for role includes + for key in IncludeRole.FROM_ARGS.intersection(my_arg_names): + from_key = key.replace('_from', '') + ir._from_files[from_key] = basename(ir.args.get(key)) - #FIXME: find a way to make this list come from object ( attributes does not work as per below) # manual list as otherwise the options would set other task parameters we don't want. - for option in ['private', 'allow_duplicates']: - if option in ir.args: - setattr(ir, option, ir.args.get(option)) + for option in IncludeRole.OTHER_ARGS.intersection(my_arg_names): + setattr(ir, option, ir.args.get(option)) return ir