Merge pull request #25 from salt-formulas/python3-new-adrian
New Python3 branch (by Adrian Chifor)
diff --git a/README-extentions.rst b/README-extentions.rst
index 97d78af..9085b57 100644
--- a/README-extentions.rst
+++ b/README-extentions.rst
@@ -208,6 +208,55 @@
group_errors: True
+Use references in class names
+-----------------------------
+
+Allows to use references in the class names.
+
+Assuming following setup:
+
+.. code-block:: yaml
+ #/etc/reclass/classes/first.yml
+ parameters:
+ _class:
+ env:
+ override: 'env.dev'
+ lab:
+ name: default
+
+ #/etc/reclass/classes/lab/env/dev.yml
+ parameters:
+ lab:
+ name: dev
+
+ #/etc/reclass/classes/second.yml
+ classes:
+ - first
+ - lab.${_class:env:override}
+
+
+Reclass --nodeinfo then returns:
+
+.. code-block:: yaml
+
+ ...
+ ...
+ applications: []
+ environment: base
+ exports: {}
+ classes:
+ - first
+ - lab.${_class:env:override}
+ - second
+ parameters:
+ _class:
+ env:
+ override: env.dev
+ lab:
+ name: dev
+ ...
+ ...
+
Inventory Queries
-----------------
diff --git a/reclass/core.py b/reclass/core.py
index 9a23d89..92e7c25 100644
--- a/reclass/core.py
+++ b/reclass/core.py
@@ -22,6 +22,7 @@
from reclass.output.yaml_outputter import ExplicitDumper
from reclass.datatypes import Entity, Classes, Parameters, Exports
from reclass.errors import MappingFormatError, ClassNotFound, InvQueryClassNotFound, InvQueryError, InterpolationError
+from reclass.values.parser import Parser
try:
basestring
@@ -97,6 +98,10 @@
return Entity(self._settings, parameters=p, name='input data')
def _recurse_entity(self, entity, merge_base=None, seen=None, nodename=None, environment=None):
+
+ # values/parser in order to interpolate references in classes
+ _parser = Parser()
+
if seen is None:
seen = {}
@@ -107,6 +112,8 @@
merge_base = Entity(self._settings, name='empty (@{0})'.format(nodename))
for klass in entity.classes.as_list():
+ if merge_base is not None:
+ klass=str(_parser.parse(klass, self._settings).render(merge_base.parameters.as_dict(), {}))
if klass not in seen:
try:
class_entity = self._storage.get_class(klass, environment, self._settings)
diff --git a/reclass/datatypes/tests/test_parameters.py b/reclass/datatypes/tests/test_parameters.py
index a00f2c6..b5dc243 100644
--- a/reclass/datatypes/tests/test_parameters.py
+++ b/reclass/datatypes/tests/test_parameters.py
@@ -204,6 +204,15 @@
p1.initialise_interpolation()
self.assertEqual(p1.as_dict()['key'], None)
+ def test_merge_none_over_list_negative(self):
+ l = ['foo', 1, 2]
+ settings = Settings({'allow_none_override': False})
+ p1 = Parameters(dict(key=l[:2]), settings, '')
+ p2 = Parameters(dict(key=None), settings, '')
+ with self.assertRaises(TypeError):
+ p1.merge(p2)
+ p1.initialise_interpolation()
+
def test_merge_none_over_dict(self):
settings = Settings({'allow_none_override': True})
p1 = Parameters(dict(key=SIMPLE), settings, '')
@@ -212,6 +221,14 @@
p1.initialise_interpolation()
self.assertEqual(p1.as_dict()['key'], None)
+ def test_merge_none_over_dict_negative(self):
+ settings = Settings({'allow_none_override': False})
+ p1 = Parameters(dict(key=SIMPLE), settings, '')
+ p2 = Parameters(dict(key=None), settings, '')
+ with self.assertRaises(TypeError):
+ p1.merge(p2)
+ p1.initialise_interpolation()
+
# def test_merge_bare_dict_over_dict(self):
# settings = Settings({'allow_bare_override': True})
# p1 = Parameters(dict(key=SIMPLE), settings, '')
diff --git a/reclass/defaults.py b/reclass/defaults.py
index b245aa8..408307d 100644
--- a/reclass/defaults.py
+++ b/reclass/defaults.py
@@ -29,7 +29,7 @@
OPT_ALLOW_SCALAR_OVER_LIST = False
OPT_ALLOW_LIST_OVER_SCALAR = False
OPT_ALLOW_DICT_OVER_SCALAR = False
-OPT_ALLOW_NONE_OVERRIDE = True
+OPT_ALLOW_NONE_OVERRIDE = False
OPT_INVENTORY_IGNORE_FAILED_NODE = False
OPT_INVENTORY_IGNORE_FAILED_RENDER = False
diff --git a/reclass/values/scaitem.py b/reclass/values/scaitem.py
index d446b3c..9de5681 100644
--- a/reclass/values/scaitem.py
+++ b/reclass/values/scaitem.py
@@ -21,12 +21,12 @@
if item.type == Item.SCALAR:
return self
elif item.type == Item.LIST:
- if self._settings.allow_scalar_over_list or (self._settings.allow_none_override and self._value in [None, 'none', 'None']):
+ if self._settings.allow_scalar_over_list or (self._settings.allow_none_override and self._value is None):
return self
else:
raise TypeError('allow scalar over list = False: cannot merge %s over %s' % (repr(self), repr(item)))
elif item.type == Item.DICTIONARY:
- if self._settings.allow_scalar_over_dict or (self._settings.allow_none_override and self._value in [None, 'none', 'None']):
+ if self._settings.allow_scalar_over_dict or (self._settings.allow_none_override and self._value is None):
return self
else:
raise TypeError('allow scalar over dict = False: cannot merge %s over %s' % (repr(self), repr(item)))