From 1796f3ec0f2787738d83b62a66b5efaa8563146d Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Thu, 16 May 2013 10:02:34 +1200 Subject: [PATCH] Tolerate resource lookup errors for quantum FnGetAtt. Fixes bug #1180293 Change-Id: I5384456bbbf53558036573c983be0b65e8883612 --- heat/engine/resources/quantum/floatingip.py | 8 ++- heat/engine/resources/quantum/net.py | 11 ++- heat/engine/resources/quantum/port.py | 11 ++- heat/engine/resources/quantum/router.py | 6 +- heat/engine/resources/quantum/subnet.py | 13 ++-- heat/tests/test_quantum.py | 78 ++++++++++++++++++++- 6 files changed, 113 insertions(+), 14 deletions(-) diff --git a/heat/engine/resources/quantum/floatingip.py b/heat/engine/resources/quantum/floatingip.py index fc214edf..b10de724 100644 --- a/heat/engine/resources/quantum/floatingip.py +++ b/heat/engine/resources/quantum/floatingip.py @@ -48,8 +48,12 @@ class FloatingIP(quantum.QuantumResource): raise ex def FnGetAtt(self, key): - attributes = self.quantum().show_floatingip( - self.resource_id)['floatingip'] + try: + attributes = self.quantum().show_floatingip( + self.resource_id)['floatingip'] + except QuantumClientException as ex: + logger.warn("failed to fetch resource attributes: %s" % str(ex)) + return None return self.handle_get_attributes(self.name, key, attributes) diff --git a/heat/engine/resources/quantum/net.py b/heat/engine/resources/quantum/net.py index 2fa9dc5f..2b60a76e 100644 --- a/heat/engine/resources/quantum/net.py +++ b/heat/engine/resources/quantum/net.py @@ -17,6 +17,9 @@ from heat.engine import clients from heat.openstack.common import log as logging from heat.engine.resources.quantum import quantum +if clients.quantumclient is not None: + from quantumclient.common.exceptions import QuantumClientException + logger = logging.getLogger(__name__) @@ -46,8 +49,6 @@ class Net(quantum.QuantumResource): return self.is_built(attributes) def handle_delete(self): - from quantumclient.common.exceptions import QuantumClientException - client = self.quantum() try: client.delete_network(self.resource_id) @@ -56,7 +57,11 @@ class Net(quantum.QuantumResource): raise ex def FnGetAtt(self, key): - attributes = self._show_resource() + try: + attributes = self._show_resource() + except QuantumClientException as ex: + logger.warn("failed to fetch resource attributes: %s" % str(ex)) + return None return self.handle_get_attributes(self.name, key, attributes) diff --git a/heat/engine/resources/quantum/port.py b/heat/engine/resources/quantum/port.py index 1ae72711..d2fe9ba7 100644 --- a/heat/engine/resources/quantum/port.py +++ b/heat/engine/resources/quantum/port.py @@ -17,6 +17,9 @@ from heat.engine import clients from heat.openstack.common import log as logging from heat.engine.resources.quantum import quantum +if clients.quantumclient is not None: + from quantumclient.common.exceptions import QuantumClientException + logger = logging.getLogger(__name__) @@ -59,8 +62,6 @@ class Port(quantum.QuantumResource): return self.is_built(attributes) def handle_delete(self): - from quantumclient.common.exceptions import QuantumClientException - client = self.quantum() try: client.delete_port(self.resource_id) @@ -69,7 +70,11 @@ class Port(quantum.QuantumResource): raise ex def FnGetAtt(self, key): - attributes = self._show_resource() + try: + attributes = self._show_resource() + except QuantumClientException as ex: + logger.warn("failed to fetch resource attributes: %s" % str(ex)) + return None return self.handle_get_attributes(self.name, key, attributes) diff --git a/heat/engine/resources/quantum/router.py b/heat/engine/resources/quantum/router.py index af704817..2915beea 100644 --- a/heat/engine/resources/quantum/router.py +++ b/heat/engine/resources/quantum/router.py @@ -58,7 +58,11 @@ class Router(quantum.QuantumResource): raise ex def FnGetAtt(self, key): - attributes = self._show_resource() + try: + attributes = self._show_resource() + except QuantumClientException as ex: + logger.warn("failed to fetch resource attributes: %s" % str(ex)) + return None return self.handle_get_attributes(self.name, key, attributes) diff --git a/heat/engine/resources/quantum/subnet.py b/heat/engine/resources/quantum/subnet.py index 3cf2f9c7..b04b9dc6 100644 --- a/heat/engine/resources/quantum/subnet.py +++ b/heat/engine/resources/quantum/subnet.py @@ -17,6 +17,9 @@ from heat.engine import clients from heat.openstack.common import log as logging from heat.engine.resources.quantum import quantum +if clients.quantumclient is not None: + from quantumclient.common.exceptions import QuantumClientException + logger = logging.getLogger(__name__) @@ -56,8 +59,6 @@ class Subnet(quantum.QuantumResource): self.resource_id_set(subnet['id']) def handle_delete(self): - from quantumclient.common.exceptions import QuantumClientException - client = self.quantum() try: client.delete_subnet(self.resource_id) @@ -66,8 +67,12 @@ class Subnet(quantum.QuantumResource): raise ex def FnGetAtt(self, key): - attributes = self.quantum().show_subnet( - self.resource_id)['subnet'] + try: + attributes = self.quantum().show_subnet( + self.resource_id)['subnet'] + except QuantumClientException as ex: + logger.warn("failed to fetch resource attributes: %s" % str(ex)) + return None return self.handle_get_attributes(self.name, key, attributes) diff --git a/heat/tests/test_quantum.py b/heat/tests/test_quantum.py index ecc65dc6..0115c24f 100644 --- a/heat/tests/test_quantum.py +++ b/heat/tests/test_quantum.py @@ -30,6 +30,7 @@ from heat.tests.utils import setup_dummy_db from heat.tests.utils import parse_stack quantumclient = try_import('quantumclient.v2_0.client') +qe = try_import('quantumclient.common.exceptions') quantum_template = ''' { @@ -218,6 +219,22 @@ class QuantumNetTest(HeatTestCase): "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" }}) + quantumclient.Client.show_network( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndReturn({"network": { + "status": "ACTIVE", + "subnets": [], + "name": "name", + "admin_state_up": False, + "shared": False, + "tenant_id": "c1210485b2424d48804aad5d39c61b8f", + "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" + }}) + + quantumclient.Client.show_network( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndRaise(qe.QuantumClientException(status_code=404)) + quantumclient.Client.show_network( 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' ).MultipleTimes().AndReturn({"network": { @@ -234,6 +251,10 @@ class QuantumNetTest(HeatTestCase): 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' ).AndReturn(None) + quantumclient.Client.delete_network( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndRaise(qe.QuantumClientException(status_code=404)) + self.m.ReplayAll() t = template_format.parse(quantum_template) stack = parse_stack(t) @@ -244,6 +265,7 @@ class QuantumNetTest(HeatTestCase): ref_id = resource.FnGetRefId() self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id) + self.assertEqual(None, resource.FnGetAtt('status')) self.assertEqual('ACTIVE', resource.FnGetAtt('status')) try: resource.FnGetAtt('Foo') @@ -256,6 +278,8 @@ class QuantumNetTest(HeatTestCase): self.assertEqual(net.Net.UPDATE_REPLACE, resource.handle_update({})) + resource.delete() + resource.state_set(resource.CREATE_COMPLETE, 'to delete again') resource.delete() self.m.VerifyAll() @@ -304,6 +328,9 @@ class QuantumSubnetTest(HeatTestCase): "tenant_id": "c1210485b2424d48804aad5d39c61b8f" } }) + quantumclient.Client.show_subnet( + '91e47a57-7508-46fe-afc9-fc454e8580e1').AndRaise( + qe.QuantumClientException(status_code=404)) quantumclient.Client.show_subnet( '91e47a57-7508-46fe-afc9-fc454e8580e1').MultipleTimes().AndReturn({ "subnet": { @@ -320,9 +347,13 @@ class QuantumSubnetTest(HeatTestCase): "enable_dhcp": False, } }) + quantumclient.Client.delete_subnet( '91e47a57-7508-46fe-afc9-fc454e8580e1' ).AndReturn(None) + quantumclient.Client.delete_subnet( + '91e47a57-7508-46fe-afc9-fc454e8580e1' + ).AndRaise(qe.QuantumClientException(status_code=404)) self.m.ReplayAll() t = template_format.parse(quantum_template) @@ -333,6 +364,8 @@ class QuantumSubnetTest(HeatTestCase): ref_id = resource.FnGetRefId() self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id) + self.assertEqual(None, + resource.FnGetAtt('network_id')) self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', resource.FnGetAtt('network_id')) self.assertEqual('8.8.8.8', resource.FnGetAtt('dns_nameservers')[0]) @@ -342,7 +375,9 @@ class QuantumSubnetTest(HeatTestCase): self.assertEqual(subnet.Subnet.UPDATE_REPLACE, resource.handle_update({})) - resource.delete() + self.assertEqual(resource.delete(), None) + resource.state_set(resource.CREATE_COMPLETE, 'to delete again') + self.assertEqual(resource.delete(), None) self.m.VerifyAll() @@ -369,6 +404,9 @@ class QuantumFloatingIPTest(HeatTestCase): "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" }}) + quantumclient.Client.show_floatingip( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndRaise(qe.QuantumClientException(status_code=404)) quantumclient.Client.show_floatingip( 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' ).MultipleTimes().AndReturn({'floatingip': { @@ -378,6 +416,9 @@ class QuantumFloatingIPTest(HeatTestCase): quantumclient.Client.delete_floatingip( 'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndReturn(None) + quantumclient.Client.delete_floatingip( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndRaise( + qe.QuantumClientException(status_code=404)) self.m.ReplayAll() t = template_format.parse(quantum_floating_template) @@ -391,6 +432,7 @@ class QuantumFloatingIPTest(HeatTestCase): fip_id = fip.FnGetRefId() self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', fip_id) + self.assertEqual(None, fip.FnGetAtt('status')) self.assertEqual('ACTIVE', fip.FnGetAtt('status')) try: fip.FnGetAtt('Foo') @@ -403,6 +445,8 @@ class QuantumFloatingIPTest(HeatTestCase): self.assertEqual(floatingip.FloatingIP.UPDATE_REPLACE, fip.handle_update({})) self.assertEqual(fip.delete(), None) + fip.state_set(fip.CREATE_COMPLETE, 'to delete again') + self.assertEqual(fip.delete(), None) self.m.VerifyAll() @@ -425,6 +469,15 @@ class QuantumFloatingIPTest(HeatTestCase): "status": "BUILD", "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" }}) + quantumclient.Client.show_port( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndReturn({'port': { + "status": "ACTIVE", + "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766" + }}) + quantumclient.Client.show_port( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndRaise(qe.QuantumClientException(status_code=404)) quantumclient.Client.show_port( 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' ).MultipleTimes().AndReturn({'port': { @@ -445,6 +498,7 @@ class QuantumFloatingIPTest(HeatTestCase): port_id = p.FnGetRefId() self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', port_id) + self.assertEqual(None, p.FnGetAtt('status')) self.assertEqual('ACTIVE', p.FnGetAtt('status')) try: p.FnGetAtt('Foo') @@ -510,6 +564,20 @@ class QuantumFloatingIPTest(HeatTestCase): 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' ).AndReturn(None) + quantumclient.Client.update_floatingip( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766', + {'floatingip': { + 'port_id': None + }}).AndRaise(qe.QuantumClientException(status_code=404)) + + quantumclient.Client.delete_port( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndRaise(qe.QuantumClientException(status_code=404)) + + quantumclient.Client.delete_floatingip( + 'fc68ea2c-b60b-4b4f-bd82-94ec81110766' + ).AndRaise(qe.QuantumClientException(status_code=404)) + self.m.ReplayAll() t = template_format.parse(quantum_floating_template) @@ -541,4 +609,12 @@ class QuantumFloatingIPTest(HeatTestCase): self.assertEqual(p.delete(), None) self.assertEqual(fip.delete(), None) + fipa.state_set(fipa.CREATE_COMPLETE, 'to delete again') + fip.state_set(fip.CREATE_COMPLETE, 'to delete again') + p.state_set(p.CREATE_COMPLETE, 'to delete again') + + self.assertEqual(fipa.delete(), None) + self.assertEqual(p.delete(), None) + self.assertEqual(fip.delete(), None) + self.m.VerifyAll() -- 2.45.2