Merge "prevent deletion of router interface if it is needed by a floating ip"
This commit is contained in:
commit
9a89ef7363
@ -351,6 +351,16 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
|
|||||||
return {'port_id': port['id'],
|
return {'port_id': port['id'],
|
||||||
'subnet_id': port['fixed_ips'][0]['subnet_id']}
|
'subnet_id': port['fixed_ips'][0]['subnet_id']}
|
||||||
|
|
||||||
|
def _confirm_router_interface_not_in_use(self, context, router_id,
|
||||||
|
subnet_id):
|
||||||
|
subnet_db = self._get_subnet(context, subnet_id)
|
||||||
|
subnet_cidr = netaddr.IPNetwork(subnet_db['cidr'])
|
||||||
|
fip_qry = context.session.query(FloatingIP)
|
||||||
|
for fip_db in fip_qry.filter_by(router_id=router_id):
|
||||||
|
if netaddr.IPAddress(fip_db['fixed_ip_address']) in subnet_cidr:
|
||||||
|
raise l3.RouterInterfaceInUseByFloatingIP(
|
||||||
|
router_id=router_id, subnet_id=subnet_id)
|
||||||
|
|
||||||
def remove_router_interface(self, context, router_id, interface_info):
|
def remove_router_interface(self, context, router_id, interface_info):
|
||||||
# make sure router exists
|
# make sure router exists
|
||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
@ -382,9 +392,15 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
|
|||||||
if port_db['device_id'] != router_id:
|
if port_db['device_id'] != router_id:
|
||||||
raise w_exc.HTTPConflict("port_id %s not used by router" %
|
raise w_exc.HTTPConflict("port_id %s not used by router" %
|
||||||
port_db['id'])
|
port_db['id'])
|
||||||
|
self._confirm_router_interface_not_in_use(
|
||||||
|
context, router_id,
|
||||||
|
port_db['fixed_ips'][0]['subnet_id'])
|
||||||
self.delete_port(context, port_db['id'], l3_port_check=False)
|
self.delete_port(context, port_db['id'], l3_port_check=False)
|
||||||
elif 'subnet_id' in interface_info:
|
elif 'subnet_id' in interface_info:
|
||||||
subnet_id = interface_info['subnet_id']
|
subnet_id = interface_info['subnet_id']
|
||||||
|
self._confirm_router_interface_not_in_use(context, router_id,
|
||||||
|
subnet_id)
|
||||||
|
|
||||||
subnet = self._get_subnet(context, subnet_id)
|
subnet = self._get_subnet(context, subnet_id)
|
||||||
found = False
|
found = False
|
||||||
|
|
||||||
|
@ -37,6 +37,12 @@ class RouterInUse(qexception.InUse):
|
|||||||
message = _("Router %(router_id)s still has active ports")
|
message = _("Router %(router_id)s still has active ports")
|
||||||
|
|
||||||
|
|
||||||
|
class RouterInterfaceInUseByFloatingIP(qexception.InUse):
|
||||||
|
message = _("Router interface for subnet %(subnet_id)s on router "
|
||||||
|
"%(router_id)s cannot be deleted, as it is required "
|
||||||
|
"by one or more floating IPs.")
|
||||||
|
|
||||||
|
|
||||||
class FloatingIPNotFound(qexception.NotFound):
|
class FloatingIPNotFound(qexception.NotFound):
|
||||||
message = _("Floating IP %(floatingip_id)s could not be found")
|
message = _("Floating IP %(floatingip_id)s could not be found")
|
||||||
|
|
||||||
|
@ -1099,6 +1099,33 @@ class L3NatDBTestCase(test_db_plugin.QuantumDbPluginV2TestCase):
|
|||||||
uuidutils.generate_uuid(), 'iamnotnanip')
|
uuidutils.generate_uuid(), 'iamnotnanip')
|
||||||
self.assertEqual(res.status_int, 400)
|
self.assertEqual(res.status_int, 400)
|
||||||
|
|
||||||
|
def test_floatingip_delete_router_intf_with_subnet_id_returns_409(self):
|
||||||
|
found = False
|
||||||
|
with self.floatingip_with_assoc() as fip:
|
||||||
|
for p in self._list('ports')['ports']:
|
||||||
|
if p['device_owner'] == 'network:router_interface':
|
||||||
|
subnet_id = p['fixed_ips'][0]['subnet_id']
|
||||||
|
router_id = p['device_id']
|
||||||
|
self._router_interface_action(
|
||||||
|
'remove', router_id, subnet_id, None,
|
||||||
|
expected_code=exc.HTTPConflict.code)
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
self.assertTrue(found)
|
||||||
|
|
||||||
|
def test_floatingip_delete_router_intf_with_port_id_returns_409(self):
|
||||||
|
found = False
|
||||||
|
with self.floatingip_with_assoc() as fip:
|
||||||
|
for p in self._list('ports')['ports']:
|
||||||
|
if p['device_owner'] == 'network:router_interface':
|
||||||
|
router_id = p['device_id']
|
||||||
|
self._router_interface_action(
|
||||||
|
'remove', router_id, None, p['id'],
|
||||||
|
expected_code=exc.HTTPConflict.code)
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
self.assertTrue(found)
|
||||||
|
|
||||||
def test_list_nets_external(self):
|
def test_list_nets_external(self):
|
||||||
with self.network() as n1:
|
with self.network() as n1:
|
||||||
self._set_net_external(n1['network']['id'])
|
self._set_net_external(n1['network']['id'])
|
||||||
|
Loading…
Reference in New Issue
Block a user