From 71431371761afc198ed50339d5c653eded369562 Mon Sep 17 00:00:00 2001 From: rabi Date: Wed, 19 Jul 2017 09:13:13 +0530 Subject: [PATCH] Fix subnet validate() for subnetpool resource ref When a resource reference is used __getitem__() returns empty string before a resource is created and the validation fails. Check for None value instead which would be the case when the property is not specified. Change-Id: Ida4b32c3611d1638b9c0eb78cb2b31a32f112fa9 Closes-Bug: #1705052 (cherry picked from commit 3d29db4c7060a546de8f880cf9515c2e22102ef8) --- .../resources/openstack/neutron/subnet.py | 4 +- .../openstack/neutron/test_neutron_subnet.py | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/heat/engine/resources/openstack/neutron/subnet.py b/heat/engine/resources/openstack/neutron/subnet.py index fb362e0cc2..049feb4645 100644 --- a/heat/engine/resources/openstack/neutron/subnet.py +++ b/heat/engine/resources/openstack/neutron/subnet.py @@ -321,10 +321,10 @@ class Subnet(neutron.NeutronResource): subnetpool = self.properties[self.SUBNETPOOL] prefixlen = self.properties[self.PREFIXLEN] cidr = self.properties[self.CIDR] - if subnetpool and cidr: + if subnetpool is not None and cidr: raise exception.ResourcePropertyConflict(self.SUBNETPOOL, self.CIDR) - if not subnetpool and not cidr: + if subnetpool is None and not cidr: raise exception.PropertyUnspecifiedError(self.SUBNETPOOL, self.CIDR) if prefixlen and cidr: diff --git a/heat/tests/openstack/neutron/test_neutron_subnet.py b/heat/tests/openstack/neutron/test_neutron_subnet.py index 667953964d..b5aa56aace 100644 --- a/heat/tests/openstack/neutron/test_neutron_subnet.py +++ b/heat/tests/openstack/neutron/test_neutron_subnet.py @@ -21,6 +21,7 @@ from heat.common import exception from heat.common import template_format from heat.engine.clients.os import neutron from heat.engine.hot import functions as hot_funcs +from heat.engine import resource from heat.engine.resources.openstack.neutron import subnet from heat.engine import rsrc_defn from heat.engine import scheduler @@ -665,6 +666,45 @@ class NeutronSubnetTest(common.HeatTestCase): "subnetpool, cidr.") self.assertEqual(msg, six.text_type(ex)) + def test_validate_subnetpool_ref_with_cidr(self): + t = template_format.parse(neutron_template) + props = t['resources']['sub_net']['properties'] + props['subnetpool'] = {'get_resource': 'subnetpool'} + props = t['resources']['sub_net']['properties'] + stack = utils.parse_stack(t) + snippet = rsrc_defn.ResourceDefinition('subnetpool', + 'OS::Neutron::SubnetPool') + res = resource.Resource('subnetpool', snippet, stack) + stack.add_resource(res) + self.patchobject(stack['subnetpool'], 'FnGetRefId', + return_value=None) + self.patchobject(stack['net'], 'FnGetRefId', + return_value='fc68ea2c-b60b-4b4f-bd82-94ec81110766') + rsrc = stack['sub_net'] + ex = self.assertRaises(exception.ResourcePropertyConflict, + rsrc.validate) + msg = ("Cannot define the following properties at the same time: " + "subnetpool, cidr.") + self.assertEqual(msg, six.text_type(ex)) + + def test_validate_subnetpool_ref_no_cidr(self): + t = template_format.parse(neutron_template) + props = t['resources']['sub_net']['properties'] + del props['cidr'] + props['subnetpool'] = {'get_resource': 'subnetpool'} + props = t['resources']['sub_net']['properties'] + stack = utils.parse_stack(t) + snippet = rsrc_defn.ResourceDefinition('subnetpool', + 'OS::Neutron::SubnetPool') + res = resource.Resource('subnetpool', snippet, stack) + stack.add_resource(res) + self.patchobject(stack['subnetpool'], 'FnGetRefId', + return_value=None) + self.patchobject(stack['net'], 'FnGetRefId', + return_value='fc68ea2c-b60b-4b4f-bd82-94ec81110766') + rsrc = stack['sub_net'] + self.assertIsNone(rsrc.validate()) + def test_validate_both_prefixlen_cidr(self): t = template_format.parse(neutron_template) props = t['resources']['sub_net']['properties']