mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-06-27 18:50:21 -07:00
Add play to the parent object structures for inheritence in v2
This commit is contained in:
parent
fb96173d10
commit
aafda44bb3
9 changed files with 98 additions and 44 deletions
|
@ -324,6 +324,20 @@ class Base:
|
||||||
# restore the UUID field
|
# restore the UUID field
|
||||||
setattr(self, '_uuid', data.get('uuid'))
|
setattr(self, '_uuid', data.get('uuid'))
|
||||||
|
|
||||||
|
def _extend_value(self, value, new_value):
|
||||||
|
'''
|
||||||
|
Will extend the value given with new_value (and will turn both
|
||||||
|
into lists if they are not so already). The values are run through
|
||||||
|
a set to remove duplicate values.
|
||||||
|
'''
|
||||||
|
|
||||||
|
if not isinstance(value, list):
|
||||||
|
value = [ value ]
|
||||||
|
if not isinstance(new_value, list):
|
||||||
|
new_value = [ new_value ]
|
||||||
|
|
||||||
|
return list(set(value + new_value))
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
return self.serialize()
|
return self.serialize()
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,11 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
# similar to the 'else' clause for exceptions
|
# similar to the 'else' clause for exceptions
|
||||||
#_otherwise = FieldAttribute(isa='list')
|
#_otherwise = FieldAttribute(isa='list')
|
||||||
|
|
||||||
def __init__(self, parent_block=None, role=None, task_include=None, use_handlers=False):
|
def __init__(self, play=None, parent_block=None, role=None, task_include=None, use_handlers=False):
|
||||||
self._parent_block = parent_block
|
self._play = play
|
||||||
self._role = role
|
self._role = role
|
||||||
self._task_include = task_include
|
self._task_include = task_include
|
||||||
|
self._parent_block = parent_block
|
||||||
self._use_handlers = use_handlers
|
self._use_handlers = use_handlers
|
||||||
self._dep_chain = []
|
self._dep_chain = []
|
||||||
|
|
||||||
|
@ -65,8 +66,8 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
return all_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, play, parent_block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
||||||
b = Block(parent_block=parent_block, role=role, task_include=task_include, use_handlers=use_handlers)
|
b = Block(play=play, parent_block=parent_block, role=role, task_include=task_include, use_handlers=use_handlers)
|
||||||
return b.load_data(data, variable_manager=variable_manager, loader=loader)
|
return b.load_data(data, variable_manager=variable_manager, loader=loader)
|
||||||
|
|
||||||
def preprocess_data(self, ds):
|
def preprocess_data(self, ds):
|
||||||
|
@ -92,6 +93,7 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
def _load_block(self, attr, ds):
|
def _load_block(self, attr, ds):
|
||||||
return load_list_of_tasks(
|
return load_list_of_tasks(
|
||||||
ds,
|
ds,
|
||||||
|
play=self._play,
|
||||||
block=self,
|
block=self,
|
||||||
role=self._role,
|
role=self._role,
|
||||||
task_include=self._task_include,
|
task_include=self._task_include,
|
||||||
|
@ -103,6 +105,7 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
def _load_rescue(self, attr, ds):
|
def _load_rescue(self, attr, ds):
|
||||||
return load_list_of_tasks(
|
return load_list_of_tasks(
|
||||||
ds,
|
ds,
|
||||||
|
play=self._play,
|
||||||
block=self,
|
block=self,
|
||||||
role=self._role,
|
role=self._role,
|
||||||
task_include=self._task_include,
|
task_include=self._task_include,
|
||||||
|
@ -114,6 +117,7 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
def _load_always(self, attr, ds):
|
def _load_always(self, attr, ds):
|
||||||
return load_list_of_tasks(
|
return load_list_of_tasks(
|
||||||
ds,
|
ds,
|
||||||
|
play=self._play,
|
||||||
block=self,
|
block=self,
|
||||||
role=self._role,
|
role=self._role,
|
||||||
task_include=self._task_include,
|
task_include=self._task_include,
|
||||||
|
@ -126,6 +130,7 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
#def _load_otherwise(self, attr, ds):
|
#def _load_otherwise(self, attr, ds):
|
||||||
# return load_list_of_tasks(
|
# return load_list_of_tasks(
|
||||||
# ds,
|
# ds,
|
||||||
|
# play=self._play,
|
||||||
# block=self,
|
# block=self,
|
||||||
# role=self._role,
|
# role=self._role,
|
||||||
# task_include=self._task_include,
|
# task_include=self._task_include,
|
||||||
|
@ -148,6 +153,7 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
return new_task_list
|
return new_task_list
|
||||||
|
|
||||||
new_me = super(Block, self).copy()
|
new_me = super(Block, self).copy()
|
||||||
|
new_me._play = self._play
|
||||||
new_me._use_handlers = self._use_handlers
|
new_me._use_handlers = self._use_handlers
|
||||||
new_me._dep_chain = self._dep_chain[:]
|
new_me._dep_chain = self._dep_chain[:]
|
||||||
|
|
||||||
|
@ -248,24 +254,44 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
for dep in self._dep_chain:
|
for dep in self._dep_chain:
|
||||||
dep.set_loader(loader)
|
dep.set_loader(loader)
|
||||||
|
|
||||||
def _get_parent_attribute(self, attr):
|
def _get_parent_attribute(self, attr, extend=False):
|
||||||
'''
|
'''
|
||||||
Generic logic to get the attribute or parent attribute for a block value.
|
Generic logic to get the attribute or parent attribute for a block value.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
value = self._attributes[attr]
|
value = self._attributes[attr]
|
||||||
if not value:
|
if self._parent_block and (not value or extend):
|
||||||
if self._parent_block:
|
parent_value = getattr(self._parent_block, attr)
|
||||||
value = getattr(self._parent_block, attr)
|
if extend:
|
||||||
elif self._role:
|
value = self._extend_value(value, parent_value)
|
||||||
value = getattr(self._role, attr)
|
else:
|
||||||
if not value and len(self._dep_chain):
|
value = parent_value
|
||||||
reverse_dep_chain = self._dep_chain[:]
|
if self._task_include and (not value or extend):
|
||||||
reverse_dep_chain.reverse()
|
parent_value = getattr(self._task_include, attr)
|
||||||
for dep in reverse_dep_chain:
|
if extend:
|
||||||
value = getattr(dep, attr)
|
value = self._extend_value(value, parent_value)
|
||||||
if value:
|
else:
|
||||||
break
|
value = parent_value
|
||||||
|
if self._role and (not value or extend):
|
||||||
|
parent_value = getattr(self._role, attr)
|
||||||
|
if len(self._dep_chain) and (not value or extend):
|
||||||
|
reverse_dep_chain = self._dep_chain[:]
|
||||||
|
reverse_dep_chain.reverse()
|
||||||
|
for dep in reverse_dep_chain:
|
||||||
|
dep_value = getattr(dep, attr)
|
||||||
|
if extend:
|
||||||
|
value = self._extend_value(value, parent_value)
|
||||||
|
else:
|
||||||
|
value = parent_value
|
||||||
|
|
||||||
|
if value and not extend:
|
||||||
|
break
|
||||||
|
if self._play and (not value or extend):
|
||||||
|
parent_value = getattr(self._play, attr)
|
||||||
|
if extend:
|
||||||
|
value = self._extend_value(value, parent_value)
|
||||||
|
else:
|
||||||
|
value = parent_value
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ from ansible.errors import AnsibleParserError
|
||||||
from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleSequence
|
from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleSequence
|
||||||
|
|
||||||
|
|
||||||
def load_list_of_blocks(ds, parent_block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
def load_list_of_blocks(ds, play, parent_block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
||||||
'''
|
'''
|
||||||
Given a list of mixed task/block data (parsed from YAML),
|
Given a list of mixed task/block data (parsed from YAML),
|
||||||
return a list of Block() objects, where implicit blocks
|
return a list of Block() objects, where implicit blocks
|
||||||
|
@ -43,6 +43,7 @@ def load_list_of_blocks(ds, parent_block=None, role=None, task_include=None, use
|
||||||
for block in ds:
|
for block in ds:
|
||||||
b = Block.load(
|
b = Block.load(
|
||||||
block,
|
block,
|
||||||
|
play=play,
|
||||||
parent_block=parent_block,
|
parent_block=parent_block,
|
||||||
role=role,
|
role=role,
|
||||||
task_include=task_include,
|
task_include=task_include,
|
||||||
|
@ -55,7 +56,7 @@ def load_list_of_blocks(ds, parent_block=None, role=None, task_include=None, use
|
||||||
return block_list
|
return block_list
|
||||||
|
|
||||||
|
|
||||||
def load_list_of_tasks(ds, block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_handlers=False, variable_manager=None, loader=None):
|
||||||
'''
|
'''
|
||||||
Given a list of task datastructures (parsed from YAML),
|
Given a list of task datastructures (parsed from YAML),
|
||||||
return a list of Task() or TaskInclude() objects.
|
return a list of Task() or TaskInclude() objects.
|
||||||
|
@ -76,6 +77,7 @@ def load_list_of_tasks(ds, block=None, role=None, task_include=None, use_handler
|
||||||
if 'block' in task:
|
if 'block' in task:
|
||||||
t = Block.load(
|
t = Block.load(
|
||||||
task,
|
task,
|
||||||
|
play=play,
|
||||||
parent_block=block,
|
parent_block=block,
|
||||||
role=role,
|
role=role,
|
||||||
task_include=task_include,
|
task_include=task_include,
|
||||||
|
|
|
@ -145,28 +145,28 @@ class Play(Base, Taggable, Become):
|
||||||
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
||||||
Bare tasks outside of a block are given an implicit block.
|
Bare tasks outside of a block are given an implicit block.
|
||||||
'''
|
'''
|
||||||
return load_list_of_blocks(ds, variable_manager=self._variable_manager, loader=self._loader)
|
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
|
||||||
|
|
||||||
def _load_pre_tasks(self, attr, ds):
|
def _load_pre_tasks(self, attr, ds):
|
||||||
'''
|
'''
|
||||||
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
||||||
Bare tasks outside of a block are given an implicit block.
|
Bare tasks outside of a block are given an implicit block.
|
||||||
'''
|
'''
|
||||||
return load_list_of_blocks(ds, variable_manager=self._variable_manager, loader=self._loader)
|
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
|
||||||
|
|
||||||
def _load_post_tasks(self, attr, ds):
|
def _load_post_tasks(self, attr, ds):
|
||||||
'''
|
'''
|
||||||
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
Loads a list of blocks from a list which may be mixed tasks/blocks.
|
||||||
Bare tasks outside of a block are given an implicit block.
|
Bare tasks outside of a block are given an implicit block.
|
||||||
'''
|
'''
|
||||||
return load_list_of_blocks(ds, variable_manager=self._variable_manager, loader=self._loader)
|
return load_list_of_blocks(ds=ds, play=self, variable_manager=self._variable_manager, loader=self._loader)
|
||||||
|
|
||||||
def _load_handlers(self, attr, ds):
|
def _load_handlers(self, attr, ds):
|
||||||
'''
|
'''
|
||||||
Loads a list of blocks from a list which may be mixed handlers/blocks.
|
Loads a list of blocks from a list which may be mixed handlers/blocks.
|
||||||
Bare handlers outside of a block are given an implicit block.
|
Bare handlers outside of a block are given an implicit block.
|
||||||
'''
|
'''
|
||||||
return load_list_of_blocks(ds, use_handlers=True, variable_manager=self._variable_manager, loader=self._loader)
|
return load_list_of_blocks(ds=ds, play=self, use_handlers=True, variable_manager=self._variable_manager, loader=self._loader)
|
||||||
|
|
||||||
def _load_roles(self, attr, ds):
|
def _load_roles(self, attr, ds):
|
||||||
'''
|
'''
|
||||||
|
@ -196,7 +196,7 @@ class Play(Base, Taggable, Become):
|
||||||
|
|
||||||
if len(self.roles) > 0:
|
if len(self.roles) > 0:
|
||||||
for r in self.roles:
|
for r in self.roles:
|
||||||
block_list.extend(r.compile())
|
block_list.extend(r.compile(play=self))
|
||||||
|
|
||||||
return block_list
|
return block_list
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ class Role(Base, Become, Conditional, Taggable):
|
||||||
self._loader = None
|
self._loader = None
|
||||||
|
|
||||||
self._metadata = None
|
self._metadata = None
|
||||||
|
self._play = None
|
||||||
self._parents = []
|
self._parents = []
|
||||||
self._dependencies = []
|
self._dependencies = []
|
||||||
self._task_blocks = []
|
self._task_blocks = []
|
||||||
|
@ -163,11 +164,11 @@ class Role(Base, Become, Conditional, Taggable):
|
||||||
|
|
||||||
task_data = self._load_role_yaml('tasks')
|
task_data = self._load_role_yaml('tasks')
|
||||||
if task_data:
|
if task_data:
|
||||||
self._task_blocks = load_list_of_blocks(task_data, role=self, loader=self._loader)
|
self._task_blocks = load_list_of_blocks(task_data, play=None, role=self, loader=self._loader)
|
||||||
|
|
||||||
handler_data = self._load_role_yaml('handlers')
|
handler_data = self._load_role_yaml('handlers')
|
||||||
if handler_data:
|
if handler_data:
|
||||||
self._handler_blocks = load_list_of_blocks(handler_data, role=self, loader=self._loader)
|
self._handler_blocks = load_list_of_blocks(handler_data, play=None, role=self, loader=self._loader)
|
||||||
|
|
||||||
# vars and default vars are regular dictionaries
|
# vars and default vars are regular dictionaries
|
||||||
self._role_vars = self._load_role_yaml('vars')
|
self._role_vars = self._load_role_yaml('vars')
|
||||||
|
@ -293,7 +294,7 @@ class Role(Base, Become, Conditional, Taggable):
|
||||||
|
|
||||||
return self._had_task_run and self._completed
|
return self._had_task_run and self._completed
|
||||||
|
|
||||||
def compile(self, dep_chain=[]):
|
def compile(self, play, dep_chain=[]):
|
||||||
'''
|
'''
|
||||||
Returns the task list for this role, which is created by first
|
Returns the task list for this role, which is created by first
|
||||||
recursively compiling the tasks for all direct dependencies, and
|
recursively compiling the tasks for all direct dependencies, and
|
||||||
|
@ -311,10 +312,11 @@ class Role(Base, Become, Conditional, Taggable):
|
||||||
|
|
||||||
deps = self.get_direct_dependencies()
|
deps = self.get_direct_dependencies()
|
||||||
for dep in deps:
|
for dep in deps:
|
||||||
dep_blocks = dep.compile(dep_chain=new_dep_chain)
|
dep_blocks = dep.compile(play=play, dep_chain=new_dep_chain)
|
||||||
for dep_block in dep_blocks:
|
for dep_block in dep_blocks:
|
||||||
new_dep_block = dep_block.copy()
|
new_dep_block = dep_block.copy()
|
||||||
new_dep_block._dep_chain = new_dep_chain
|
new_dep_block._dep_chain = new_dep_chain
|
||||||
|
new_dep_block._play = play
|
||||||
block_list.append(new_dep_block)
|
block_list.append(new_dep_block)
|
||||||
|
|
||||||
block_list.extend(self._task_blocks)
|
block_list.extend(self._task_blocks)
|
||||||
|
|
|
@ -26,7 +26,7 @@ from ansible.template import Templar
|
||||||
class Taggable:
|
class Taggable:
|
||||||
|
|
||||||
untagged = set(['untagged'])
|
untagged = set(['untagged'])
|
||||||
_tags = FieldAttribute(isa='list', default=[])
|
_tags = FieldAttribute(isa='list', default=None)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Taggable, self).__init__()
|
super(Taggable, self).__init__()
|
||||||
|
@ -44,9 +44,11 @@ class Taggable:
|
||||||
Override for the 'tags' getattr fetcher, used from Base.
|
Override for the 'tags' getattr fetcher, used from Base.
|
||||||
'''
|
'''
|
||||||
tags = self._attributes['tags']
|
tags = self._attributes['tags']
|
||||||
|
if tags is None:
|
||||||
|
tags = []
|
||||||
if hasattr(self, '_get_parent_attribute'):
|
if hasattr(self, '_get_parent_attribute'):
|
||||||
tags.extend(self._get_parent_attribute('tags'))
|
tags = self._get_parent_attribute('tags', extend=True)
|
||||||
return list(set(tags))
|
return tags
|
||||||
|
|
||||||
def evaluate_tags(self, only_tags, skip_tags, all_vars):
|
def evaluate_tags(self, only_tags, skip_tags, all_vars):
|
||||||
''' this checks if the current item should be executed depending on tag options '''
|
''' this checks if the current item should be executed depending on tag options '''
|
||||||
|
|
|
@ -205,16 +205,6 @@ class Task(Base, Conditional, Taggable, Become):
|
||||||
del all_vars['when']
|
del all_vars['when']
|
||||||
return all_vars
|
return all_vars
|
||||||
|
|
||||||
# no longer used, as blocks are the lowest level of compilation now
|
|
||||||
#def compile(self):
|
|
||||||
# '''
|
|
||||||
# For tasks, this is just a dummy method returning an array
|
|
||||||
# with 'self' in it, so we don't have to care about task types
|
|
||||||
# further up the chain.
|
|
||||||
# '''
|
|
||||||
#
|
|
||||||
# return [self]
|
|
||||||
|
|
||||||
def copy(self, exclude_block=False):
|
def copy(self, exclude_block=False):
|
||||||
new_me = super(Task, self).copy()
|
new_me = super(Task, self).copy()
|
||||||
|
|
||||||
|
@ -299,12 +289,22 @@ class Task(Base, Conditional, Taggable, Become):
|
||||||
if self._task_include:
|
if self._task_include:
|
||||||
self._task_include.set_loader(loader)
|
self._task_include.set_loader(loader)
|
||||||
|
|
||||||
def _get_parent_attribute(self, attr):
|
def _get_parent_attribute(self, attr, extend=False):
|
||||||
'''
|
'''
|
||||||
Generic logic to get the attribute or parent attribute for a task value.
|
Generic logic to get the attribute or parent attribute for a task value.
|
||||||
'''
|
'''
|
||||||
value = self._attributes[attr]
|
value = self._attributes[attr]
|
||||||
if not value and self._block:
|
if self._block and (not value or extend):
|
||||||
value = getattr(self._block, attr)
|
parent_value = getattr(self._block, attr)
|
||||||
|
if extend:
|
||||||
|
value = self._extend_value(value, parent_value)
|
||||||
|
else:
|
||||||
|
value = parent_value
|
||||||
|
if self._task_include and (not value or extend):
|
||||||
|
parent_value = getattr(self._task_include, attr)
|
||||||
|
if extend:
|
||||||
|
value = self._extend_value(value, parent_value)
|
||||||
|
else:
|
||||||
|
value = parent_value
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,7 @@ class StrategyBase:
|
||||||
is_handler = isinstance(included_file._task, Handler)
|
is_handler = isinstance(included_file._task, Handler)
|
||||||
block_list = load_list_of_blocks(
|
block_list = load_list_of_blocks(
|
||||||
data,
|
data,
|
||||||
|
play=included_file._task._block._play,
|
||||||
parent_block=included_file._task._block,
|
parent_block=included_file._task._block,
|
||||||
task_include=included_file._task,
|
task_include=included_file._task,
|
||||||
role=included_file._task._role,
|
role=included_file._task._role,
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
gather_facts: no
|
gather_facts: no
|
||||||
|
vars:
|
||||||
|
a: "tags"
|
||||||
|
tags:
|
||||||
|
- play
|
||||||
tasks:
|
tasks:
|
||||||
- block:
|
- block:
|
||||||
- debug: msg="this is the tagged block"
|
- debug: msg="this is the tagged block"
|
||||||
tags:
|
tags:
|
||||||
- block
|
- block
|
||||||
|
- include: include.yml
|
||||||
|
tags:
|
||||||
|
- include
|
||||||
- block:
|
- block:
|
||||||
- debug: msg="tagged debug from second block"
|
- debug: msg="tagged debug from second block"
|
||||||
tags:
|
tags:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue