1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

WIP on Attributes. Getting closer.

This commit is contained in:
Michael DeHaan 2014-10-03 16:37:32 -04:00
parent b02afa2268
commit b54434c1b2
5 changed files with 71 additions and 49 deletions

View file

@ -16,20 +16,22 @@ class TestTask(unittest.TestCase):
def tearDown(self): def tearDown(self):
pass pass
def test_can_construct_empty_task(): def test_can_construct_empty_task(self):
t = Task() t = Task()
def test_can_construct_task_with_role(): def test_can_construct_task_with_role(self):
pass pass
def test_can_construct_task_with_block(): def test_can_construct_task_with_block(self):
pass pass
def test_can_construct_task_with_role_and_block(): def test_can_construct_task_with_role_and_block(self):
pass pass
def test_can_load_simple_task(): def test_can_load_simple_task(self):
t = Task.load(basic_shell_task) t = Task.load(basic_shell_task)
assert t is not None
print "T.NAME = %s" % t.name
assert t.name == basic_shell_task['name'] assert t.name == basic_shell_task['name']
assert t.module == 'shell' assert t.module == 'shell'
assert t.args == 'echo hi' assert t.args == 'echo hi'

View file

@ -23,6 +23,7 @@ class Attribute(object):
self.isa = isa self.isa = isa
self.validator = validator self.validator = validator
self.post_validator = post_validator self.post_validator = post_validator
self.value = None
class FieldAttribute(Attribute): class FieldAttribute(Attribute):

View file

@ -17,21 +17,51 @@
#from ansible.cmmon.errors import AnsibleError #from ansible.cmmon.errors import AnsibleError
#from playbook.tag import Tag #from playbook.tag import Tag
from ansible.playbook.attribute import Attribute, FieldAttribute
class Base(object): class Base(object):
def __init__(self, attribute): def __init__(self):
pass self._data = dict()
self._attributes = dict()
def add_attribute(self): def load_data(self, ds):
self.attributes.push(attribute) ''' walk the input datastructure and assign any values '''
def load(self, data): assert ds is not None
for attribute in self.attributes:
attribute.load(data) for name in self.__class__.__dict__:
print "DEBUG: processing attribute: %s" % name
attribute = self.__class__.__dict__[name]
if isinstance(attribute, FieldAttribute):
method = getattr(self, '_load_%s' % name, None)
if method:
self._attributes[name] = method(self, attribute)
else:
if name in ds:
self._attributes[name] = ds[name]
# implement PluginAtrribute which allows "with_" and "action" aliases.
return self
def attribute_value(self, name):
return self._attributes[name]
def validate(self): def validate(self):
for attribute in self.attributes:
attribute.validate(self)
for name in self.__dict__:
attribute = self.__dict__[name]
if instanceof(attribute, FieldAttribute):
method = getattr(self, '_validate_%s' % (prefix, name), None)
if method:
method(self, attribute)
def post_validate(self, runner_context):
raise exception.NotImplementedError
# TODO: __getattr__ that looks inside _attributes

View file

@ -20,9 +20,14 @@ from v2.utils import list_union
class Role(PlaybookBase): class Role(PlaybookBase):
# TODO: this will be overhauled to match Task.py at some point
def __init__(self): def __init__(self):
pass pass
def get_name(self):
return "TEMPORARY"
def load(self, ds): def load(self, ds):
self._ds = ds self._ds = ds
self._tasks = [] self._tasks = []

View file

@ -43,6 +43,7 @@ class Task(Base):
# will be used if defined # will be used if defined
# might be possible to define others # might be possible to define others
action = FieldAttribute(isa='string')
always_run = FieldAttribute(isa='bool') always_run = FieldAttribute(isa='bool')
any_errors_fatal = FieldAttribute(isa='bool') any_errors_fatal = FieldAttribute(isa='bool')
async = FieldAttribute(isa='int') async = FieldAttribute(isa='int')
@ -54,14 +55,14 @@ class Task(Base):
ignore_errors = FieldAttribute(isa='bool') ignore_errors = FieldAttribute(isa='bool')
# FIXME: this should not be a Task # FIXME: this should not be a Task
# include = FieldAttribute(isa='string') # include = FieldAttribute(isa='string')
local_action = FieldAttribute(isa='string', alias='action', post_validate='_set_local_action') local_action = FieldAttribute(isa='string')
# FIXME: this should not be a Task # FIXME: this should not be a Task
meta = FieldAttribute(isa='string') meta = FieldAttribute(isa='string')
name = FieldAttribute(isa='string', validate=self._set_name) name = FieldAttribute(isa='string')
no_log = FieldAttribute(isa='bool') no_log = FieldAttribute(isa='bool')
notify = FieldAttribute(isa='list') notify = FieldAttribute(isa='list')
@ -82,29 +83,33 @@ class Task(Base):
role = Attribute() role = Attribute()
block = Attribute() block = Attribute()
# ==================================================================================
def __init__(self, block=None, role=None): def __init__(self, block=None, role=None):
''' constructors a task, without the Task.load classmethod, it will be pretty blank ''' ''' constructors a task, without the Task.load classmethod, it will be pretty blank '''
self.block = block self._block = block
self.role = role self._role = role
super(Task, self).__init__() super(Task, self).__init__()
# ==================================================================================
# BASIC ACCESSORS
def get_name(self): def get_name(self):
''' return the name of the task ''' ''' return the name of the task '''
if self._role:
return "%s : %s" % (self._role.get_name(), self._name) # FIXME: getattr magic in baseclass so this is not required:
original = self.attribute_value('name')
role_value = self.attribute_value('role')
if role_value:
return "%s : %s" % (role_value.get_name(), original)
else: else:
return self._name return original
@staticmethod
def load(data, block=block, role=role):
t = Task(block=block, role=role)
return t.load_data(data)
def __repr__(self): def __repr__(self):
''' returns a human readable representation of the task ''' ''' returns a human readable representation of the task '''
return "TASK: %s" % self.get_name() return "TASK: %s" % self.get_name()
# ================================================================================== # ==================================================================================
# BELOW THIS LINE # BELOW THIS LINE
# info below this line is "old" and is before the attempt to build Attributes # info below this line is "old" and is before the attempt to build Attributes
@ -237,27 +242,6 @@ LEGACY = """
else: else:
return self._load_other_valid_key return self._load_other_valid_key
@classmethod
def load(self, ds, block=None, role=None):
''' walk the datastructure and store/validate parameters '''
self = Task(block=block, role=role)
return self._load_from_datastructure(ds)
# TODO: move to BaseObject
def _load_from_datastructure(ds)
self._pre_validate(ds)
# load the keys from the datastructure
for k,v in ds.iteritems():
mods = self._loader_for_key(k)(k,v)
if (k,v) in mods.iteritems():
setattr(self,k,v)
self._post_validate()
return self
# ================================================================================== # ==================================================================================
# PRE-VALIDATION - expected to be uncommonly used, this checks for arguments that # PRE-VALIDATION - expected to be uncommonly used, this checks for arguments that
# are aliases of each other. Most everything else should be in the LOAD block # are aliases of each other. Most everything else should be in the LOAD block