Add validating of section 'conditions'
Validate section 'conditions' when stack validate. Change-Id: I0cf1abcc4656c573afbbd41e02b573ada63c1ae6 Blueprint: support-conditions-function
This commit is contained in:
parent
0803639788
commit
d072f6e7f1
@ -133,6 +133,11 @@ class InvalidConditionFunction(HeatException):
|
||||
msg_fmt = _("The function is not supported in condition: %(func)s")
|
||||
|
||||
|
||||
class InvalidConditionDefinition(HeatException):
|
||||
msg_fmt = _("The definition of condition (%(cd)s) is "
|
||||
"invalid: %(definition)s")
|
||||
|
||||
|
||||
class ImmutableParameterModified(HeatException):
|
||||
msg_fmt = _("The following parameters are immutable and may not be "
|
||||
"updated: %(keys)s")
|
||||
|
@ -176,6 +176,9 @@ class CfnTemplate(CfnTemplateBase):
|
||||
(n, function.Invalid) for n in self.functions)
|
||||
self._parser_condition_functions.update(self.condition_functions)
|
||||
|
||||
def get_condition_definitions(self):
|
||||
return self[self.CONDITIONS]
|
||||
|
||||
|
||||
class HeatTemplate(CfnTemplateBase):
|
||||
functions = {
|
||||
|
@ -511,3 +511,6 @@ class HOTemplate20161014(HOTemplate20160408):
|
||||
else:
|
||||
self._parser_condition_functions[n] = f
|
||||
self._parser_condition_functions.update(self.condition_functions)
|
||||
|
||||
def get_condition_definitions(self):
|
||||
return self[self.CONDITIONS]
|
||||
|
@ -779,6 +779,9 @@ class Stack(collections.Mapping):
|
||||
parameter_groups = param_groups.ParameterGroups(self.t)
|
||||
parameter_groups.validate()
|
||||
|
||||
# Validate condition definition of conditions section
|
||||
self.t.validate_condition_definitions(self)
|
||||
|
||||
# Validate types of sections in ResourceDefinitions
|
||||
self.t.validate_resource_definitions(self)
|
||||
|
||||
|
@ -211,6 +211,11 @@ class Template(collections.Mapping):
|
||||
"""Check section's type of ResourceDefinitions."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def validate_condition_definitions(self, stack):
|
||||
"""Check conditions section."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def resource_definitions(self, stack):
|
||||
"""Return a dictionary of ResourceDefinition objects."""
|
||||
|
@ -74,3 +74,33 @@ class CommonTemplate(template.Template):
|
||||
self.validate_resource_definition(name, data)
|
||||
except (TypeError, ValueError, KeyError) as ex:
|
||||
raise exception.StackValidationFailed(message=six.text_type(ex))
|
||||
|
||||
def validate_condition_definitions(self, stack):
|
||||
"""Check conditions section."""
|
||||
|
||||
resolved_cds = self.resolve_conditions(stack)
|
||||
if resolved_cds:
|
||||
for cd_key, cd_value in six.iteritems(resolved_cds):
|
||||
if not isinstance(cd_value, bool):
|
||||
raise exception.InvalidConditionDefinition(
|
||||
cd=cd_key,
|
||||
definition=cd_value)
|
||||
|
||||
def resolve_conditions(self, stack):
|
||||
cd_snippet = self.get_condition_definitions()
|
||||
result = {}
|
||||
if cd_snippet:
|
||||
for cd_key, cd_value in six.iteritems(cd_snippet):
|
||||
# hasn't been resolved yet
|
||||
if not isinstance(cd_value, bool):
|
||||
condition_func = self.parse_condition(
|
||||
stack, cd_value)
|
||||
resolved_cd_value = function.resolve(condition_func)
|
||||
result[cd_key] = resolved_cd_value
|
||||
else:
|
||||
result[cd_key] = cd_value
|
||||
|
||||
return result
|
||||
|
||||
def get_condition_definitions(self):
|
||||
return {}
|
||||
|
@ -138,6 +138,9 @@ class TestTemplatePluginManager(common.HeatTestCase):
|
||||
def validate_resource_definitions(self, stack):
|
||||
pass
|
||||
|
||||
def validate_condition_definitions(self, stack):
|
||||
pass
|
||||
|
||||
def resource_definitions(self, stack):
|
||||
pass
|
||||
|
||||
@ -274,6 +277,71 @@ class ParserTest(common.HeatTestCase):
|
||||
self.assertIsNot(raw, parsed)
|
||||
|
||||
|
||||
class TestTemplateConditionParser(common.HeatTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestTemplateConditionParser, self).setUp()
|
||||
self.ctx = utils.dummy_context()
|
||||
|
||||
def test_conditions_with_non_supported_functions(self):
|
||||
t = {
|
||||
'heat_template_version': '2016-10-14',
|
||||
'parameters': {
|
||||
'env_type': {
|
||||
'type': 'string',
|
||||
'default': 'test'
|
||||
}
|
||||
},
|
||||
'conditions': {
|
||||
'prod_env': {
|
||||
'equals': [{'get_param': 'env_type'},
|
||||
{'get_attr': [None, 'att']}]}}}
|
||||
# test with get_attr in equals
|
||||
tmpl = template.Template(t)
|
||||
stk = stack.Stack(self.ctx, 'test_condition_with_get_attr_func', tmpl)
|
||||
ex = self.assertRaises(exception.InvalidConditionFunction,
|
||||
tmpl.resolve_conditions, stk)
|
||||
self.assertIn('The function is not supported in condition: get_attr',
|
||||
six.text_type(ex))
|
||||
|
||||
# test with get_resource in top level of a condition
|
||||
tmpl.t['conditions']['prod_env'] = {'get_resource': 'R1'}
|
||||
stk = stack.Stack(self.ctx, 'test_condition_with_get_attr_func', tmpl)
|
||||
ex = self.assertRaises(exception.InvalidConditionFunction,
|
||||
tmpl.resolve_conditions, stk)
|
||||
self.assertIn('The function is not supported in condition: '
|
||||
'get_resource', six.text_type(ex))
|
||||
|
||||
# test with get_attr in top level of a condition
|
||||
tmpl.t['conditions']['prod_env'] = {'get_attr': [None, 'att']}
|
||||
stk = stack.Stack(self.ctx, 'test_condition_with_get_attr_func', tmpl)
|
||||
ex = self.assertRaises(exception.InvalidConditionFunction,
|
||||
tmpl.resolve_conditions, stk)
|
||||
self.assertIn('The function is not supported in condition: get_attr',
|
||||
six.text_type(ex))
|
||||
|
||||
def test_condition_resolved_not_boolean(self):
|
||||
t = {
|
||||
'heat_template_version': '2016-10-14',
|
||||
'parameters': {
|
||||
'env_type': {
|
||||
'type': 'string',
|
||||
'default': 'test'
|
||||
}
|
||||
},
|
||||
'conditions': {
|
||||
'prod_env': {'get_param': 'env_type'}}}
|
||||
|
||||
# test with get_attr in equals
|
||||
tmpl = template.Template(t)
|
||||
stk = stack.Stack(self.ctx, 'test_condition_not_boolean', tmpl)
|
||||
|
||||
ex = self.assertRaises(exception.InvalidConditionDefinition,
|
||||
tmpl.validate_condition_definitions, stk)
|
||||
self.assertIn('The definition of condition (prod_env) is invalid',
|
||||
six.text_type(ex))
|
||||
|
||||
|
||||
class TestTemplateValidate(common.HeatTestCase):
|
||||
|
||||
def test_template_validate_cfn_check_t_digest(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user