diff --git a/heat/engine/cfn/template.py b/heat/engine/cfn/template.py index d249a6f325..edeb543d18 100644 --- a/heat/engine/cfn/template.py +++ b/heat/engine/cfn/template.py @@ -130,7 +130,7 @@ class CfnTemplate(template.Template): 'list or string', allowed_keys, name, data) self.validate_resource_key_type( RES_DELETION_POLICY, - six.string_types, + (six.string_types, function.Function), 'string', allowed_keys, name, data) self.validate_resource_key_type( RES_UPDATE_POLICY, @@ -153,9 +153,10 @@ class CfnTemplate(template.Template): if isinstance(depends, six.string_types): depends = [depends] - deletion_policy = data.get(RES_DELETION_POLICY) + deletion_policy = function.resolve(data.get(RES_DELETION_POLICY)) if deletion_policy is not None: - if deletion_policy not in self.deletion_policies: + if deletion_policy not in six.iterkeys( + self.deletion_policies): msg = _('Invalid deletion policy "%s"') % deletion_policy raise exception.StackValidationFailed(message=msg) else: diff --git a/heat/engine/hot/template.py b/heat/engine/hot/template.py index 34a4fae790..44e68bf48f 100644 --- a/heat/engine/hot/template.py +++ b/heat/engine/hot/template.py @@ -235,7 +235,7 @@ class HOTemplate20130523(template.Template): 'list or string', allowed_keys, name, data) self.validate_resource_key_type( RES_DELETION_POLICY, - six.string_types, + (six.string_types, function.Function), 'string', allowed_keys, name, data) self.validate_resource_key_type( RES_UPDATE_POLICY, @@ -256,9 +256,10 @@ class HOTemplate20130523(template.Template): if isinstance(depends, six.string_types): depends = [depends] - deletion_policy = data.get(RES_DELETION_POLICY) + deletion_policy = function.resolve(data.get(RES_DELETION_POLICY)) if deletion_policy is not None: - if deletion_policy not in HOTemplate20130523.deletion_policies: + if deletion_policy not in six.iterkeys( + HOTemplate20130523.deletion_policies): msg = _('Invalid deletion policy "%s"') % deletion_policy raise exception.StackValidationFailed(message=msg) else: diff --git a/heat/tests/test_stack.py b/heat/tests/test_stack.py index f6cded3e2b..56e4d7012a 100644 --- a/heat/tests/test_stack.py +++ b/heat/tests/test_stack.py @@ -1977,29 +1977,85 @@ class StackTest(common.HeatTestCase): def test_incorrect_deletion_policy(self): tmpl = template_format.parse(""" HeatTemplateFormatVersion: '2012-12-12' + Parameters: + Deletion_Policy: + Type: String + Default: [1, 2] Resources: AResource: Type: ResourceWithPropsType - DeletionPolicy: wibble + DeletionPolicy: {Ref: Deletion_Policy} Properties: Foo: abc """) + self.stack = stack.Stack(self.ctx, 'stack_bad_delpol', template.Template(tmpl)) ex = self.assertRaises(exception.StackValidationFailed, self.stack.validate) - self.assertIn('Invalid deletion policy "wibble"', + self.assertIn('Invalid deletion policy "[1, 2]"', six.text_type(ex)) + def test_deletion_policy_apply_ref(self): + tmpl = template_format.parse(""" + HeatTemplateFormatVersion: '2012-12-12' + Parameters: + Deletion_Policy: + Type: String + Default: Delete + Resources: + AResource: + Type: ResourceWithPropsType + DeletionPolicy: wibble + Properties: + Foo: abc + DeletionPolicy: {Ref: Deletion_Policy} + """) + + self.stack = stack.Stack(self.ctx, 'stack_delpol_get_param', + template.Template(tmpl)) + self.stack.validate() + self.stack.store() + self.stack.create() + self.assertEqual((self.stack.CREATE, self.stack.COMPLETE), + self.stack.state) + + def test_deletion_policy_apply_get_param(self): + tmpl = template_format.parse(""" + heat_template_version: 2016-04-08 + parameters: + deletion_policy: + type: string + default: Delete + resources: + AResource: + type: ResourceWithPropsType + deletion_policy: {get_param: deletion_policy} + properties: + Foo: abc + """) + + self.stack = stack.Stack(self.ctx, 'stack_delpol_get_param', + template.Template(tmpl)) + self.stack.validate() + self.stack.store() + self.stack.create() + self.assertEqual((self.stack.CREATE, self.stack.COMPLETE), + self.stack.state) + def test_incorrect_deletion_policy_hot(self): tmpl = template_format.parse(""" heat_template_version: 2013-05-23 + parameters: + deletion_policy: + type: string + default: [1, 2] resources: AResource: type: ResourceWithPropsType - deletion_policy: wibble + deletion_policy: {get_param: deletion_policy} properties: Foo: abc """) @@ -2009,7 +2065,7 @@ class StackTest(common.HeatTestCase): ex = self.assertRaises(exception.StackValidationFailed, self.stack.validate) - self.assertIn('Invalid deletion policy "wibble"', + self.assertIn('Invalid deletion policy "[1, 2]', six.text_type(ex)) def test_incorrect_outputs_hot_get_attr(self):