From 27426e83306e55067e1a450ed0cce37533749a8c Mon Sep 17 00:00:00 2001 From: rabi Date: Thu, 18 Jan 2018 12:53:57 +0530 Subject: [PATCH] Fix nested template genearation when attribute path is not string When determining attributes to cache, we seem to be assuming the paths to be strings. If there are resource references in outputs it would be None during validation. As we've the same code snippet in all group resources ex. ResourceGroup, ResourceChain and heat AutoScalingGroup, this fixes it in all those places. Change-Id: I36d623b183d01632041113f7bff63bf255f5d53c Closes-Bug: #1719603 (cherry picked from commit aabb3392b30e4905e8b780bec4c819ec6058b2b6) --- heat/engine/resources/openstack/heat/autoscaling_group.py | 2 +- heat/engine/resources/openstack/heat/resource_chain.py | 2 +- heat/engine/resources/openstack/heat/resource_group.py | 2 +- heat/tests/autoscaling/test_heat_scaling_group.py | 7 +++++++ heat/tests/openstack/heat/test_resource_chain.py | 6 ++++++ heat/tests/openstack/heat/test_resource_group.py | 8 ++++++++ 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/heat/engine/resources/openstack/heat/autoscaling_group.py b/heat/engine/resources/openstack/heat/autoscaling_group.py index 1eb4976305..5b31a240e9 100644 --- a/heat/engine/resources/openstack/heat/autoscaling_group.py +++ b/heat/engine/resources/openstack/heat/autoscaling_group.py @@ -226,7 +226,7 @@ class AutoScalingResourceGroup(aws_asg.AutoScalingGroup): output_name = attr else: key, path = attr[0], list(attr[1:]) - output_name = ', '.join(attr) + output_name = ', '.join(six.text_type(a) for a in attr) if key.startswith("resource."): keycomponents = key.split('.', 2) diff --git a/heat/engine/resources/openstack/heat/resource_chain.py b/heat/engine/resources/openstack/heat/resource_chain.py index 0d3973348c..42362584e3 100644 --- a/heat/engine/resources/openstack/heat/resource_chain.py +++ b/heat/engine/resources/openstack/heat/resource_chain.py @@ -166,7 +166,7 @@ class ResourceChain(stack_resource.StackResource): output_name = attr else: key, path = attr[0], list(attr[1:]) - output_name = ', '.join(attr) + output_name = ', '.join(six.text_type(a) for a in attr) if key.startswith("resource."): keycomponents = key.split('.', 2) diff --git a/heat/engine/resources/openstack/heat/resource_group.py b/heat/engine/resources/openstack/heat/resource_group.py index 3351395277..10fba283c2 100644 --- a/heat/engine/resources/openstack/heat/resource_group.py +++ b/heat/engine/resources/openstack/heat/resource_group.py @@ -462,7 +462,7 @@ class ResourceGroup(stack_resource.StackResource): output_name = attr else: key, path = attr[0], list(attr[1:]) - output_name = ', '.join(attr) + output_name = ', '.join(six.text_type(a) for a in attr) if key.startswith("resource."): keycomponents = key.split('.', 2) diff --git a/heat/tests/autoscaling/test_heat_scaling_group.py b/heat/tests/autoscaling/test_heat_scaling_group.py index 5f913adae1..3446331539 100644 --- a/heat/tests/autoscaling/test_heat_scaling_group.py +++ b/heat/tests/autoscaling/test_heat_scaling_group.py @@ -42,6 +42,13 @@ class TestAutoScalingGroupValidation(common.HeatTestCase): self.assertRaises(exception.StackValidationFailed, stack['my-group'].validate) + def test_validate_reference_attr_with_none_ref(self): + stack = utils.parse_stack(self.parsed) + group = stack['my-group'] + self.patchobject(group, 'referenced_attrs', + return_value=set([('something', None)])) + self.assertIsNone(group.validate()) + class TestScalingGroupTags(common.HeatTestCase): def setUp(self): diff --git a/heat/tests/openstack/heat/test_resource_chain.py b/heat/tests/openstack/heat/test_resource_chain.py index f352ec5614..10ab7f0e6e 100644 --- a/heat/tests/openstack/heat/test_resource_chain.py +++ b/heat/tests/openstack/heat/test_resource_chain.py @@ -129,6 +129,12 @@ class ResourceChainTest(common.HeatTestCase): chain = self._create_chain(TEMPLATE) chain.validate_nested_stack() + def test_validate_reference_attr_with_none_ref(self): + chain = self._create_chain(TEMPLATE) + self.patchobject(chain, 'referenced_attrs', + return_value=set([('config', None)])) + self.assertIsNone(chain.validate()) + def test_validate_incompatible_properties(self): # Tests a resource in the chain that does not support the properties # specified to each resource. diff --git a/heat/tests/openstack/heat/test_resource_group.py b/heat/tests/openstack/heat/test_resource_group.py index 75bff2dfd4..91174abf81 100644 --- a/heat/tests/openstack/heat/test_resource_group.py +++ b/heat/tests/openstack/heat/test_resource_group.py @@ -507,6 +507,14 @@ class ResourceGroupTest(common.HeatTestCase): resgrp = resource_group.ResourceGroup('test', snip, stack) self.assertIsNone(resgrp.validate()) + def test_validate_reference_attr_with_none_ref(self): + stack = utils.parse_stack(template_attr) + snip = stack.t.resource_definitions(stack)['group1'] + resgrp = resource_group.ResourceGroup('test', snip, stack) + self.patchobject(resgrp, 'referenced_attrs', + return_value=set([('nested_dict', None)])) + self.assertIsNone(resgrp.validate()) + def test_invalid_removal_policies_nolist(self): """Test that error raised for malformed removal_policies.""" tmp = copy.deepcopy(template)