summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2016-11-07 16:10:51 -0600
committerJames Cammarata <jimi@sngx.net>2016-11-07 16:10:51 -0600
commitb03fed804d41382a5e4002db08d56789244ed0a9 (patch)
treeecf8a2e39e7a5966cd4f53e58fd6a02311bade41
parenta0f27d552c4bee9374ab224cb969119e5d9c0cc5 (diff)
downloadansible-issue_18378_handler_environment_inheritance.tar.gz
Add flag to Attributes to allow forcing parent inheritenceissue_18378_handler_environment_inheritance
In some situations, where the Base class defines an Attribute, the BaseMeta class doesn't properly see the _get_parent_attribute or _get_attr_<whatever> methods because of multiple layers of subclasses (ie. Handler, which subclasses Task). Fixes #18378
-rw-r--r--lib/ansible/playbook/attribute.py27
-rw-r--r--lib/ansible/playbook/base.py21
2 files changed, 37 insertions, 11 deletions
diff --git a/lib/ansible/playbook/attribute.py b/lib/ansible/playbook/attribute.py
index 3f55936ff6..f401eee3d7 100644
--- a/lib/ansible/playbook/attribute.py
+++ b/lib/ansible/playbook/attribute.py
@@ -23,17 +23,42 @@ from copy import deepcopy
class Attribute:
- def __init__(self, isa=None, private=False, default=None, required=False, listof=None, priority=0, class_type=None, always_post_validate=False, inherit=True):
+ def __init__(
+ self,
+ isa=None,
+ private=False,
+ default=None,
+ required=False,
+ listof=None,
+ priority=0,
+ class_type=None,
+ always_post_validate=False,
+ inherit=True,
+ force_parent=False,
+ ):
+ # the type of the field (string, bool, int, etc.)
self.isa = isa
+ # whether the value of the attribute is private
self.private = private
+ # the default value of the attribute, if not specified in the YAML
self.default = default
+ # if required and not set, an error will be raised
self.required = required
+ # if isa == 'list', this field can be used to control the types
+ # of each element in the list for validation purposes
self.listof = listof
+ # the loading priority of the attribute
self.priority = priority
+ # the class type of the attribute when isa == 'class'
self.class_type = class_type
+ # whether or not the attribute should be post validated
self.always_post_validate = always_post_validate
+ # whether or not the attribute should be inherited from the parent
self.inherit = inherit
+ # force inheritence from the parent, even if _get_parent_attribute
+ # is not found in the class
+ self.force_parent = force_parent
if default is not None and self.isa in ('list', 'dict', 'set'):
self.default = deepcopy(default)
diff --git a/lib/ansible/playbook/base.py b/lib/ansible/playbook/base.py
index 77fd6890b5..f76927653f 100644
--- a/lib/ansible/playbook/base.py
+++ b/lib/ansible/playbook/base.py
@@ -111,7 +111,7 @@ class BaseMeta(type):
method = "_get_attr_%s" % attr_name
if method in src_dict or method in dst_dict:
getter = partial(_generic_g_method, attr_name)
- elif '_get_parent_attribute' in dst_dict and value.inherit:
+ elif '_get_parent_attribute' in dst_dict and value.inherit or value.force_parent:
getter = partial(_generic_g_parent, attr_name)
else:
getter = partial(_generic_g, attr_name)
@@ -148,20 +148,20 @@ class BaseMeta(type):
class Base(with_metaclass(BaseMeta, object)):
# connection/transport
- _connection = FieldAttribute(isa='string')
- _port = FieldAttribute(isa='int')
- _remote_user = FieldAttribute(isa='string')
+ _connection = FieldAttribute(isa='string', force_parent=True)
+ _port = FieldAttribute(isa='int', force_parent=True)
+ _remote_user = FieldAttribute(isa='string', force_parent=True)
# variables
_vars = FieldAttribute(isa='dict', priority=100, inherit=False)
# flags and misc. settings
- _environment = FieldAttribute(isa='list')
- _no_log = FieldAttribute(isa='bool')
- _always_run = FieldAttribute(isa='bool')
- _run_once = FieldAttribute(isa='bool')
- _ignore_errors = FieldAttribute(isa='bool')
- _check_mode = FieldAttribute(isa='bool')
+ _environment = FieldAttribute(isa='list', force_parent=True)
+ _no_log = FieldAttribute(isa='bool', force_parent=True)
+ _always_run = FieldAttribute(isa='bool', force_parent=True)
+ _run_once = FieldAttribute(isa='bool', force_parent=True)
+ _ignore_errors = FieldAttribute(isa='bool', force_parent=True)
+ _check_mode = FieldAttribute(isa='bool', force_parent=True)
# param names which have been deprecated/removed
DEPRECATED_ATTRIBUTES = [
@@ -535,3 +535,4 @@ class Base(with_metaclass(BaseMeta, object)):
setattr(self, '_uuid', data.get('uuid'))
self._finalized = data.get('finalized', False)
self._squashed = data.get('squashed', False)
+