mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Adjust field loading order for vars and tweak post_validate exclusion logic
FieldAttributes will now by default not be post_validated unless a flag is set on them in the class, as a large number of fields are really there simply to be inherited by Task/PlayContext and shouldn't be templated too early. The other (unrelated to the base issue) in #12084 is also fixed here, where the roles field is loaded before vars/vars_files, meaning there are no vars yet loaded in the play when the templating occurs. Fixes #12084
This commit is contained in:
parent
ee7f7a82a8
commit
0859ba7726
4 changed files with 24 additions and 40 deletions
|
@ -21,7 +21,7 @@ __metaclass__ = type
|
||||||
|
|
||||||
class Attribute:
|
class Attribute:
|
||||||
|
|
||||||
def __init__(self, isa=None, private=False, default=None, required=False, listof=None, priority=0):
|
def __init__(self, isa=None, private=False, default=None, required=False, listof=None, priority=0, always_post_validate=False):
|
||||||
|
|
||||||
self.isa = isa
|
self.isa = isa
|
||||||
self.private = private
|
self.private = private
|
||||||
|
@ -29,6 +29,7 @@ class Attribute:
|
||||||
self.required = required
|
self.required = required
|
||||||
self.listof = listof
|
self.listof = listof
|
||||||
self.priority = priority
|
self.priority = priority
|
||||||
|
self.always_post_validate = always_post_validate
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
return cmp(other.priority, self.priority)
|
return cmp(other.priority, self.priority)
|
||||||
|
|
|
@ -48,7 +48,7 @@ class Base:
|
||||||
_remote_user = FieldAttribute(isa='string')
|
_remote_user = FieldAttribute(isa='string')
|
||||||
|
|
||||||
# variables
|
# variables
|
||||||
_vars = FieldAttribute(isa='dict', default=dict())
|
_vars = FieldAttribute(isa='dict', default=dict(), priority=100)
|
||||||
|
|
||||||
# flags and misc. settings
|
# flags and misc. settings
|
||||||
_environment = FieldAttribute(isa='list')
|
_environment = FieldAttribute(isa='list')
|
||||||
|
@ -266,6 +266,11 @@ class Base:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
raise AnsibleParserError("the field '%s' is required but was not set" % name)
|
raise AnsibleParserError("the field '%s' is required but was not set" % name)
|
||||||
|
elif not attribute.always_post_validate and self.__class__.__name__ not in ('Task', 'PlayContext'):
|
||||||
|
# Intermediate objects like Play() won't have their fields validated by
|
||||||
|
# default, as their values are often inherited by other objects and validated
|
||||||
|
# later, so we don't want them to fail out early
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Run the post-validator if present. These methods are responsible for
|
# Run the post-validator if present. These methods are responsible for
|
||||||
|
|
|
@ -52,22 +52,22 @@ class Play(Base, Taggable, Become):
|
||||||
# Connection-Related Attributes
|
# Connection-Related Attributes
|
||||||
|
|
||||||
# TODO: generalize connection
|
# TODO: generalize connection
|
||||||
_accelerate = FieldAttribute(isa='bool', default=False)
|
_accelerate = FieldAttribute(isa='bool', default=False, always_post_validate=True)
|
||||||
_accelerate_ipv6 = FieldAttribute(isa='bool', default=False)
|
_accelerate_ipv6 = FieldAttribute(isa='bool', default=False, always_post_validate=True)
|
||||||
_accelerate_port = FieldAttribute(isa='int', default=5099) # should be alias of port
|
_accelerate_port = FieldAttribute(isa='int', default=5099, always_post_validate=True)
|
||||||
|
|
||||||
# Connection
|
# Connection
|
||||||
_gather_facts = FieldAttribute(isa='bool', default=None)
|
_gather_facts = FieldAttribute(isa='bool', default=None, always_post_validate=True)
|
||||||
_hosts = FieldAttribute(isa='list', default=[], required=True, listof=string_types)
|
_hosts = FieldAttribute(isa='list', default=[], required=True, listof=string_types, always_post_validate=True)
|
||||||
_name = FieldAttribute(isa='string', default='')
|
_name = FieldAttribute(isa='string', default='', always_post_validate=True)
|
||||||
|
|
||||||
# Variable Attributes
|
# Variable Attributes
|
||||||
_vars_files = FieldAttribute(isa='list', default=[])
|
_vars_files = FieldAttribute(isa='list', default=[], priority=99)
|
||||||
_vars_prompt = FieldAttribute(isa='list', default=[])
|
_vars_prompt = FieldAttribute(isa='list', default=[], always_post_validate=True)
|
||||||
_vault_password = FieldAttribute(isa='string')
|
_vault_password = FieldAttribute(isa='string', always_post_validate=True)
|
||||||
|
|
||||||
# Role Attributes
|
# Role Attributes
|
||||||
_roles = FieldAttribute(isa='list', default=[], priority=100)
|
_roles = FieldAttribute(isa='list', default=[], priority=90)
|
||||||
|
|
||||||
# Block (Task) Lists Attributes
|
# Block (Task) Lists Attributes
|
||||||
_handlers = FieldAttribute(isa='list', default=[])
|
_handlers = FieldAttribute(isa='list', default=[])
|
||||||
|
@ -76,11 +76,11 @@ class Play(Base, Taggable, Become):
|
||||||
_tasks = FieldAttribute(isa='list', default=[])
|
_tasks = FieldAttribute(isa='list', default=[])
|
||||||
|
|
||||||
# Flag/Setting Attributes
|
# Flag/Setting Attributes
|
||||||
_any_errors_fatal = FieldAttribute(isa='bool', default=False)
|
_any_errors_fatal = FieldAttribute(isa='bool', default=False, always_post_validate=True)
|
||||||
_force_handlers = FieldAttribute(isa='bool')
|
_force_handlers = FieldAttribute(isa='bool', always_post_validate=True)
|
||||||
_max_fail_percentage = FieldAttribute(isa='percent')
|
_max_fail_percentage = FieldAttribute(isa='percent', always_post_validate=True)
|
||||||
_serial = FieldAttribute(isa='int', default=0)
|
_serial = FieldAttribute(isa='int', default=0, always_post_validate=True)
|
||||||
_strategy = FieldAttribute(isa='string', default='linear')
|
_strategy = FieldAttribute(isa='string', default='linear', always_post_validate=True)
|
||||||
|
|
||||||
# =================================================================================
|
# =================================================================================
|
||||||
|
|
||||||
|
@ -191,28 +191,6 @@ class Play(Base, Taggable, Become):
|
||||||
roles.append(Role.load(ri, play=self))
|
roles.append(Role.load(ri, play=self))
|
||||||
return roles
|
return roles
|
||||||
|
|
||||||
def _post_validate_vars(self, attr, value, templar):
|
|
||||||
'''
|
|
||||||
Override post validation of vars on the play, as we don't want to
|
|
||||||
template these too early.
|
|
||||||
'''
|
|
||||||
return value
|
|
||||||
|
|
||||||
def _post_validate_vars_files(self, attr, value, templar):
|
|
||||||
'''
|
|
||||||
Override post validation of vars_files on the play, as we don't want to
|
|
||||||
template these too early.
|
|
||||||
'''
|
|
||||||
return value
|
|
||||||
|
|
||||||
# disable validation on various fields which will be validated later in other objects
|
|
||||||
def _post_validate_become(self, attr, value, templar):
|
|
||||||
return value
|
|
||||||
def _post_validate_become_user(self, attr, value, templar):
|
|
||||||
return value
|
|
||||||
def _post_validate_become_method(self, attr, value, templar):
|
|
||||||
return value
|
|
||||||
|
|
||||||
# FIXME: post_validation needs to ensure that become/su/sudo have only 1 set
|
# FIXME: post_validation needs to ensure that become/su/sudo have only 1 set
|
||||||
|
|
||||||
def _compile_roles(self):
|
def _compile_roles(self):
|
||||||
|
|
|
@ -119,7 +119,7 @@ class RoleDefinition(Base, Become, Conditional, Taggable):
|
||||||
|
|
||||||
# if we have the required datastructures, and if the role_name
|
# if we have the required datastructures, and if the role_name
|
||||||
# contains a variable, try and template it now
|
# contains a variable, try and template it now
|
||||||
if self._play and self._variable_manager:
|
if self._variable_manager:
|
||||||
all_vars = self._variable_manager.get_vars(loader=self._loader, play=self._play)
|
all_vars = self._variable_manager.get_vars(loader=self._loader, play=self._play)
|
||||||
templar = Templar(loader=self._loader, variables=all_vars)
|
templar = Templar(loader=self._loader, variables=all_vars)
|
||||||
if templar._contains_vars(role_name):
|
if templar._contains_vars(role_name):
|
||||||
|
|
Loading…
Reference in a new issue