Add a strict_validate flag to Stacks

Enables optionally disabling strict validation, which atm just
disables the value part of properties validation.

This is needed for a similar reason to bug #1347571, which
conditionally disables value validation when inter-resource
references cause a default pre-create value to be evaluated by
a custom constraint (e.g the default resource name returned by
get_resource until a resource is actually created).

This flag enables a similar fix for StackResource, so we avoid
strictly validating before create, otherwise the nested stack
validation fails when the default resource name is passed in
during validation, even though create-time validation would succeed.

Change-Id: I80b5b8969007319e9a8fa1d104f4eb4fcbf7ebad
Partial-Bug: #1407100
This commit is contained in:
Steven Hardy 2015-01-02 18:16:40 +00:00
parent 966e0ff884
commit 35853f5223
3 changed files with 26 additions and 2 deletions

View File

@ -840,7 +840,7 @@ class Resource(object):
function.validate(self.t)
self.validate_deletion_policy(self.t.deletion_policy())
return self.properties.validate()
return self.properties.validate(with_value=self.stack.strict_validate)
@classmethod
def validate_deletion_policy(cls, policy):

View File

@ -79,7 +79,7 @@ class Stack(collections.Mapping):
created_time=None, updated_time=None,
user_creds_id=None, tenant_id=None,
use_stored_context=False, username=None,
nested_depth=0):
nested_depth=0, strict_validate=True):
'''
Initialise from a context, name, Template object and (optionally)
Environment object. The database ID may also be initialised, if the
@ -117,6 +117,7 @@ class Stack(collections.Mapping):
self.updated_time = updated_time
self.user_creds_id = user_creds_id
self.nested_depth = nested_depth
self.strict_validate = strict_validate
if use_stored_context:
self.context = self.stored_context()

View File

@ -1407,6 +1407,29 @@ class ResourceDependenciesTest(common.HeatTestCase):
stack.validate)
self.assertIn('"baz" (in bar.Properties.Foo)', six.text_type(ex))
def test_validate_value_fail(self):
tmpl = template.Template({
'heat_template_version': '2013-05-23',
'resources': {
'bar': {
'type': 'ResourceWithPropsType',
'properties': {
'FooInt': 'notanint',
}
}
}
})
stack = parser.Stack(utils.dummy_context(), 'test', tmpl)
ex = self.assertRaises(exception.StackValidationFailed,
stack.validate)
expected = "FooInt Value 'notanint' is not an integer"
self.assertIn(expected, six.text_type(ex))
# You can turn off value validation via strict_validate
stack_novalidate = parser.Stack(utils.dummy_context(), 'test', tmpl,
strict_validate=False)
self.assertIsNone(stack_novalidate.validate())
def test_getatt(self):
tmpl = template.Template({
'HeatTemplateFormatVersion': '2012-12-12',