diff options
Diffstat (limited to 'lib/ansible/vars/manager.py')
-rw-r--r-- | lib/ansible/vars/manager.py | 92 |
1 files changed, 24 insertions, 68 deletions
diff --git a/lib/ansible/vars/manager.py b/lib/ansible/vars/manager.py index 8282190e..a09704e0 100644 --- a/lib/ansible/vars/manager.py +++ b/lib/ansible/vars/manager.py @@ -32,7 +32,7 @@ from ansible import constants as C from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVariable, AnsibleFileNotFound, AnsibleAssertionError, AnsibleTemplateError from ansible.inventory.host import Host from ansible.inventory.helpers import sort_groups, get_group_vars -from ansible.module_utils.common.text.converters import to_text +from ansible.module_utils._text import to_text from ansible.module_utils.six import text_type, string_types from ansible.plugins.loader import lookup_loader from ansible.vars.fact_cache import FactCache @@ -139,7 +139,7 @@ class VariableManager: def set_inventory(self, inventory): self._inventory = inventory - def get_vars(self, play=None, host=None, task=None, include_hostvars=True, include_delegate_to=False, use_cache=True, + def get_vars(self, play=None, host=None, task=None, include_hostvars=True, include_delegate_to=True, use_cache=True, _hosts=None, _hosts_all=None, stage='task'): ''' Returns the variables, with optional "context" given via the parameters @@ -172,6 +172,7 @@ class VariableManager: host=host, task=task, include_hostvars=include_hostvars, + include_delegate_to=include_delegate_to, _hosts=_hosts, _hosts_all=_hosts_all, ) @@ -184,9 +185,6 @@ class VariableManager: See notes in the VarsWithSources docstring for caveats and limitations of the source tracking ''' - if new_data == {}: - return data - if C.DEFAULT_DEBUG: # Populate var sources dict for key in new_data: @@ -199,10 +197,11 @@ class VariableManager: basedirs = [self._loader.get_basedir()] if play: - # get role defaults (lowest precedence) - for role in play.roles: - if role.public: - all_vars = _combine_and_track(all_vars, role.get_default_vars(), "role '%s' defaults" % role.name) + # first we compile any vars specified in defaults/main.yml + # for all roles within the specified play + for role in play.get_roles(): + all_vars = _combine_and_track(all_vars, role.get_default_vars(), "role '%s' defaults" % role.name) + if task: # set basedirs if C.PLAYBOOK_VARS_ROOT == 'all': # should be default @@ -216,9 +215,9 @@ class VariableManager: # if we have a task in this context, and that task has a role, make # sure it sees its defaults above any other roles, as we previously # (v1) made sure each task had a copy of its roles default vars - # TODO: investigate why we need play or include_role check? if task._role is not None and (play or task.action in C._ACTION_INCLUDE_ROLE): - all_vars = _combine_and_track(all_vars, task._role.get_default_vars(dep_chain=task.get_dep_chain()), "role '%s' defaults" % task._role.name) + all_vars = _combine_and_track(all_vars, task._role.get_default_vars(dep_chain=task.get_dep_chain()), + "role '%s' defaults" % task._role.name) if host: # THE 'all' group and the rest of groups for a host, used below @@ -384,18 +383,19 @@ class VariableManager: raise AnsibleParserError("Error while reading vars files - please supply a list of file names. " "Got '%s' of type %s" % (vars_files, type(vars_files))) - # We now merge in all exported vars from all roles in the play (very high precedence) - for role in play.roles: - if role.public: - all_vars = _combine_and_track(all_vars, role.get_vars(include_params=False, only_exports=True), "role '%s' exported vars" % role.name) + # By default, we now merge in all vars from all roles in the play, + # unless the user has disabled this via a config option + if not C.DEFAULT_PRIVATE_ROLE_VARS: + for role in play.get_roles(): + all_vars = _combine_and_track(all_vars, role.get_vars(include_params=False), "role '%s' vars" % role.name) # next, we merge in the vars from the role, which will specifically # follow the role dependency chain, and then we merge in the tasks # vars (which will look at parent blocks/task includes) if task: if task._role: - all_vars = _combine_and_track(all_vars, task._role.get_vars(task.get_dep_chain(), include_params=False, only_exports=False), - "role '%s' all vars" % task._role.name) + all_vars = _combine_and_track(all_vars, task._role.get_vars(task.get_dep_chain(), include_params=False), + "role '%s' vars" % task._role.name) all_vars = _combine_and_track(all_vars, task.get_vars(), "task vars") # next, we merge in the vars cache (include vars) and nonpersistent @@ -408,11 +408,12 @@ class VariableManager: # next, we merge in role params and task include params if task: + if task._role: + all_vars = _combine_and_track(all_vars, task._role.get_role_params(task.get_dep_chain()), "role '%s' params" % task._role.name) + # special case for include tasks, where the include params # may be specified in the vars field for the task, which should # have higher precedence than the vars/np facts above - if task._role: - all_vars = _combine_and_track(all_vars, task._role.get_role_params(task.get_dep_chain()), "role params") all_vars = _combine_and_track(all_vars, task.get_include_params(), "include params") # extra vars @@ -443,7 +444,7 @@ class VariableManager: else: return all_vars - def _get_magic_variables(self, play, host, task, include_hostvars, _hosts=None, _hosts_all=None): + def _get_magic_variables(self, play, host, task, include_hostvars, include_delegate_to, _hosts=None, _hosts_all=None): ''' Returns a dictionary of so-called "magic" variables in Ansible, which are special variables we set internally for use. @@ -455,8 +456,9 @@ class VariableManager: variables['ansible_config_file'] = C.CONFIG_FILE if play: - # using role_cache as play.roles only has 'public' roles for vars exporting + # This is a list of all role names of all dependencies for all roles for this play dependency_role_names = list({d.get_name() for r in play.roles for d in r.get_all_dependencies()}) + # This is a list of all role names of all roles for this play play_role_names = [r.get_name() for r in play.roles] # ansible_role_names includes all role names, dependent or directly referenced by the play @@ -468,7 +470,7 @@ class VariableManager: # dependencies that are also explicitly named as roles are included in this list variables['ansible_dependent_role_names'] = dependency_role_names - # TODO: data tagging!!! DEPRECATED: role_names should be deprecated in favor of ansible_ prefixed ones + # DEPRECATED: role_names should be deprecated in favor of ansible_role_names or ansible_play_role_names variables['role_names'] = variables['ansible_play_role_names'] variables['ansible_play_name'] = play.get_name() @@ -514,47 +516,6 @@ class VariableManager: return variables - def get_delegated_vars_and_hostname(self, templar, task, variables): - """Get the delegated_vars for an individual task invocation, which may be be in the context - of an individual loop iteration. - - Not used directly be VariableManager, but used primarily within TaskExecutor - """ - delegated_vars = {} - delegated_host_name = None - if task.delegate_to: - delegated_host_name = templar.template(task.delegate_to, fail_on_undefined=False) - - # no need to do work if omitted - if delegated_host_name != self._omit_token: - - if not delegated_host_name: - raise AnsibleError('Empty hostname produced from delegate_to: "%s"' % task.delegate_to) - - delegated_host = self._inventory.get_host(delegated_host_name) - if delegated_host is None: - for h in self._inventory.get_hosts(ignore_limits=True, ignore_restrictions=True): - # check if the address matches, or if both the delegated_to host - # and the current host are in the list of localhost aliases - if h.address == delegated_host_name: - delegated_host = h - break - else: - delegated_host = Host(name=delegated_host_name) - - delegated_vars['ansible_delegated_vars'] = { - delegated_host_name: self.get_vars( - play=task.get_play(), - host=delegated_host, - task=task, - include_delegate_to=False, - include_hostvars=True, - ) - } - delegated_vars['ansible_delegated_vars'][delegated_host_name]['inventory_hostname'] = variables.get('inventory_hostname') - - return delegated_vars, delegated_host_name - def _get_delegated_vars(self, play, task, existing_variables): # This method has a lot of code copied from ``TaskExecutor._get_loop_items`` # if this is failing, and ``TaskExecutor._get_loop_items`` is not @@ -566,11 +527,6 @@ class VariableManager: # This "task" is not a Task, so we need to skip it return {}, None - display.deprecated( - 'Getting delegated variables via get_vars is no longer used, and is handled within the TaskExecutor.', - version='2.18', - ) - # we unfortunately need to template the delegate_to field here, # as we're fetching vars before post_validate has been called on # the task that has been passed in |