Merge "Refactor external-network update to router gateway cascading effect"
This commit is contained in:
commit
2b5d080afb
@ -302,11 +302,6 @@ class DbBasePluginCommon(object):
|
||||
return subnet_obj.Route.get_objects(context,
|
||||
subnet_id=subnet_id)
|
||||
|
||||
def _get_router_gw_ports_by_network(self, context, network_id):
|
||||
return port_obj.Port.get_objects(
|
||||
context, network_id=network_id,
|
||||
device_owner=constants.DEVICE_OWNER_ROUTER_GW)
|
||||
|
||||
@db_api.CONTEXT_READER
|
||||
def _get_subnets_by_network(self, context, network_id):
|
||||
return subnet_obj.Subnet.get_objects(context, network_id=network_id)
|
||||
|
@ -73,7 +73,6 @@ from neutron.objects import network as network_obj
|
||||
from neutron.objects import ports as port_obj
|
||||
from neutron.objects import subnet as subnet_obj
|
||||
from neutron.objects import subnetpool as subnetpool_obj
|
||||
from neutron.services.ovn_l3 import plugin as l3_ovn
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -807,47 +806,10 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon,
|
||||
|
||||
def _update_router_gw_ports(self, context, network, subnet):
|
||||
l3plugin = directory.get_plugin(plugin_constants.L3)
|
||||
if l3plugin:
|
||||
s = subnet_obj.Subnet.get_object(context, id=subnet['id'])
|
||||
service_types = s.service_types
|
||||
update_types = ['', constants.DEVICE_OWNER_ROUTER_GW]
|
||||
if (not isinstance(l3plugin, l3_ovn.OVNL3RouterPlugin) and
|
||||
subnet['ip_version'] == constants.IP_VERSION_4 and
|
||||
all(s not in update_types for s in service_types)):
|
||||
return
|
||||
gw_ports = self._get_router_gw_ports_by_network(context,
|
||||
network['id'])
|
||||
router_ids = [p.device_id for p in gw_ports]
|
||||
for id in router_ids:
|
||||
try:
|
||||
self._update_router_gw_port(context, id, network, subnet)
|
||||
except l3_exc.RouterNotFound:
|
||||
LOG.debug("Router %(id)s was concurrently deleted while "
|
||||
"updating GW port for subnet %(s)s",
|
||||
{'id': id, 's': subnet})
|
||||
|
||||
def _update_router_gw_port(self, context, router_id, network, subnet):
|
||||
l3plugin = directory.get_plugin(plugin_constants.L3)
|
||||
ctx_admin = context.elevated()
|
||||
ext_subnets_dict = {s['id']: s for s in network['subnets']}
|
||||
router = l3plugin.get_router(ctx_admin, router_id)
|
||||
external_gateway_info = router['external_gateway_info']
|
||||
# Get all stateful (i.e. non-SLAAC/DHCPv6-stateless) fixed ips
|
||||
fips = [f for f in external_gateway_info['external_fixed_ips']
|
||||
if not ipv6_utils.is_auto_address_subnet(
|
||||
ext_subnets_dict[f['subnet_id']])]
|
||||
num_fips = len(fips)
|
||||
# Don't add the fixed IP to the port if it already
|
||||
# has a stateful fixed IP of the same IP version
|
||||
if num_fips > 1:
|
||||
return
|
||||
if num_fips == 1 and netaddr.IPAddress(
|
||||
fips[0]['ip_address']).version == subnet['ip_version']:
|
||||
return
|
||||
external_gateway_info['external_fixed_ips'].append(
|
||||
{'subnet_id': subnet['id']})
|
||||
info = {'router': {'external_gateway_info': external_gateway_info}}
|
||||
l3plugin.update_router(ctx_admin, router_id, info)
|
||||
# The hasattr check for customized l3 plugins that may have no such
|
||||
# function.
|
||||
if l3plugin and hasattr(l3plugin, "update_router_gw_ports"):
|
||||
l3plugin.update_router_gw_ports(context, network, subnet)
|
||||
|
||||
@db_api.retry_if_session_inactive()
|
||||
def _create_subnet_postcommit(self, context, result,
|
||||
|
@ -2322,3 +2322,51 @@ class L3_NAT_db_mixin(L3_NAT_dbonly_mixin, L3RpcNotifierMixin):
|
||||
if rp.port_type == old_owner:
|
||||
rp.port_type = new_owner
|
||||
rp.port.device_owner = new_owner
|
||||
|
||||
def _get_router_gw_ports_by_network(self, context, network_id):
|
||||
return port_obj.Port.get_objects(
|
||||
context, network_id=network_id,
|
||||
device_owner=constants.DEVICE_OWNER_ROUTER_GW)
|
||||
|
||||
def _update_router_gateway_ports(self, context, network, subnet):
|
||||
gw_ports = self._get_router_gw_ports_by_network(context,
|
||||
network['id'])
|
||||
router_ids = [p.device_id for p in gw_ports]
|
||||
for id in router_ids:
|
||||
try:
|
||||
self._update_router_gw_port(context, id, network, subnet)
|
||||
except l3_exc.RouterNotFound:
|
||||
LOG.debug("Router %(id)s was concurrently deleted while "
|
||||
"updating GW port for subnet %(s)s",
|
||||
{'id': id, 's': subnet})
|
||||
|
||||
def update_router_gw_ports(self, context, network, subnet):
|
||||
s = subnet_obj.Subnet.get_object(context, id=subnet['id'])
|
||||
service_types = s.service_types
|
||||
update_types = ['', constants.DEVICE_OWNER_ROUTER_GW]
|
||||
if (subnet['ip_version'] == constants.IP_VERSION_4 and
|
||||
all(s not in update_types for s in service_types)):
|
||||
return
|
||||
self._update_router_gateway_ports(context, network, subnet)
|
||||
|
||||
def _update_router_gw_port(self, context, router_id, network, subnet):
|
||||
ctx_admin = context.elevated()
|
||||
ext_subnets_dict = {s['id']: s for s in network['subnets']}
|
||||
router = self.get_router(ctx_admin, router_id)
|
||||
external_gateway_info = router['external_gateway_info']
|
||||
# Get all stateful (i.e. non-SLAAC/DHCPv6-stateless) fixed ips
|
||||
fips = [f for f in external_gateway_info['external_fixed_ips']
|
||||
if not ipv6_utils.is_auto_address_subnet(
|
||||
ext_subnets_dict[f['subnet_id']])]
|
||||
num_fips = len(fips)
|
||||
# Don't add the fixed IP to the port if it already
|
||||
# has a stateful fixed IP of the same IP version
|
||||
if num_fips > 1:
|
||||
return
|
||||
if num_fips == 1 and netaddr.IPAddress(
|
||||
fips[0]['ip_address']).version == subnet['ip_version']:
|
||||
return
|
||||
external_gateway_info['external_fixed_ips'].append(
|
||||
{'subnet_id': subnet['id']})
|
||||
info = {'router': {'external_gateway_info': external_gateway_info}}
|
||||
self.update_router(ctx_admin, router_id, info)
|
||||
|
@ -395,3 +395,6 @@ class OVNL3RouterPlugin(service_base.ServicePluginBase,
|
||||
@resource_extend.extends([l3_apidef.ROUTERS])
|
||||
def add_flavor_id(router_res, router_db):
|
||||
router_res['flavor_id'] = router_db['flavor_id']
|
||||
|
||||
def update_router_gw_ports(self, context, network, subnet):
|
||||
self._update_router_gateway_ports(context, network, subnet)
|
||||
|
@ -332,7 +332,7 @@ class L3DvrHATestCase(test_l3_dvr_router_plugin.L3DvrTestCase):
|
||||
|
||||
def _check_snat_external_gateway_presence(self, ext_net, router, gw_count):
|
||||
ext_net_id = ext_net['network']['id']
|
||||
gw_port = (self.l3_plugin._core_plugin.
|
||||
gw_port = (self.l3_plugin.
|
||||
_get_router_gw_ports_by_network(self.context, ext_net_id))
|
||||
self.assertEqual(gw_count, len(gw_port))
|
||||
if gw_count > 1:
|
||||
|
Loading…
Reference in New Issue
Block a user