# figure out if we need to delete existing port
if gw_port and gw_port['network_id'] != network_id:
+ fip_count = self.get_floatingips_count(context.elevated(),
+ {'router_id': [router_id]})
+ if fip_count:
+ raise l3.RouterExternalGatewayInUseByFloatingIp(
+ router_id=router_id, net_id=gw_port['network_id'])
with context.session.begin(subtransactions=True):
router.gw_port = None
context.session.add(router)
"non-external, since it has existing gateway ports")
+class RouterExternalGatewayInUseByFloatingIp(qexception.InUse):
+ message = _("Gateway cannot be updated for router %(router_id), since a "
+ "gateway to external network %(net_id) is required by one or "
+ "more floating IPs.")
+
+
def _validate_uuid_or_none(data, valid_values=None):
if data is None:
return None
r['router']['id'],
s2['subnet']['network_id'])
+ def test_router_update_gateway_with_existed_floatingip(self):
+ with self.subnet() as subnet:
+ self._set_net_external(subnet['subnet']['network_id'])
+ with self.floatingip_with_assoc() as fip:
+ self._add_external_gateway_to_router(
+ fip['floatingip']['router_id'],
+ subnet['subnet']['network_id'],
+ expected_code=exc.HTTPConflict.code)
+
+ def test_router_update_gateway_to_empty_with_existed_floatingip(self):
+ with self.floatingip_with_assoc() as fip:
+ self._remove_external_gateway_from_router(
+ fip['floatingip']['router_id'], None,
+ expected_code=exc.HTTPConflict.code)
+
def test_router_add_gateway_invalid_network(self):
with self.router() as r:
self._add_external_gateway_to_router(
port_id=p['port']['id'])
self.assertEqual(res.status_int, exc.HTTPCreated.code)
floatingip = self.deserialize(fmt, res)
- self._remove_external_gateway_from_router(
- r['router']['id'],
- public_sub['subnet']['network_id'])
self._delete('routers', r['router']['id'],
expected_code=exc.HTTPConflict.code)
# Cleanup