diff --git a/doc/source/template_guide/hot_spec.rst b/doc/source/template_guide/hot_spec.rst index b8969145c2..6fc8b81971 100644 --- a/doc/source/template_guide/hot_spec.rst +++ b/doc/source/template_guide/hot_spec.rst @@ -80,8 +80,9 @@ parameters resources This section contains the declaration of the single resources of the - template. This section is mandatory and at least one resource must be - defined in any HOT template. + template. This section with at least one resource should be defined in any + HOT template, or the template would not really do anything when being + instantiated. outputs This section allows for specifying output parameters available to users once diff --git a/heat/engine/service.py b/heat/engine/service.py index 3ff7598f87..9a2f663490 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -600,7 +600,7 @@ class EngineService(service.Service): # validate overall template try: - tmpl.validate(allow_empty=False) + tmpl.validate() except Exception as ex: return {'Error': six.text_type(ex)} diff --git a/heat/engine/template.py b/heat/engine/template.py index 840275c5f7..f714ad77bf 100644 --- a/heat/engine/template.py +++ b/heat/engine/template.py @@ -18,7 +18,9 @@ import functools from heat.common import exception from heat.db import api as db_api from heat.engine import plugin_manager +from heat.openstack.common import log as logging +logger = logging.getLogger(__name__) __all__ = ['Template'] @@ -164,7 +166,7 @@ class Template(collections.Mapping): def parse(self, stack, snippet): return parse(self.functions(), stack, snippet) - def validate(self, allow_empty=True): + def validate(self): '''Validate the template. Validates the top-level sections of the template as well as syntax @@ -172,7 +174,6 @@ class Template(collections.Mapping): code parts that are responsible for working with the respective sections (e.g. parameters are check by parameters schema class). - :param allow_empty: whether to allow an empty resources section ''' # check top-level sections @@ -182,11 +183,10 @@ class Template(collections.Mapping): # check resources tmpl_resources = self[self.RESOURCES] - - if not allow_empty and not tmpl_resources: - message = _('The template is invalid. A Resources section with at ' - 'least one resource must be defined.') - raise exception.StackValidationFailed(message=message) + if not tmpl_resources: + logger.warn(_('Template does not contain any resources, so ' + 'the template would not really do anything when ' + 'being instantiated.')) for res in tmpl_resources.values(): try: diff --git a/heat/tests/test_validate.py b/heat/tests/test_validate.py index 68dccaa599..bde9fa864b 100644 --- a/heat/tests/test_validate.py +++ b/heat/tests/test_validate.py @@ -1076,9 +1076,8 @@ class validateTest(HeatTestCase): engine = service.EngineService('a', 't') res = dict(engine.validate_template(None, hot_tpl, {})) - self.assertEqual({'Error': 'The template is invalid. ' - 'A Resources section with at least one resource ' - 'must be defined.'}, res) + expected = {'Description': 'No description', 'Parameters': {}} + self.assertEqual(expected, res) def test_validate_template_with_invalid_resource_type(self): hot_tpl = template_format.parse('''