summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2014-11-20 12:20:32 -0600
committerJames Cammarata <jimi@sngx.net>2014-11-20 12:53:48 -0600
commit4b6b58ab11fde889ee5301be773f554fa8f49a41 (patch)
tree5b16f810f7cfe46d2b9d6b1a4448402198fc2099
parent0edaa6f790b8623506acc6981e980183b4f857b4 (diff)
downloadansible-4b6b58ab11fde889ee5301be773f554fa8f49a41.tar.gz
Fix role parameter precedence after 9a0f8f0
Fixes #9497
-rw-r--r--lib/ansible/playbook/__init__.py1
-rw-r--r--lib/ansible/playbook/play.py42
-rw-r--r--lib/ansible/playbook/task.py6
-rw-r--r--lib/ansible/runner/__init__.py4
4 files changed, 41 insertions, 12 deletions
diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py
index 28e1d923eb..d3c0aa5300 100644
--- a/lib/ansible/playbook/__init__.py
+++ b/lib/ansible/playbook/__init__.py
@@ -402,6 +402,7 @@ class PlayBook(object):
play_vars=task.play_vars,
play_file_vars=task.play_file_vars,
role_vars=task.role_vars,
+ role_params=task.role_params,
default_vars=task.default_vars,
extra_vars=self.extra_vars,
private_key_file=self.private_key_file,
diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py
index b793247826..0dcbca8684 100644
--- a/lib/ansible/playbook/play.py
+++ b/lib/ansible/playbook/play.py
@@ -221,6 +221,14 @@ class Play(object):
raise errors.AnsibleError("too many levels of recursion while resolving role dependencies")
for role in roles:
role_path,role_vars = self._get_role_path(role)
+
+ # save just the role params for this role, which exclude the special
+ # keywords 'role', 'tags', and 'when'.
+ role_params = role_vars.copy()
+ for item in ('role', 'tags', 'when'):
+ if item in role_params:
+ del role_params[item]
+
role_vars = utils.combine_vars(passed_vars, role_vars)
vars = self._resolve_main(utils.path_dwim(self.basedir, os.path.join(role_path, 'vars')))
@@ -249,6 +257,13 @@ class Play(object):
for dep in dependencies:
allow_dupes = False
(dep_path,dep_vars) = self._get_role_path(dep)
+
+ # save the dep params, just as we did above
+ dep_params = dep_vars.copy()
+ for item in ('role', 'tags', 'when'):
+ if item in dep_params:
+ del dep_params[item]
+
meta = self._resolve_main(utils.path_dwim(self.basedir, os.path.join(dep_path, 'meta')))
if os.path.isfile(meta):
meta_data = utils.parse_yaml_from_file(meta, vault_password=self.vault_password)
@@ -332,13 +347,13 @@ class Play(object):
dep_vars['when'] = tmpcond
self._build_role_dependencies([dep], dep_stack, passed_vars=dep_vars, level=level+1)
- dep_stack.append([dep,dep_path,dep_vars,dep_defaults_data])
+ dep_stack.append([dep, dep_path, dep_vars, dep_params, dep_defaults_data])
# only add the current role when we're at the top level,
# otherwise we'll end up in a recursive loop
if level == 0:
self.included_roles.append(role)
- dep_stack.append([role,role_path,role_vars,defaults_data])
+ dep_stack.append([role, role_path, role_vars, role_params, defaults_data])
return dep_stack
def _load_role_vars_files(self, vars_files):
@@ -400,12 +415,12 @@ class Play(object):
# make role_path available as variable to the task
for idx, val in enumerate(roles):
this_uuid = str(uuid.uuid4())
- roles[idx][-2]['role_uuid'] = this_uuid
- roles[idx][-2]['role_path'] = roles[idx][1]
+ roles[idx][-3]['role_uuid'] = this_uuid
+ roles[idx][-3]['role_path'] = roles[idx][1]
role_names = []
- for (role,role_path,role_vars,default_vars) in roles:
+ for (role, role_path, role_vars, role_params, default_vars) in roles:
# special vars must be extracted from the dict to the included tasks
special_keys = [ "sudo", "sudo_user", "when", "with_items" ]
special_vars = {}
@@ -438,13 +453,13 @@ class Play(object):
role_names.append(role_name)
if os.path.isfile(task):
- nt = dict(include=pipes.quote(task), vars=role_vars, default_vars=default_vars, role_name=role_name)
+ nt = dict(include=pipes.quote(task), vars=role_vars, role_params=role_params, default_vars=default_vars, role_name=role_name)
for k in special_keys:
if k in special_vars:
nt[k] = special_vars[k]
new_tasks.append(nt)
if os.path.isfile(handler):
- nt = dict(include=pipes.quote(handler), vars=role_vars, role_name=role_name)
+ nt = dict(include=pipes.quote(handler), vars=role_vars, role_params=role_params, role_name=role_name)
for k in special_keys:
if k in special_vars:
nt[k] = special_vars[k]
@@ -509,7 +524,7 @@ class Play(object):
# *************************************************
- def _load_tasks(self, tasks, vars=None, default_vars=None, sudo_vars=None,
+ def _load_tasks(self, tasks, vars=None, role_params=None, default_vars=None, sudo_vars=None,
additional_conditions=None, original_file=None, role_name=None):
''' handle task and handler include statements '''
@@ -521,6 +536,8 @@ class Play(object):
additional_conditions = []
if vars is None:
vars = {}
+ if role_params is None:
+ role_params = {}
if default_vars is None:
default_vars = {}
if sudo_vars is None:
@@ -572,11 +589,15 @@ class Play(object):
included_additional_conditions.append(x[k])
elif type(x[k]) is list:
included_additional_conditions.extend(x[k])
- elif k in ("include", "vars", "default_vars", "sudo", "sudo_user", "role_name", "no_log"):
+ elif k in ("include", "vars", "role_params", "default_vars", "sudo", "sudo_user", "role_name", "no_log"):
continue
else:
include_vars[k] = x[k]
+ # get any role parameters specified
+ role_params = x.get('role_params', {})
+
+ # get any role default variables specified
default_vars = x.get('default_vars', {})
if not default_vars:
default_vars = self.default_vars
@@ -609,7 +630,7 @@ class Play(object):
for y in data:
if isinstance(y, dict) and 'include' in y:
y['role_name'] = new_role
- loaded = self._load_tasks(data, mv, default_vars, included_sudo_vars, list(included_additional_conditions), original_file=include_filename, role_name=new_role)
+ loaded = self._load_tasks(data, mv, role_params, default_vars, included_sudo_vars, list(included_additional_conditions), original_file=include_filename, role_name=new_role)
results += loaded
elif type(x) == dict:
task = Task(
@@ -618,6 +639,7 @@ class Play(object):
play_vars=self.vars,
play_file_vars=self.vars_file_vars,
role_vars=self.role_vars,
+ role_params=role_params,
default_vars=default_vars,
additional_conditions=list(additional_conditions),
role_name=role_name
diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py
index ebe43f63c1..783f488fa1 100644
--- a/lib/ansible/playbook/task.py
+++ b/lib/ansible/playbook/task.py
@@ -26,7 +26,7 @@ class Task(object):
__slots__ = [
'name', 'meta', 'action', 'when', 'async_seconds', 'async_poll_interval',
- 'notify', 'module_name', 'module_args', 'module_vars', 'play_vars', 'play_file_vars', 'role_vars', 'default_vars',
+ 'notify', 'module_name', 'module_args', 'module_vars', 'play_vars', 'play_file_vars', 'role_vars', 'role_params', 'default_vars',
'play', 'notified_by', 'tags', 'register', 'role_name',
'delegate_to', 'first_available_file', 'ignore_errors',
'local_action', 'transport', 'sudo', 'remote_user', 'sudo_user', 'sudo_pass',
@@ -45,7 +45,7 @@ class Task(object):
'su', 'su_user', 'su_pass', 'no_log', 'run_once',
]
- def __init__(self, play, ds, module_vars=None, play_vars=None, play_file_vars=None, role_vars=None, default_vars=None, additional_conditions=None, role_name=None):
+ def __init__(self, play, ds, module_vars=None, play_vars=None, play_file_vars=None, role_vars=None, role_params=None, default_vars=None, additional_conditions=None, role_name=None):
''' constructor loads from a task or handler datastructure '''
# meta directives are used to tell things like ansible/playbook to run
@@ -123,6 +123,7 @@ class Task(object):
self.play_vars = play_vars
self.play_file_vars = play_file_vars
self.role_vars = role_vars
+ self.role_params = role_params
self.default_vars = default_vars
self.play = play
@@ -226,6 +227,7 @@ class Task(object):
all_vars = utils.combine_vars(all_vars, self.play_file_vars)
all_vars = utils.combine_vars(all_vars, self.role_vars)
all_vars = utils.combine_vars(all_vars, self.module_vars)
+ all_vars = utils.combine_vars(all_vars, self.role_params)
self.async_seconds = ds.get('async', 0) # not async by default
self.async_seconds = template.template_from_string(play.basedir, self.async_seconds, all_vars)
diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
index 1d236f5f11..0d16746255 100644
--- a/lib/ansible/runner/__init__.py
+++ b/lib/ansible/runner/__init__.py
@@ -137,6 +137,7 @@ class Runner(object):
play_vars=None, #
play_file_vars=None, #
role_vars=None, #
+ role_params=None, #
default_vars=None, #
extra_vars=None, # extra vars specified with he playbook(s)
is_playbook=False, # running from playbook or not?
@@ -182,6 +183,7 @@ class Runner(object):
self.play_vars = utils.default(play_vars, lambda: {})
self.play_file_vars = utils.default(play_file_vars, lambda: {})
self.role_vars = utils.default(role_vars, lambda: {})
+ self.role_params = utils.default(role_params, lambda: {})
self.default_vars = utils.default(default_vars, lambda: {})
self.extra_vars = utils.default(extra_vars, lambda: {})
@@ -645,6 +647,8 @@ class Runner(object):
# followed by vars_cache things (set_fact, include_vars, and
# vars_files which had host-specific templating done)
inject = utils.combine_vars(inject, self.vars_cache.get(host, {}))
+ # role parameters next
+ inject = utils.combine_vars(inject, self.role_params)
# and finally -e vars are the highest priority
inject = utils.combine_vars(inject, self.extra_vars)
# and then special vars