1
0
Fork 0
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:
James Cammarata 2015-08-28 15:54:20 -04:00
parent ee7f7a82a8
commit 0859ba7726
4 changed files with 24 additions and 40 deletions

View file

@ -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)

View file

@ -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

View file

@ -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):

View file

@ -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):