Do not delete subnets with IPs on router interfaces

Bug 1152171

This patch simply causes a 409 to be returned when attempting to
delete a subnet which has IPs on ports whose device_owner is
network:router_interface

This does not address a similar problem that arises when the ips for
a port owned by a router_interface are updated. This problem is hidden
when updating a port which has been assigned the gateway_ip by an
exception in the IP recycling process. However, it will hit when the
port was explicitly added to the router, since it will have an ip
different from the subnet's gateway ip.

Change-Id: I38dfd2639acd03db8d3f1f933495a456a4a8724f
This commit is contained in:
Salvatore Orlando 2013-03-08 18:10:38 +01:00
parent 2e1cefbf48
commit e8dc595dde
3 changed files with 27 additions and 18 deletions

View File

@ -46,7 +46,7 @@ AGENT_OWNER_PREFIX = 'network:'
# finds out that all existing IP Allocations are associated with ports
# with these owners, it will allow subnet deletion to proceed with the
# IP allocations being cleaned up by cascade.
AUTO_DELETE_PORT_OWNERS = ['network:dhcp', 'network:router_interface']
AUTO_DELETE_PORT_OWNERS = ['network:dhcp']
class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):

View File

@ -602,6 +602,16 @@ class OvsAgentSchedulerTestCase(test_l3_plugin.L3NatTestCaseMixin,
router1['router']['id'])
l3_agents_2 = self._list_l3_agents_hosting_router(
router2['router']['id'])
# safe cleanup
self._router_interface_action('remove',
router1['router']['id'],
subnet1['subnet']['id'],
None)
self._router_interface_action('remove',
router2['router']['id'],
subnet2['subnet']['id'],
None)
# L3 agent will host only the compatible router.
self.assertEqual(1, num_hosta_routers)
self.assertEqual(1, len(l3_agents_1['agents']))

View File

@ -969,23 +969,6 @@ class L3NatDBTestCase(L3NatTestCaseBase):
r['router']['id'],
n['network']['id'], expected_code=exc.HTTPBadRequest.code)
def test_delete_unused_router_interface(self):
with self.network() as n:
with self.router() as r:
with self.subnet(network=n) as s:
res = self._create_port(self.fmt,
s['subnet']['network_id'])
p = self.deserialize(self.fmt, res)
self._router_interface_action('add',
r['router']['id'],
None,
p['port']['id'])
# The subnet here is deleted, and the port should have no IP
self._delete('ports', p['port']['id'])
# Verify the port has been deleted
self._show('ports', p['port']['id'],
expected_code=exc.HTTPNotFound.code)
def test_router_remove_interface_inuse_returns_409(self):
with self.router() as r:
with self.subnet() as s:
@ -1635,6 +1618,22 @@ class L3NatDBTestCase(L3NatTestCaseBase):
self.assertTrue(floatingips[0]['fixed_ip_address'] is not None)
self.assertTrue(floatingips[0]['router_id'] is not None)
def test_router_delete_subnet_inuse_returns_409(self):
with self.router() as r:
with self.subnet() as s:
self._router_interface_action('add',
r['router']['id'],
s['subnet']['id'],
None)
# subnet cannot be delete as it's attached to a router
self._delete('subnets', s['subnet']['id'],
expected_code=exc.HTTPConflict.code)
# remove interface so test can exit without errors
self._router_interface_action('remove',
r['router']['id'],
s['subnet']['id'],
None)
class L3NatDBTestCaseXML(L3NatDBTestCase):
fmt = 'xml'