diff --git a/heat/engine/cfn/template.py b/heat/engine/cfn/template.py index 271f4537cf..f91a39d5bf 100644 --- a/heat/engine/cfn/template.py +++ b/heat/engine/cfn/template.py @@ -11,8 +11,6 @@ # License for the specific language governing permissions and limitations # under the License. -import collections - import six from heat.common import exception @@ -22,10 +20,10 @@ from heat.engine import function from heat.engine.hot import functions as hot_funcs from heat.engine import parameters from heat.engine import rsrc_defn -from heat.engine import template +from heat.engine import template_common -class CfnTemplateBase(template.Template): +class CfnTemplateBase(template_common.CommonTemplate): """The base implementation of cfn template.""" SECTIONS = ( @@ -103,53 +101,6 @@ class CfnTemplateBase(template.Template): user_params=user_params, param_defaults=param_defaults) - def validate_resource_definitions(self, stack): - resources = self.t.get(self.RESOURCES) or {} - allowed_keys = set(self._RESOURCE_KEYS) - - try: - - for name, snippet in resources.items(): - path = '.'.join([self.RESOURCES, name]) - data = self.parse(stack, snippet, path) - - if not self.validate_resource_key_type(self.RES_TYPE, - six.string_types, - 'string', - allowed_keys, - name, data): - args = {'name': name, 'type_key': self.RES_TYPE} - msg = _('Resource %(name)s is missing ' - '"%(type_key)s"') % args - raise KeyError(msg) - - self.validate_resource_key_type( - self.RES_PROPERTIES, - (collections.Mapping, function.Function), - 'object', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_METADATA, - (collections.Mapping, function.Function), - 'object', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_DEPENDS_ON, - collections.Sequence, - 'list or string', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_DELETION_POLICY, - (six.string_types, function.Function), - 'string', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_UPDATE_POLICY, - (collections.Mapping, function.Function), - 'object', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_DESCRIPTION, - six.string_types, - 'string', allowed_keys, name, data) - except TypeError as ex: - raise exception.StackValidationFailed(message=six.text_type(ex)) - def resource_definitions(self, stack): resources = self.t.get(self.RESOURCES) or {} diff --git a/heat/engine/hot/template.py b/heat/engine/hot/template.py index 3234a537bf..19f3ece427 100644 --- a/heat/engine/hot/template.py +++ b/heat/engine/hot/template.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import collections - import six from heat.common import exception @@ -22,10 +20,10 @@ from heat.engine import function from heat.engine.hot import functions as hot_funcs from heat.engine.hot import parameters from heat.engine import rsrc_defn -from heat.engine import template +from heat.engine import template_common -class HOTemplate20130523(template.Template): +class HOTemplate20130523(template_common.CommonTemplate): """A Heat Orchestration Template format stack template.""" SECTIONS = ( @@ -218,48 +216,6 @@ class HOTemplate20130523(template.Template): user_params=user_params, param_defaults=param_defaults) - def validate_resource_definitions(self, stack): - resources = self.t.get(self.RESOURCES) or {} - allowed_keys = set(self._RESOURCE_KEYS) - - try: - for name, snippet in resources.items(): - path = '.'.join([self.RESOURCES, name]) - data = self.parse(stack, snippet, path) - - if not self.validate_resource_key_type(self.RES_TYPE, - six.string_types, - 'string', - allowed_keys, - name, data): - args = {'name': name, 'type_key': self.RES_TYPE} - msg = _('Resource %(name)s is missing ' - '"%(type_key)s"') % args - raise KeyError(msg) - - self.validate_resource_key_type( - self.RES_PROPERTIES, - (collections.Mapping, function.Function), - 'object', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_METADATA, - (collections.Mapping, function.Function), - 'object', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_DEPENDS_ON, - collections.Sequence, - 'list or string', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_DELETION_POLICY, - (six.string_types, function.Function), - 'string', allowed_keys, name, data) - self.validate_resource_key_type( - self.RES_UPDATE_POLICY, - (collections.Mapping, function.Function), - 'object', allowed_keys, name, data) - except (TypeError, ValueError) as ex: - raise exception.StackValidationFailed(message=six.text_type(ex)) - def resource_definitions(self, stack): resources = self.t.get(self.RESOURCES) or {} parsed_resources = self.parse(stack, resources) diff --git a/heat/engine/template_common.py b/heat/engine/template_common.py new file mode 100644 index 0000000000..3c1fb0e54e --- /dev/null +++ b/heat/engine/template_common.py @@ -0,0 +1,76 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import collections + +import six + +from heat.common import exception +from heat.common.i18n import _ +from heat.engine import function +from heat.engine import template + + +class CommonTemplate(template.Template): + """A class of the common implementation for HOT and CFN templates.""" + + def validate_resource_definition(self, name, data): + allowed_keys = set(self._RESOURCE_KEYS) + + if not self.validate_resource_key_type(self.RES_TYPE, + six.string_types, + 'string', + allowed_keys, + name, + data): + args = {'name': name, 'type_key': self.RES_TYPE} + msg = _('Resource %(name)s is missing "%(type_key)s"') % args + raise KeyError(msg) + + self.validate_resource_key_type( + self.RES_PROPERTIES, + (collections.Mapping, function.Function), + 'object', allowed_keys, name, data) + self.validate_resource_key_type( + self.RES_METADATA, + (collections.Mapping, function.Function), + 'object', allowed_keys, name, data) + self.validate_resource_key_type( + self.RES_DEPENDS_ON, + collections.Sequence, + 'list or string', allowed_keys, name, data) + self.validate_resource_key_type( + self.RES_DELETION_POLICY, + (six.string_types, function.Function), + 'string', allowed_keys, name, data) + self.validate_resource_key_type( + self.RES_UPDATE_POLICY, + (collections.Mapping, function.Function), + 'object', allowed_keys, name, data) + self.validate_resource_key_type( + self.RES_DESCRIPTION, + six.string_types, + 'string', allowed_keys, name, data) + + def validate_resource_definitions(self, stack): + """Check section's type of ResourceDefinitions.""" + + resources = self.t.get(self.RESOURCES) or {} + + try: + for name, snippet in resources.items(): + path = '.'.join([self.RESOURCES, name]) + data = self.parse(stack, snippet, path) + self.validate_resource_definition(name, data) + except (TypeError, ValueError, KeyError) as ex: + raise exception.StackValidationFailed(message=six.text_type(ex))