summaryrefslogtreecommitdiff
path: root/lib/ansible/vars/manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/vars/manager.py')
-rw-r--r--lib/ansible/vars/manager.py92
1 files changed, 68 insertions, 24 deletions
diff --git a/lib/ansible/vars/manager.py b/lib/ansible/vars/manager.py
index a09704e0..8282190e 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._text import to_text
+from ansible.module_utils.common.text.converters 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=True, use_cache=True,
+ def get_vars(self, play=None, host=None, task=None, include_hostvars=True, include_delegate_to=False, use_cache=True,
_hosts=None, _hosts_all=None, stage='task'):
'''
Returns the variables, with optional "context" given via the parameters
@@ -172,7 +172,6 @@ class VariableManager:
host=host,
task=task,
include_hostvars=include_hostvars,
- include_delegate_to=include_delegate_to,
_hosts=_hosts,
_hosts_all=_hosts_all,
)
@@ -185,6 +184,9 @@ 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:
@@ -197,11 +199,10 @@ class VariableManager:
basedirs = [self._loader.get_basedir()]
if play:
- # 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)
-
+ # 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)
if task:
# set basedirs
if C.PLAYBOOK_VARS_ROOT == 'all': # should be default
@@ -215,9 +216,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
@@ -383,19 +384,18 @@ 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)))
- # 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)
+ # 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)
# 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),
- "role '%s' vars" % task._role.name)
+ 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.get_vars(), "task vars")
# next, we merge in the vars cache (include vars) and nonpersistent
@@ -408,12 +408,11 @@ 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
@@ -444,7 +443,7 @@ class VariableManager:
else:
return all_vars
- def _get_magic_variables(self, play, host, task, include_hostvars, include_delegate_to, _hosts=None, _hosts_all=None):
+ def _get_magic_variables(self, play, host, task, include_hostvars, _hosts=None, _hosts_all=None):
'''
Returns a dictionary of so-called "magic" variables in Ansible,
which are special variables we set internally for use.
@@ -456,9 +455,8 @@ class VariableManager:
variables['ansible_config_file'] = C.CONFIG_FILE
if play:
- # This is a list of all role names of all dependencies for all roles for this play
+ # using role_cache as play.roles only has 'public' roles for vars exporting
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
@@ -470,7 +468,7 @@ class VariableManager:
# dependencies that are also explicitly named as roles are included in this list
variables['ansible_dependent_role_names'] = dependency_role_names
- # DEPRECATED: role_names should be deprecated in favor of ansible_role_names or ansible_play_role_names
+ # TODO: data tagging!!! DEPRECATED: role_names should be deprecated in favor of ansible_ prefixed ones
variables['role_names'] = variables['ansible_play_role_names']
variables['ansible_play_name'] = play.get_name()
@@ -516,6 +514,47 @@ 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
@@ -527,6 +566,11 @@ 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