mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-23 05:10:22 -07:00
Adding more fixes for integration testing under v2
This commit is contained in:
parent
2e0472e03b
commit
c60c295ada
10 changed files with 317 additions and 23 deletions
|
@ -43,7 +43,10 @@ class TaskResult:
|
||||||
return self._check_key('skipped')
|
return self._check_key('skipped')
|
||||||
|
|
||||||
def is_failed(self):
|
def is_failed(self):
|
||||||
return self._check_key('failed') or self._result.get('rc', 0) != 0
|
if 'failed_when_result' in self._result:
|
||||||
|
return self._check_key('failed_when_result')
|
||||||
|
else:
|
||||||
|
return self._check_key('failed') or self._result.get('rc', 0) != 0
|
||||||
|
|
||||||
def is_unreachable(self):
|
def is_unreachable(self):
|
||||||
return self._check_key('unreachable')
|
return self._check_key('unreachable')
|
||||||
|
|
128
v2/ansible/module_utils/database.py
Normal file
128
v2/ansible/module_utils/database.py
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
# This code is part of Ansible, but is an independent component.
|
||||||
|
# This particular file snippet, and this file snippet only, is BSD licensed.
|
||||||
|
# Modules you write using this snippet, which is embedded dynamically by Ansible
|
||||||
|
# still belong to the author of the module, and may assign their own license
|
||||||
|
# to the complete work.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com>
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
# are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
class SQLParseError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class UnclosedQuoteError(SQLParseError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# maps a type of identifier to the maximum number of dot levels that are
|
||||||
|
# allowed to specifiy that identifier. For example, a database column can be
|
||||||
|
# specified by up to 4 levels: database.schema.table.column
|
||||||
|
_PG_IDENTIFIER_TO_DOT_LEVEL = dict(database=1, schema=2, table=3, column=4, role=1)
|
||||||
|
_MYSQL_IDENTIFIER_TO_DOT_LEVEL = dict(database=1, table=2, column=3, role=1, vars=1)
|
||||||
|
|
||||||
|
def _find_end_quote(identifier, quote_char):
|
||||||
|
accumulate = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
quote = identifier.index(quote_char)
|
||||||
|
except ValueError:
|
||||||
|
raise UnclosedQuoteError
|
||||||
|
accumulate = accumulate + quote
|
||||||
|
try:
|
||||||
|
next_char = identifier[quote+1]
|
||||||
|
except IndexError:
|
||||||
|
return accumulate
|
||||||
|
if next_char == quote_char:
|
||||||
|
try:
|
||||||
|
identifier = identifier[quote+2:]
|
||||||
|
accumulate = accumulate + 2
|
||||||
|
except IndexError:
|
||||||
|
raise UnclosedQuoteError
|
||||||
|
else:
|
||||||
|
return accumulate
|
||||||
|
|
||||||
|
|
||||||
|
def _identifier_parse(identifier, quote_char):
|
||||||
|
if not identifier:
|
||||||
|
raise SQLParseError('Identifier name unspecified or unquoted trailing dot')
|
||||||
|
|
||||||
|
already_quoted = False
|
||||||
|
if identifier.startswith(quote_char):
|
||||||
|
already_quoted = True
|
||||||
|
try:
|
||||||
|
end_quote = _find_end_quote(identifier[1:], quote_char=quote_char) + 1
|
||||||
|
except UnclosedQuoteError:
|
||||||
|
already_quoted = False
|
||||||
|
else:
|
||||||
|
if end_quote < len(identifier) - 1:
|
||||||
|
if identifier[end_quote+1] == '.':
|
||||||
|
dot = end_quote + 1
|
||||||
|
first_identifier = identifier[:dot]
|
||||||
|
next_identifier = identifier[dot+1:]
|
||||||
|
further_identifiers = _identifier_parse(next_identifier, quote_char)
|
||||||
|
further_identifiers.insert(0, first_identifier)
|
||||||
|
else:
|
||||||
|
raise SQLParseError('User escaped identifiers must escape extra quotes')
|
||||||
|
else:
|
||||||
|
further_identifiers = [identifier]
|
||||||
|
|
||||||
|
if not already_quoted:
|
||||||
|
try:
|
||||||
|
dot = identifier.index('.')
|
||||||
|
except ValueError:
|
||||||
|
identifier = identifier.replace(quote_char, quote_char*2)
|
||||||
|
identifier = ''.join((quote_char, identifier, quote_char))
|
||||||
|
further_identifiers = [identifier]
|
||||||
|
else:
|
||||||
|
if dot == 0 or dot >= len(identifier) - 1:
|
||||||
|
identifier = identifier.replace(quote_char, quote_char*2)
|
||||||
|
identifier = ''.join((quote_char, identifier, quote_char))
|
||||||
|
further_identifiers = [identifier]
|
||||||
|
else:
|
||||||
|
first_identifier = identifier[:dot]
|
||||||
|
next_identifier = identifier[dot+1:]
|
||||||
|
further_identifiers = _identifier_parse(next_identifier, quote_char)
|
||||||
|
first_identifier = first_identifier.replace(quote_char, quote_char*2)
|
||||||
|
first_identifier = ''.join((quote_char, first_identifier, quote_char))
|
||||||
|
further_identifiers.insert(0, first_identifier)
|
||||||
|
|
||||||
|
return further_identifiers
|
||||||
|
|
||||||
|
|
||||||
|
def pg_quote_identifier(identifier, id_type):
|
||||||
|
identifier_fragments = _identifier_parse(identifier, quote_char='"')
|
||||||
|
if len(identifier_fragments) > _PG_IDENTIFIER_TO_DOT_LEVEL[id_type]:
|
||||||
|
raise SQLParseError('PostgreSQL does not support %s with more than %i dots' % (id_type, _PG_IDENTIFIER_TO_DOT_LEVEL[id_type]))
|
||||||
|
return '.'.join(identifier_fragments)
|
||||||
|
|
||||||
|
def mysql_quote_identifier(identifier, id_type):
|
||||||
|
identifier_fragments = _identifier_parse(identifier, quote_char='`')
|
||||||
|
if len(identifier_fragments) > _MYSQL_IDENTIFIER_TO_DOT_LEVEL[id_type]:
|
||||||
|
raise SQLParseError('MySQL does not support %s with more than %i dots' % (id_type, _MYSQL_IDENTIFIER_TO_DOT_LEVEL[id_type]))
|
||||||
|
|
||||||
|
special_cased_fragments = []
|
||||||
|
for fragment in identifier_fragments:
|
||||||
|
if fragment == '`*`':
|
||||||
|
special_cased_fragments.append('*')
|
||||||
|
else:
|
||||||
|
special_cased_fragments.append(fragment)
|
||||||
|
|
||||||
|
return '.'.join(special_cased_fragments)
|
|
@ -267,6 +267,10 @@ class ModuleArgsParser:
|
||||||
# if we didn't see any module in the task at all, it's not a task really
|
# if we didn't see any module in the task at all, it's not a task really
|
||||||
if action is None:
|
if action is None:
|
||||||
raise AnsibleParserError("no action detected in task", obj=self._task_ds)
|
raise AnsibleParserError("no action detected in task", obj=self._task_ds)
|
||||||
|
# FIXME: disabled for now, as there are other places besides the shell/script modules where
|
||||||
|
# having variables as the sole param for the module is valid (include_vars, add_host, and group_by?)
|
||||||
|
#elif args.get('_raw_params', '') != '' and action not in ('command', 'shell', 'script', 'include_vars'):
|
||||||
|
# raise AnsibleParserError("this task has extra params, which is only allowed in the command, shell or script module.", obj=self._task_ds)
|
||||||
|
|
||||||
# shell modules require special handling
|
# shell modules require special handling
|
||||||
(action, args) = self._handle_shell_weirdness(action, args)
|
(action, args) = self._handle_shell_weirdness(action, args)
|
||||||
|
|
|
@ -45,10 +45,20 @@ class Block(Base, Conditional, Taggable):
|
||||||
|
|
||||||
super(Block, self).__init__()
|
super(Block, self).__init__()
|
||||||
|
|
||||||
def get_variables(self):
|
def get_vars(self):
|
||||||
# blocks do not (currently) store any variables directly,
|
'''
|
||||||
# so we just return an empty dict here
|
Blocks do not store variables directly, however they may be a member
|
||||||
return dict()
|
of a role or task include which does, so return those if present.
|
||||||
|
'''
|
||||||
|
|
||||||
|
all_vars = dict()
|
||||||
|
|
||||||
|
if self._role:
|
||||||
|
all_vars.update(self._role.get_vars())
|
||||||
|
if self._task_include:
|
||||||
|
all_vars.update(self._task_include.get_vars())
|
||||||
|
|
||||||
|
return all_vars
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load(data, parent_block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
def load(data, parent_block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
||||||
|
@ -73,17 +83,49 @@ class Block(Base, Conditional, Taggable):
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
def _load_block(self, attr, ds):
|
def _load_block(self, attr, ds):
|
||||||
return load_list_of_tasks(ds, block=self, role=self._role, variable_manager=self._variable_manager, loader=self._loader, use_handlers=self._use_handlers)
|
return load_list_of_tasks(
|
||||||
|
ds,
|
||||||
|
block=self,
|
||||||
|
role=self._role,
|
||||||
|
task_include=self._task_include,
|
||||||
|
variable_manager=self._variable_manager,
|
||||||
|
loader=self._loader,
|
||||||
|
use_handlers=self._use_handlers,
|
||||||
|
)
|
||||||
|
|
||||||
def _load_rescue(self, attr, ds):
|
def _load_rescue(self, attr, ds):
|
||||||
return load_list_of_tasks(ds, block=self, role=self._role, variable_manager=self._variable_manager, loader=self._loader, use_handlers=self._use_handlers)
|
return load_list_of_tasks(
|
||||||
|
ds,
|
||||||
|
block=self,
|
||||||
|
role=self._role,
|
||||||
|
task_include=self._task_include,
|
||||||
|
variable_manager=self._variable_manager,
|
||||||
|
loader=self._loader,
|
||||||
|
use_handlers=self._use_handlers,
|
||||||
|
)
|
||||||
|
|
||||||
def _load_always(self, attr, ds):
|
def _load_always(self, attr, ds):
|
||||||
return load_list_of_tasks(ds, block=self, role=self._role, variable_manager=self._variable_manager, loader=self._loader, use_handlers=self._use_handlers)
|
return load_list_of_tasks(
|
||||||
|
ds,
|
||||||
|
block=self,
|
||||||
|
role=self._role,
|
||||||
|
task_include=self._task_include,
|
||||||
|
variable_manager=self._variable_manager,
|
||||||
|
loader=self._loader,
|
||||||
|
use_handlers=self._use_handlers,
|
||||||
|
)
|
||||||
|
|
||||||
# not currently used
|
# not currently used
|
||||||
#def _load_otherwise(self, attr, ds):
|
#def _load_otherwise(self, attr, ds):
|
||||||
# return self._load_list_of_tasks(ds, block=self, role=self._role, variable_manager=self._variable_manager, loader=self._loader, use_handlers=self._use_handlers)
|
# return load_list_of_tasks(
|
||||||
|
# ds,
|
||||||
|
# block=self,
|
||||||
|
# role=self._role,
|
||||||
|
# task_include=self._task_include,
|
||||||
|
# variable_manager=self._variable_manager,
|
||||||
|
# loader=self._loader,
|
||||||
|
# use_handlers=self._use_handlers,
|
||||||
|
# )
|
||||||
|
|
||||||
def compile(self):
|
def compile(self):
|
||||||
'''
|
'''
|
||||||
|
@ -125,6 +167,8 @@ class Block(Base, Conditional, Taggable):
|
||||||
|
|
||||||
if self._role is not None:
|
if self._role is not None:
|
||||||
data['role'] = self._role.serialize()
|
data['role'] = self._role.serialize()
|
||||||
|
if self._task_include is not None:
|
||||||
|
data['task_include'] = self._task_include.serialize()
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -134,6 +178,8 @@ class Block(Base, Conditional, Taggable):
|
||||||
serialize method
|
serialize method
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
from ansible.playbook.task_include import TaskInclude
|
||||||
|
|
||||||
# unpack the when attribute, which is the only one we want
|
# unpack the when attribute, which is the only one we want
|
||||||
self.when = data.get('when')
|
self.when = data.get('when')
|
||||||
|
|
||||||
|
@ -144,7 +190,17 @@ class Block(Base, Conditional, Taggable):
|
||||||
r.deserialize(role_data)
|
r.deserialize(role_data)
|
||||||
self._role = r
|
self._role = r
|
||||||
|
|
||||||
|
# if there was a serialized task include, unpack it too
|
||||||
|
ti_data = data.get('task_include')
|
||||||
|
if ti_data:
|
||||||
|
ti = TaskInclude()
|
||||||
|
ti.deserialize(ti_data)
|
||||||
|
self._task_include = ti
|
||||||
|
|
||||||
def evaluate_conditional(self, all_vars):
|
def evaluate_conditional(self, all_vars):
|
||||||
|
if self._task_include is not None:
|
||||||
|
if not self._task_include.evaluate_conditional(all_vars):
|
||||||
|
return False
|
||||||
if self._parent_block is not None:
|
if self._parent_block is not None:
|
||||||
if not self._parent_block.evaluate_conditional(all_vars):
|
if not self._parent_block.evaluate_conditional(all_vars):
|
||||||
return False
|
return False
|
||||||
|
@ -168,3 +224,6 @@ class Block(Base, Conditional, Taggable):
|
||||||
elif self._role:
|
elif self._role:
|
||||||
self._role.set_loader(loader)
|
self._role.set_loader(loader)
|
||||||
|
|
||||||
|
if self._task_include:
|
||||||
|
self._task_include.set_loader(loader)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ def load_list_of_blocks(ds, parent_block=None, role=None, task_include=None, use
|
||||||
return a list of Block() objects, where implicit blocks
|
return a list of Block() objects, where implicit blocks
|
||||||
are created for each bare Task.
|
are created for each bare Task.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# we import here to prevent a circular dependency with imports
|
# we import here to prevent a circular dependency with imports
|
||||||
from ansible.playbook.block import Block
|
from ansible.playbook.block import Block
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,8 @@ class RoleDefinition(Base, Conditional, Taggable):
|
||||||
self._role_params = dict()
|
self._role_params = dict()
|
||||||
super(RoleDefinition, self).__init__()
|
super(RoleDefinition, self).__init__()
|
||||||
|
|
||||||
def __repr__(self):
|
#def __repr__(self):
|
||||||
return 'ROLEDEF: ' + self._attributes.get('role', '<no name set>')
|
# return 'ROLEDEF: ' + self._attributes.get('role', '<no name set>')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load(data, variable_manager=None, loader=None):
|
def load(data, variable_manager=None, loader=None):
|
||||||
|
|
|
@ -33,6 +33,7 @@ from ansible.playbook.block import Block
|
||||||
from ansible.playbook.conditional import Conditional
|
from ansible.playbook.conditional import Conditional
|
||||||
from ansible.playbook.role import Role
|
from ansible.playbook.role import Role
|
||||||
from ansible.playbook.taggable import Taggable
|
from ansible.playbook.taggable import Taggable
|
||||||
|
from ansible.playbook.task_include import TaskInclude
|
||||||
|
|
||||||
class Task(Base, Conditional, Taggable):
|
class Task(Base, Conditional, Taggable):
|
||||||
|
|
||||||
|
@ -189,16 +190,23 @@ class Task(Base, Conditional, Taggable):
|
||||||
def post_validate(self, all_vars=dict(), fail_on_undefined=True):
|
def post_validate(self, all_vars=dict(), fail_on_undefined=True):
|
||||||
'''
|
'''
|
||||||
Override of base class post_validate, to also do final validation on
|
Override of base class post_validate, to also do final validation on
|
||||||
the block to which this task belongs.
|
the block and task include (if any) to which this task belongs.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if self._block:
|
if self._block:
|
||||||
self._block.post_validate(all_vars=all_vars, fail_on_undefined=fail_on_undefined)
|
self._block.post_validate(all_vars=all_vars, fail_on_undefined=fail_on_undefined)
|
||||||
|
if self._task_include:
|
||||||
|
self._task_include.post_validate(all_vars=all_vars, fail_on_undefined=fail_on_undefined)
|
||||||
|
|
||||||
super(Task, self).post_validate(all_vars=all_vars, fail_on_undefined=fail_on_undefined)
|
super(Task, self).post_validate(all_vars=all_vars, fail_on_undefined=fail_on_undefined)
|
||||||
|
|
||||||
def get_vars(self):
|
def get_vars(self):
|
||||||
all_vars = self.serialize()
|
all_vars = dict()
|
||||||
|
if self._task_include:
|
||||||
|
all_vars.update(self._task_include.get_vars())
|
||||||
|
|
||||||
|
all_vars.update(self.serialize())
|
||||||
|
|
||||||
if 'tags' in all_vars:
|
if 'tags' in all_vars:
|
||||||
del all_vars['tags']
|
del all_vars['tags']
|
||||||
if 'when' in all_vars:
|
if 'when' in all_vars:
|
||||||
|
@ -242,6 +250,9 @@ class Task(Base, Conditional, Taggable):
|
||||||
if self._role:
|
if self._role:
|
||||||
data['role'] = self._role.serialize()
|
data['role'] = self._role.serialize()
|
||||||
|
|
||||||
|
if self._task_include:
|
||||||
|
data['task_include'] = self._task_include.serialize()
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def deserialize(self, data):
|
def deserialize(self, data):
|
||||||
|
@ -261,6 +272,13 @@ class Task(Base, Conditional, Taggable):
|
||||||
self._role = r
|
self._role = r
|
||||||
del data['role']
|
del data['role']
|
||||||
|
|
||||||
|
ti_data = data.get('task_include')
|
||||||
|
if ti_data:
|
||||||
|
ti = TaskInclude()
|
||||||
|
ti.deserialize(ti_data)
|
||||||
|
self._task_include = ti
|
||||||
|
del data['task_include']
|
||||||
|
|
||||||
super(Task, self).deserialize(data)
|
super(Task, self).deserialize(data)
|
||||||
|
|
||||||
def evaluate_conditional(self, all_vars):
|
def evaluate_conditional(self, all_vars):
|
||||||
|
@ -271,6 +289,9 @@ class Task(Base, Conditional, Taggable):
|
||||||
if self._block is not None:
|
if self._block is not None:
|
||||||
if not self._block.evaluate_conditional(all_vars):
|
if not self._block.evaluate_conditional(all_vars):
|
||||||
return False
|
return False
|
||||||
|
if self._task_include is not None:
|
||||||
|
if not self._task_include.evaluate_conditional(all_vars):
|
||||||
|
return False
|
||||||
return super(Task, self).evaluate_conditional(all_vars)
|
return super(Task, self).evaluate_conditional(all_vars)
|
||||||
|
|
||||||
def evaluate_tags(self, only_tags, skip_tags, all_vars):
|
def evaluate_tags(self, only_tags, skip_tags, all_vars):
|
||||||
|
@ -293,6 +314,8 @@ class Task(Base, Conditional, Taggable):
|
||||||
|
|
||||||
if self._block:
|
if self._block:
|
||||||
self._block.set_loader(loader)
|
self._block.set_loader(loader)
|
||||||
|
if self._task_include:
|
||||||
|
self._task_include.set_loader(loader)
|
||||||
|
|
||||||
for dep in self._dep_chain:
|
for dep in self._dep_chain:
|
||||||
dep.set_loader(loader)
|
dep.set_loader(loader)
|
||||||
|
|
|
@ -24,14 +24,16 @@ from ansible.parsing.splitter import split_args, parse_kv
|
||||||
from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleMapping
|
from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleMapping
|
||||||
from ansible.playbook.attribute import Attribute, FieldAttribute
|
from ansible.playbook.attribute import Attribute, FieldAttribute
|
||||||
from ansible.playbook.base import Base
|
from ansible.playbook.base import Base
|
||||||
|
from ansible.playbook.conditional import Conditional
|
||||||
from ansible.playbook.helpers import load_list_of_blocks, compile_block_list
|
from ansible.playbook.helpers import load_list_of_blocks, compile_block_list
|
||||||
|
from ansible.playbook.taggable import Taggable
|
||||||
from ansible.plugins import lookup_loader
|
from ansible.plugins import lookup_loader
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['TaskInclude']
|
__all__ = ['TaskInclude']
|
||||||
|
|
||||||
|
|
||||||
class TaskInclude(Base):
|
class TaskInclude(Base, Conditional, Taggable):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
A class used to wrap the use of `include: /some/other/file.yml`
|
A class used to wrap the use of `include: /some/other/file.yml`
|
||||||
|
@ -146,13 +148,13 @@ class TaskInclude(Base):
|
||||||
raise AnsibleParsingError("included task files must contain a list of tasks", obj=ds)
|
raise AnsibleParsingError("included task files must contain a list of tasks", obj=ds)
|
||||||
|
|
||||||
self._task_blocks = load_list_of_blocks(
|
self._task_blocks = load_list_of_blocks(
|
||||||
data,
|
data,
|
||||||
parent_block=self._block,
|
parent_block=self._block,
|
||||||
task_include=self,
|
task_include=self,
|
||||||
role=self._role,
|
role=self._role,
|
||||||
use_handlers=self._use_handlers,
|
use_handlers=self._use_handlers,
|
||||||
loader=self._loader
|
loader=self._loader
|
||||||
)
|
)
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
def compile(self):
|
def compile(self):
|
||||||
|
@ -164,3 +166,77 @@ class TaskInclude(Base):
|
||||||
task_list.extend(compile_block_list(self._task_blocks))
|
task_list.extend(compile_block_list(self._task_blocks))
|
||||||
return task_list
|
return task_list
|
||||||
|
|
||||||
|
def get_vars(self):
|
||||||
|
'''
|
||||||
|
Returns the vars for this task include, but also first merges in
|
||||||
|
those from any parent task include which may exist.
|
||||||
|
'''
|
||||||
|
|
||||||
|
all_vars = dict()
|
||||||
|
if self._task_include:
|
||||||
|
all_vars.update(self._task_include.get_vars())
|
||||||
|
all_vars.update(self.vars)
|
||||||
|
return all_vars
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
|
||||||
|
data = super(TaskInclude, self).serialize()
|
||||||
|
|
||||||
|
if self._block:
|
||||||
|
data['block'] = self._block.serialize()
|
||||||
|
|
||||||
|
if self._role:
|
||||||
|
data['role'] = self._role.serialize()
|
||||||
|
|
||||||
|
if self._task_include:
|
||||||
|
data['task_include'] = self._task_include.serialize()
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def deserialize(self, data):
|
||||||
|
|
||||||
|
# import here to prevent circular importing issues
|
||||||
|
from ansible.playbook.block import Block
|
||||||
|
from ansible.playbook.role import Role
|
||||||
|
|
||||||
|
block_data = data.get('block')
|
||||||
|
if block_data:
|
||||||
|
b = Block()
|
||||||
|
b.deserialize(block_data)
|
||||||
|
self._block = b
|
||||||
|
del data['block']
|
||||||
|
|
||||||
|
role_data = data.get('role')
|
||||||
|
if role_data:
|
||||||
|
r = Role()
|
||||||
|
r.deserialize(role_data)
|
||||||
|
self._role = r
|
||||||
|
del data['role']
|
||||||
|
|
||||||
|
ti_data = data.get('task_include')
|
||||||
|
if ti_data:
|
||||||
|
ti = TaskInclude()
|
||||||
|
ti.deserialize(ti_data)
|
||||||
|
self._task_include = ti
|
||||||
|
del data['task_include']
|
||||||
|
|
||||||
|
super(TaskInclude, self).deserialize(data)
|
||||||
|
|
||||||
|
def evaluate_conditional(self, all_vars):
|
||||||
|
if self._task_include is not None:
|
||||||
|
if not self._task_include.evaluate_conditional(all_vars):
|
||||||
|
return False
|
||||||
|
if self._block is not None:
|
||||||
|
if not self._block.evaluate_conditional(all_vars):
|
||||||
|
return False
|
||||||
|
elif self._role is not None:
|
||||||
|
if not self._role.evaluate_conditional(all_vars):
|
||||||
|
return False
|
||||||
|
return super(TaskInclude, self).evaluate_conditional(all_vars)
|
||||||
|
|
||||||
|
def set_loader(self, loader):
|
||||||
|
self._loader = loader
|
||||||
|
if self._block:
|
||||||
|
self._block.set_loader(loader)
|
||||||
|
elif self._task_include:
|
||||||
|
self._task_include.set_loader(loader)
|
||||||
|
|
|
@ -121,6 +121,7 @@ import os
|
||||||
|
|
||||||
from ansible.plugins.lookup import LookupBase
|
from ansible.plugins.lookup import LookupBase
|
||||||
from ansible.template import Templar
|
from ansible.template import Templar
|
||||||
|
from ansible.utils.boolean import boolean
|
||||||
|
|
||||||
class LookupModule(LookupBase):
|
class LookupModule(LookupBase):
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ class StrategyModule(StrategyBase):
|
||||||
debug("'%s' skipped because role has already run" % task)
|
debug("'%s' skipped because role has already run" % task)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not task.evaluate_tags(connection_info.only_tags, connection_info.skip_tags, task_vars):
|
if not task.evaluate_tags(connection_info.only_tags, connection_info.skip_tags, task_vars) and task.action != 'setup':
|
||||||
debug("'%s' failed tag evaluation" % task)
|
debug("'%s' failed tag evaluation" % task)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue