summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2017-03-03 00:56:24 -0600
committerJames Cammarata <jimi@sngx.net>2017-06-06 10:19:32 -0500
commit8e748d34c208033bb4a91819092690f181bdd3a0 (patch)
tree0c2928e7f1bd602e9b9785e59057e8fdae95f833
parent7bebc83dcf5af181d36be2cc8a0e9ced0726810c (diff)
downloadansible-8e748d34c208033bb4a91819092690f181bdd3a0.tar.gz
Initial commit to split includes into static imports/dynamic includes
-rw-r--r--lib/ansible/executor/task_executor.py4
-rw-r--r--lib/ansible/parsing/mod_args.py6
-rw-r--r--lib/ansible/playbook/__init__.py4
-rw-r--r--lib/ansible/playbook/helpers.py28
-rw-r--r--lib/ansible/playbook/included_file.py2
-rw-r--r--lib/ansible/playbook/playbook_include.py30
-rw-r--r--lib/ansible/playbook/role_include.py5
-rw-r--r--lib/ansible/playbook/task.py10
-rw-r--r--lib/ansible/plugins/callback/default.py5
-rw-r--r--lib/ansible/plugins/strategy/__init__.py2
10 files changed, 59 insertions, 37 deletions
diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py
index cc8276ec0d..7df69f48aa 100644
--- a/lib/ansible/executor/task_executor.py
+++ b/lib/ansible/executor/task_executor.py
@@ -432,7 +432,7 @@ class TaskExecutor:
if self._loop_eval_error is not None:
raise self._loop_eval_error
# skip conditional exception in the case of includes as the vars needed might not be available except in the included tasks or due to tags
- if self._task.action not in ['include', 'include_role']:
+ if self._task.action not in ['include', 'include_tasks', 'include_role']:
raise
# Not skipping, if we had loop error raised earlier we need to raise it now to halt the execution of this task
@@ -445,7 +445,7 @@ class TaskExecutor:
# if this task is a TaskInclude, we just return now with a success code so the
# main thread can expand the task list for the given host
- if self._task.action == 'include':
+ if self._task.action in ('include', 'include_tasks'):
include_variables = self._task.args.copy()
include_file = include_variables.pop('_raw_params', None)
if not include_file:
diff --git a/lib/ansible/parsing/mod_args.py b/lib/ansible/parsing/mod_args.py
index 2ed4b9202c..d48a3d2468 100644
--- a/lib/ansible/parsing/mod_args.py
+++ b/lib/ansible/parsing/mod_args.py
@@ -36,6 +36,10 @@ RAW_PARAM_MODULES = ([
'script',
'include',
'include_vars',
+ 'include_tasks',
+ 'include_role',
+ 'import_tasks',
+ 'import_role',
'add_host',
'group_by',
'set_fact',
@@ -281,7 +285,7 @@ class ModuleArgsParser:
# walk the input dictionary to see we recognize a module name
for (item, value) in iteritems(self._task_ds):
- if item in module_loader or item in ['meta', 'include', 'include_role']:
+ if item in module_loader or item in ['meta', 'include', 'include_tasks', 'include_role', 'import_tasks', 'import_role']:
# finding more than one module name is a problem
if action is not None:
raise AnsibleParserError("conflicting action statements: %s, %s" % (action, item), obj=self._task_ds)
diff --git a/lib/ansible/playbook/__init__.py b/lib/ansible/playbook/__init__.py
index c47025d5eb..cc0451a2f8 100644
--- a/lib/ansible/playbook/__init__.py
+++ b/lib/ansible/playbook/__init__.py
@@ -89,7 +89,9 @@ class Playbook:
self._loader.set_basedir(cur_basedir)
raise AnsibleParserError("playbook entries must be either a valid play or an include statement", obj=entry)
- if 'include' in entry:
+ if 'include' in entry or 'import_playbook' in entry:
+ if 'include' in entry:
+ display.deprecated("You should use 'import_playbook' instead of 'include' for playbook includes")
pb = PlaybookInclude.load(entry, basedir=self._basedir, variable_manager=variable_manager, loader=self._loader)
if pb is not None:
self._entries.extend(pb._entries)
diff --git a/lib/ansible/playbook/helpers.py b/lib/ansible/playbook/helpers.py
index f2a5b6fb33..f1850cf6a4 100644
--- a/lib/ansible/playbook/helpers.py
+++ b/lib/ansible/playbook/helpers.py
@@ -108,7 +108,11 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
)
task_list.append(t)
else:
- if 'include' in task_ds:
+ if 'include' in task_ds or 'import_tasks' in task_ds or 'include_tasks' in task_ds:
+ if 'include' in task_ds:
+ display.deprecated("The use of 'include' for tasks has been deprecated. " \
+ "Use 'import_tasks' for static inclusions or 'include_tasks' for dynamic inclusions")
+
if use_handlers:
include_class = HandlerTaskInclude
else:
@@ -129,7 +133,13 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
# check to see if this include is dynamic or static:
# 1. the user has set the 'static' option to false or true
# 2. one of the appropriate config options was set
- if t.static is not None:
+ if 'include_tasks' in task_ds:
+ is_static = False
+ elif 'import_tasks' in task_ds:
+ is_static = True
+ elif t.static is not None:
+ display.deprecated("The use of 'static' has been deprecated. " \
+ "Use 'import_role' for static inclusion, or 'include_role' for dynamic inclusion")
is_static = t.static
else:
is_static = C.DEFAULT_TASK_INCLUDES_STATIC or \
@@ -138,7 +148,10 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
if is_static:
if t.loop is not None:
- raise AnsibleParserError("You cannot use 'static' on an include with a loop", obj=task_ds)
+ if 'import_tasks' in task_ds:
+ raise AnsibleParserError("You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.", obj=task_ds)
+ else:
+ raise AnsibleParserError("You cannot use 'static' on an include with a loop", obj=task_ds)
# we set a flag to indicate this include was static
t.statically_loaded = True
@@ -202,7 +215,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
# the same fashion used by the on_include callback. We also do it here,
# because the recursive nature of helper methods means we may be loading
# nested includes, and we want the include order printed correctly
- display.vv("statically included: %s" % include_file)
+ display.vv("statically imported: %s" % include_file)
except AnsibleFileNotFound:
if t.static or \
C.DEFAULT_TASK_INCLUDES_STATIC or \
@@ -267,8 +280,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
else:
task_list.append(t)
- elif 'include_role' in task_ds:
-
+ elif 'include_role' in task_ds or 'import_role' in task_ds:
ir = IncludeRole.load(
task_ds,
block=block,
@@ -280,7 +292,11 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
# 1. the user has set the 'static' option to false or true
# 2. one of the appropriate config options was set
+ if 'import_role' in task_ds:
+ is_static = True
if ir.static is not None:
+ display.deprecated("The use of 'static' for 'include_role' has been deprecated. " \
+ "Use 'import_role' for static inclusion, or 'include_role' for dynamic inclusion")
is_static = ir.static
else:
display.debug('Determine if include_role is static')
diff --git a/lib/ansible/playbook/included_file.py b/lib/ansible/playbook/included_file.py
index 5a7902db74..5784ea0650 100644
--- a/lib/ansible/playbook/included_file.py
+++ b/lib/ansible/playbook/included_file.py
@@ -64,7 +64,7 @@ class IncludedFile:
original_host = res._host
original_task = res._task
- if original_task.action == 'include':
+ if original_task.action in ('include', 'include_tasks'):
if original_task.loop:
if 'results' not in res._result:
continue
diff --git a/lib/ansible/playbook/playbook_include.py b/lib/ansible/playbook/playbook_include.py
index 3cf6aca188..2ca48dc088 100644
--- a/lib/ansible/playbook/playbook_include.py
+++ b/lib/ansible/playbook/playbook_include.py
@@ -35,7 +35,7 @@ from ansible.template import Templar
class PlaybookInclude(Base, Conditional, Taggable):
_name = FieldAttribute(isa='string')
- _include = FieldAttribute(isa='string')
+ _import_playbook = FieldAttribute(isa='string')
_vars = FieldAttribute(isa='dict', default=dict())
@staticmethod
@@ -66,7 +66,7 @@ class PlaybookInclude(Base, Conditional, Taggable):
# then we use the object to load a Playbook
pb = Playbook(loader=loader)
- file_name = templar.template(new_obj.include)
+ file_name = templar.template(new_obj.import_playbook)
if not os.path.isabs(file_name):
file_name = os.path.join(basedir, file_name)
@@ -113,36 +113,36 @@ class PlaybookInclude(Base, Conditional, Taggable):
if isinstance(ds, AnsibleBaseYAMLObject):
new_ds.ansible_pos = ds.ansible_pos
- for (k, v) in iteritems(ds):
- if k == 'include':
- self._preprocess_include(ds, new_ds, k, v)
+ for (k,v) in iteritems(ds):
+ if k in ('include', 'import_playbook'):
+ self._preprocess_import(ds, new_ds, k, v)
else:
# some basic error checking, to make sure vars are properly
# formatted and do not conflict with k=v parameters
if k == 'vars':
if 'vars' in new_ds:
- raise AnsibleParserError("include parameters cannot be mixed with 'vars' entries for include statements", obj=ds)
+ raise AnsibleParserError("import_playbook parameters cannot be mixed with 'vars' entries for import statements", obj=ds)
elif not isinstance(v, dict):
- raise AnsibleParserError("vars for include statements must be specified as a dictionary", obj=ds)
+ raise AnsibleParserError("vars for import_playbook statements must be specified as a dictionary", obj=ds)
new_ds[k] = v
return super(PlaybookInclude, self).preprocess_data(new_ds)
- def _preprocess_include(self, ds, new_ds, k, v):
+ def _preprocess_import(self, ds, new_ds, k, v):
'''
- Splits the include line up into filename and parameters
+ Splits the playbook import line up into filename and parameters
'''
if v is None:
- raise AnsibleParserError("include parameter is missing", obj=ds)
+ raise AnsibleParserError("playbook import parameter is missing", obj=ds)
- # The include line must include at least one item, which is the filename
- # to include. Anything after that should be regarded as a parameter to the include
+ # The import_playbook line must include at least one item, which is the filename
+ # to import. Anything after that should be regarded as a parameter to the import
items = split_args(v)
if len(items) == 0:
- raise AnsibleParserError("include statements must specify the file name to include", obj=ds)
+ raise AnsibleParserError("import_playbook statements must specify the file name to import", obj=ds)
else:
- new_ds['include'] = items[0]
+ new_ds['import_playbook'] = items[0]
if len(items) > 1:
# rejoin the parameter portion of the arguments and
# then use parse_kv() to get a dict of params back
@@ -150,5 +150,5 @@ class PlaybookInclude(Base, Conditional, Taggable):
if 'tags' in params:
new_ds['tags'] = params.pop('tags')
if 'vars' in new_ds:
- raise AnsibleParserError("include parameters cannot be mixed with 'vars' entries for include statements", obj=ds)
+ raise AnsibleParserError("import_playbook parameters cannot be mixed with 'vars' entries for import statements", obj=ds)
new_ds['vars'] = params
diff --git a/lib/ansible/playbook/role_include.py b/lib/ansible/playbook/role_include.py
index 44d57fab57..ccb2b1cf9f 100644
--- a/lib/ansible/playbook/role_include.py
+++ b/lib/ansible/playbook/role_include.py
@@ -23,7 +23,7 @@ from os.path import basename
from ansible.errors import AnsibleParserError
from ansible.playbook.attribute import FieldAttribute
-from ansible.playbook.task import Task
+from ansible.playbook.task_include import TaskInclude
from ansible.playbook.role import Role
from ansible.playbook.role.include import RoleInclude
@@ -36,7 +36,7 @@ except ImportError:
__all__ = ['IncludeRole']
-class IncludeRole(Task):
+class IncludeRole(TaskInclude):
"""
A Role include is derived from a regular role to handle the special
@@ -55,7 +55,6 @@ class IncludeRole(Task):
super(IncludeRole, self).__init__(block=block, role=role, task_include=task_include)
- self.statically_loaded = False
self._from_files = {}
self._parent_role = role
self._role_name = None
diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py
index 979f0ce8a5..a40cd79b28 100644
--- a/lib/ansible/playbook/task.py
+++ b/lib/ansible/playbook/task.py
@@ -215,10 +215,10 @@ class Task(Base, Conditional, Taggable, Become):
# top level of the task, so we move those into the 'vars' dictionary
# here, and show a deprecation message as we will remove this at
# some point in the future.
- if action == 'include' and k not in self._valid_attrs and k not in self.DEPRECATED_ATTRIBUTES:
- display.deprecated("Specifying include variables at the top-level of the task is deprecated. "
- "Please see:\nhttp://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse\n\n "
- "for currently supported syntax regarding included files and variables", version="2.7")
+ if action in ('include', 'include_tasks') and k not in self._valid_attrs and k not in self.DEPRECATED_ATTRIBUTES:
+ display.deprecated("Specifying include variables at the top-level of the task is deprecated."
+ " Please see:\nhttp://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse\n\n"
+ " for currently supported syntax regarding included files and variables", version="2.7")
new_ds['vars'][k] = v
else:
new_ds[k] = v
@@ -331,7 +331,7 @@ class Task(Base, Conditional, Taggable, Become):
all_vars = dict()
if self._parent:
all_vars.update(self._parent.get_include_params())
- if self.action in ('include', 'include_role'):
+ if self.action in ('include', 'include_tasks', 'include_role'):
all_vars.update(self.vars)
return all_vars
diff --git a/lib/ansible/plugins/callback/default.py b/lib/ansible/plugins/callback/default.py
index 8313c39513..87d7e33642 100644
--- a/lib/ansible/plugins/callback/default.py
+++ b/lib/ansible/plugins/callback/default.py
@@ -27,6 +27,7 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible import constants as C
+from ansible.playbook.task_include import TaskInclude
from ansible.plugins.callback import CallbackBase
from ansible.utils.color import colorize, hostcolor
@@ -80,7 +81,7 @@ class CallbackModule(CallbackBase):
delegated_vars = result._result.get('_ansible_delegated_vars', None)
self._clean_results(result._result, result._task.action)
- if result._task.action in ('include', 'include_role'):
+ if isinstance(result._task, TaskInclude):
return
elif result._result.get('changed', False):
if delegated_vars:
@@ -194,7 +195,7 @@ class CallbackModule(CallbackBase):
def v2_runner_item_on_ok(self, result):
delegated_vars = result._result.get('_ansible_delegated_vars', None)
- if result._task.action in ('include', 'include_role'):
+ if isinstance(result._task, TaskInclude):
return
elif result._result.get('changed', False):
msg = 'changed'
diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py
index a26074b5b9..2b10f87b7a 100644
--- a/lib/ansible/plugins/strategy/__init__.py
+++ b/lib/ansible/plugins/strategy/__init__.py
@@ -535,7 +535,7 @@ class StrategyBase:
if self._diff:
self._tqm.send_callback('v2_on_file_diff', task_result)
- if original_task.action not in ['include', 'include_role']:
+ if not isinstance(original_task, TaskInclude):
self._tqm._stats.increment('ok', original_host.name)
if 'changed' in task_result._result and task_result._result['changed']:
self._tqm._stats.increment('changed', original_host.name)