NSX|V3+P: Improve router interface actions performance

- Remove duplicated code and reuse common code
- Reduce the number of calls to get_network / get_subnet / get_port
  by using previous results

Change-Id: If669f149a3a91186b1b96ffc7768be42195345b2
This commit is contained in:
Adit Sarfaty 2019-08-15 11:41:37 +03:00
parent e98e3b563a
commit cf33e4698a
4 changed files with 75 additions and 88 deletions

View File

@ -116,7 +116,8 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
network = self.get_network(context, net_id) network = self.get_network(context, net_id)
return network.get(ext_address_scope.IPV4_ADDRESS_SCOPE) return network.get(ext_address_scope.IPV4_ADDRESS_SCOPE)
def _get_subnet_address_scope(self, context, subnet_id): def _get_subnet_address_scope(self, context, subnet_id, subnet=None):
if not subnet:
subnet = self.get_subnet(context, subnet_id) subnet = self.get_subnet(context, subnet_id)
if not subnet['subnetpool_id']: if not subnet['subnetpool_id']:
return return
@ -130,14 +131,15 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
return subnetpool.get('address_scope_id', '') return subnetpool.get('address_scope_id', '')
def _validate_address_scope_for_router_interface(self, context, router_id, def _validate_address_scope_for_router_interface(self, context, router_id,
gw_network_id, subnet_id): gw_network_id, subnet_id,
subnet=None):
"""Validate that the GW address scope is the same as the interface""" """Validate that the GW address scope is the same as the interface"""
gw_address_scope = self._get_network_address_scope(context, gw_address_scope = self._get_network_address_scope(context,
gw_network_id) gw_network_id)
if not gw_address_scope: if not gw_address_scope:
return return
subnet_address_scope = self._get_subnet_address_scope(context, subnet_address_scope = self._get_subnet_address_scope(
subnet_id) context, subnet_id, subnet=subnet)
if (not subnet_address_scope or if (not subnet_address_scope or
subnet_address_scope != gw_address_scope): subnet_address_scope != gw_address_scope):
raise nsx_exc.NsxRouterInterfaceDoesNotMatchAddressScope( raise nsx_exc.NsxRouterInterfaceDoesNotMatchAddressScope(
@ -386,16 +388,6 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
if qos_policy_id: if qos_policy_id:
qos_com_utils.validate_policy_accessable(context, qos_policy_id) qos_com_utils.validate_policy_accessable(context, qos_policy_id)
def _get_interface_network(self, context, interface_info):
is_port, is_sub = self._validate_interface_info(interface_info)
if is_port:
net_id = self.get_port(context,
interface_info['port_id'])['network_id']
elif is_sub:
net_id = self.get_subnet(context,
interface_info['subnet_id'])['network_id']
return net_id
def _process_extra_attr_router_create(self, context, router_db, r): def _process_extra_attr_router_create(self, context, router_db, r):
for extra_attr in l3_attrs_db.get_attr_info().keys(): for extra_attr in l3_attrs_db.get_attr_info().keys():
if (extra_attr in r and if (extra_attr in r and

View File

@ -52,6 +52,7 @@ from neutron_lib.api.definitions import allowedaddresspairs as addr_apidef
from neutron_lib.api.definitions import availability_zone as az_def from neutron_lib.api.definitions import availability_zone as az_def
from neutron_lib.api.definitions import external_net as extnet_apidef from neutron_lib.api.definitions import external_net as extnet_apidef
from neutron_lib.api.definitions import extra_dhcp_opt as ext_edo from neutron_lib.api.definitions import extra_dhcp_opt as ext_edo
from neutron_lib.api.definitions import l3 as l3_apidef
from neutron_lib.api.definitions import port_security as psec from neutron_lib.api.definitions import port_security as psec
from neutron_lib.api.definitions import portbindings as pbin from neutron_lib.api.definitions import portbindings as pbin
from neutron_lib.api.definitions import provider_net as pnet from neutron_lib.api.definitions import provider_net as pnet
@ -287,7 +288,10 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
if subnet_id: if subnet_id:
return self.get_subnet(context, subnet_id) return self.get_subnet(context, subnet_id)
def _get_interface_network(self, context, interface_info): def _get_interface_network_id(self, context, interface_info, subnet=None):
if subnet:
return subnet['network_id']
is_port, is_sub = self._validate_interface_info(interface_info) is_port, is_sub = self._validate_interface_info(interface_info)
if is_port: if is_port:
net_id = self.get_port(context, net_id = self.get_port(context,
@ -310,15 +314,14 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
sg_rule[sg_prefix.LOCAL_IP_PREFIX].startswith('::/'))): sg_rule[sg_prefix.LOCAL_IP_PREFIX].startswith('::/'))):
sg_rule[sg_prefix.LOCAL_IP_PREFIX] = None sg_rule[sg_prefix.LOCAL_IP_PREFIX] = None
def _validate_interface_address_scope(self, context, def _validate_interface_address_scope(self, context, router_db,
router_db, interface_info): interface_subnet):
gw_network_id = (router_db.gw_port.network_id if router_db.gw_port gw_network_id = (router_db.gw_port.network_id if router_db.gw_port
else None) else None)
subnet = self.get_subnet(context, interface_info['subnet_ids'][0])
if not router_db.enable_snat and gw_network_id: if not router_db.enable_snat and gw_network_id:
self._validate_address_scope_for_router_interface( self._validate_address_scope_for_router_interface(
context.elevated(), router_db.id, gw_network_id, subnet['id']) context.elevated(), router_db.id, gw_network_id,
interface_subnet['id'], subnet=interface_subnet)
def _validate_address_pairs(self, address_pairs): def _validate_address_pairs(self, address_pairs):
for pair in address_pairs: for pair in address_pairs:
@ -1260,6 +1263,10 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
""" """
pass pass
def _get_router_gw_info(self, context, router_id):
router = self.get_router(context, router_id)
return router.get(l3_apidef.EXTERNAL_GW_INFO, {})
def _validate_router_gw_and_tz(self, context, router_id, info, def _validate_router_gw_and_tz(self, context, router_id, info,
org_enable_snat, router_subnets): org_enable_snat, router_subnets):
# Ensure that a router cannot have SNAT disabled if there are # Ensure that a router cannot have SNAT disabled if there are
@ -1280,6 +1287,10 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
self._validate_router_tz(context, new_tier0_uuid, self._validate_router_tz(context, new_tier0_uuid,
router_subnets) router_subnets)
def _get_tier0_uuid_by_router(self, context, router):
network_id = router.gw_port_id and router.gw_port.network_id
return self._get_tier0_uuid_by_net_id(context, network_id)
def _validate_gw_overlap_interfaces(self, context, gateway_net, def _validate_gw_overlap_interfaces(self, context, gateway_net,
interfaces_networks): interfaces_networks):
# Ensure that interface subnets cannot overlap with the GW subnet # Ensure that interface subnets cannot overlap with the GW subnet

View File

@ -873,7 +873,7 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
return updated_net return updated_net
def _update_slaac_on_router(self, context, router_id, def _update_slaac_on_router(self, context, router_id,
subnet, delete=False): subnet, router_subnets, delete=False):
# TODO(annak): redesign when policy supports downlink-level # TODO(annak): redesign when policy supports downlink-level
# ndra profile attachment # ndra profile attachment
@ -892,12 +892,9 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
profile_id = SLAAC_NDRA_PROFILE_ID profile_id = SLAAC_NDRA_PROFILE_ID
if delete: if delete:
rtr_subnets = self._find_router_subnets(context.elevated(),
router_id)
# check if there is another slaac overlay subnet that needs # check if there is another slaac overlay subnet that needs
# advertising (vlan advertising is attached on interface level) # advertising (vlan advertising is attached on interface level)
slaac_subnets = [s for s in rtr_subnets slaac_subnets = [s for s in router_subnets
if s['id'] != subnet['id'] and if s['id'] != subnet['id'] and
s.get('ipv6_address_mode') == 'slaac' and s.get('ipv6_address_mode') == 'slaac' and
self._is_overlay_network(context, self._is_overlay_network(context,
@ -1428,10 +1425,6 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
return (ports if not fields else return (ports if not fields else
[db_utils.resource_fields(port, fields) for port in ports]) [db_utils.resource_fields(port, fields) for port in ports])
def _get_tier0_uuid_by_router(self, context, router):
network_id = router.gw_port_id and router.gw_port.network_id
return self._get_tier0_uuid_by_net_id(context, network_id)
def _add_subnet_snat_rule(self, context, router_id, subnet, def _add_subnet_snat_rule(self, context, router_id, subnet,
gw_address_scope, gw_ip): gw_address_scope, gw_ip):
if not self._need_router_snat_rules(context, router_id, subnet, if not self._need_router_snat_rules(context, router_id, subnet,
@ -1621,10 +1614,6 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
# remove the edge cluster from the tier1 router # remove the edge cluster from the tier1 router
self.nsxpolicy.tier1.remove_edge_cluster(router_id) self.nsxpolicy.tier1.remove_edge_cluster(router_id)
def _get_router_gw_info(self, context, router_id):
router = self.get_router(context, router_id)
return router.get(l3_apidef.EXTERNAL_GW_INFO, {})
def _update_router_gw_info(self, context, router_id, info, def _update_router_gw_info(self, context, router_id, info,
called_from=None): called_from=None):
# Get the original data of the router GW # Get the original data of the router GW
@ -1654,8 +1643,6 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
new_enable_snat = router.enable_snat new_enable_snat = router.enable_snat
newaddr, newmask, _newnexthop = self._get_external_attachment_info( newaddr, newmask, _newnexthop = self._get_external_attachment_info(
context, router) context, router)
router_subnets = self._find_router_subnets(
context.elevated(), router_id)
sr_currently_exists = self.verify_sr_at_backend(router_id) sr_currently_exists = self.verify_sr_at_backend(router_id)
fw_exist = self._router_has_edge_fw_rules(context, router) fw_exist = self._router_has_edge_fw_rules(context, router)
vpn_exist = self.service_router_has_vpnaas(context, router_id) vpn_exist = self.service_router_has_vpnaas(context, router_id)
@ -1802,8 +1789,8 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
return self.get_router(context, router['id']) return self.get_router(context, router['id'])
def delete_router(self, context, router_id): def delete_router(self, context, router_id):
router = self.get_router(context, router_id) gw_info = self._get_router_gw_info(context, router_id)
if router.get(l3_apidef.EXTERNAL_GW_INFO): if gw_info:
try: try:
self._update_router_gw_info(context, router_id, {}, self._update_router_gw_info(context, router_id, {},
called_from="delete") called_from="delete")
@ -1928,16 +1915,17 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
@nsx_plugin_common.api_replay_mode_wrapper @nsx_plugin_common.api_replay_mode_wrapper
def add_router_interface(self, context, router_id, interface_info): def add_router_interface(self, context, router_id, interface_info):
network_id = self._get_interface_network(context, interface_info) # NOTE: In dual stack case, neutron would create a separate interface
# for each IP version
# We only allow one subnet per IP version
subnet = self._get_interface_subnet(context, interface_info)
network_id = self._get_interface_network_id(context, interface_info,
subnet=subnet)
extern_net = self._network_is_external(context, network_id) extern_net = self._network_is_external(context, network_id)
overlay_net = self._is_overlay_network(context, network_id) overlay_net = self._is_overlay_network(context, network_id)
router_db = self._get_router(context, router_id) router_db = self._get_router(context, router_id)
gw_network_id = (router_db.gw_port.network_id if router_db.gw_port gw_network_id = (router_db.gw_port.network_id if router_db.gw_port
else None) else None)
# NOTE: In dual stack case, neutron would create a separate interface
# for each IP version
# We only allow one subnet per IP version
subnet = self._get_interface_subnet(context, interface_info)
with locking.LockManager.get_lock(str(network_id)): with locking.LockManager.get_lock(str(network_id)):
# disallow more than one subnets belong to same network being # disallow more than one subnets belong to same network being
@ -1969,21 +1957,21 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
try: try:
# If it is a no-snat router, interface address scope must be the # If it is a no-snat router, interface address scope must be the
# same as the gateways # same as the gateways
self._validate_interface_address_scope(context, router_db, info) self._validate_interface_address_scope(context, router_db, subnet)
# Check GW & subnets TZ # Check GW & subnets TZ
subnets = self._find_router_subnets(context.elevated(), router_id)
tier0_uuid = self._get_tier0_uuid_by_router( tier0_uuid = self._get_tier0_uuid_by_router(
context.elevated(), router_db) context.elevated(), router_db)
# Validate the TZ of the new subnet match the one of the router # Validate the TZ of the new subnet match the one of the router
self._validate_router_tz(context.elevated(), tier0_uuid, [subnet]) self._validate_router_tz(context.elevated(), tier0_uuid, [subnet])
segment_id = self._get_network_nsx_segment_id(context, network_id) segment_id = self._get_network_nsx_segment_id(context, network_id)
subnet = self.get_subnet(context, info['subnet_ids'][0]) rtr_subnets = self._find_router_subnets(context.elevated(),
router_id)
if overlay_net: if overlay_net:
# overlay interface # overlay interface
pol_subnets = [] pol_subnets = []
for rtr_subnet in subnets: for rtr_subnet in rtr_subnets:
# For dual stack, we allow one v4 and one v6 # For dual stack, we allow one v4 and one v6
# subnet per network # subnet per network
if rtr_subnet['network_id'] == network_id: if rtr_subnet['network_id'] == network_id:
@ -1998,11 +1986,11 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
# will update the router only if needed # will update the router only if needed
self._update_slaac_on_router(context, router_id, self._update_slaac_on_router(context, router_id,
subnet) subnet, rtr_subnets)
else: else:
# Vlan interface # Vlan interface
pol_subnets = [] pol_subnets = []
for rtr_subnet in subnets: for rtr_subnet in rtr_subnets:
if rtr_subnet['network_id'] == network_id: if rtr_subnet['network_id'] == network_id:
prefix_len = int(rtr_subnet['cidr'].split('/')[1]) prefix_len = int(rtr_subnet['cidr'].split('/')[1])
pol_subnets.append(policy_defs.InterfaceSubnet( pol_subnets.append(policy_defs.InterfaceSubnet(
@ -2032,7 +2020,7 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
# if this is an ipv6 subnet and router has GW, # if this is an ipv6 subnet and router has GW,
# we need to add advertisement rule # we need to add advertisement rule
self._update_router_advertisement_rules( self._update_router_advertisement_rules(
router_id, subnets, True) router_id, rtr_subnets, True)
# update firewall rules # update firewall rules
self.update_router_firewall(context, router_id, router_db) self.update_router_firewall(context, router_id, router_db)
@ -2048,7 +2036,6 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
return info return info
def remove_router_interface(self, context, router_id, interface_info): def remove_router_interface(self, context, router_id, interface_info):
LOG.info("Removing router %s interface %s", router_id, interface_info)
# find the subnet - it is need for removing the SNAT rule # find the subnet - it is need for removing the SNAT rule
subnet = subnet_id = None subnet = subnet_id = None
if 'port_id' in interface_info: if 'port_id' in interface_info:
@ -2068,13 +2055,13 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
overlay_net = self._is_overlay_network(context, network_id) overlay_net = self._is_overlay_network(context, network_id)
segment_id = self._get_network_nsx_segment_id(context, network_id) segment_id = self._get_network_nsx_segment_id(context, network_id)
subnets = self._find_router_subnets(context.elevated(), rtr_subnets = self._find_router_subnets(context.elevated(),
router_id) router_id)
try: try:
if overlay_net: if overlay_net:
# Remove the tier1 router from this segment on the NSX # Remove the tier1 router from this segment on the NSX
pol_subnets = [] pol_subnets = []
for rtr_subnet in subnets: for rtr_subnet in rtr_subnets:
# For dual stack, we allow one v4 and one v6 # For dual stack, we allow one v4 and one v6
# subnet per network # subnet per network
if rtr_subnet['network_id'] == network_id: if rtr_subnet['network_id'] == network_id:
@ -2093,12 +2080,12 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
# will update the router only if needed # will update the router only if needed
self._update_slaac_on_router(context, router_id, self._update_slaac_on_router(context, router_id,
subnet, delete=True) subnet, rtr_subnets, delete=True)
else: else:
# VLAN interface # VLAN interface
pol_subnets = [] pol_subnets = []
for rtr_subnet in subnets: for rtr_subnet in rtr_subnets:
if rtr_subnet['network_id'] == network_id: if rtr_subnet['network_id'] == network_id:
prefix_len = int(rtr_subnet['cidr'].split('/')[1]) prefix_len = int(rtr_subnet['cidr'].split('/')[1])
pol_subnets.append(policy_defs.InterfaceSubnet( pol_subnets.append(policy_defs.InterfaceSubnet(
@ -2125,7 +2112,7 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
# if this is an ipv6 subnet and router has GW, # if this is an ipv6 subnet and router has GW,
# we need to remove advertisement rule # we need to remove advertisement rule
self._update_router_advertisement_rules( self._update_router_advertisement_rules(
router_id, subnets, True) router_id, rtr_subnets, True)
# update firewall rules # update firewall rules
self.update_router_firewall(context, router_id, router_db) self.update_router_firewall(context, router_id, router_db)

View File

@ -2062,10 +2062,6 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
return (ports if not fields else return (ports if not fields else
[db_utils.resource_fields(port, fields) for port in ports]) [db_utils.resource_fields(port, fields) for port in ports])
def _get_tier0_uuid_by_router(self, context, router):
network_id = router.gw_port_id and router.gw_port.network_id
return self._get_tier0_uuid_by_net_id(context, network_id)
def _validate_router_tz(self, context, tier0_uuid, subnets): def _validate_router_tz(self, context, tier0_uuid, subnets):
# make sure the related GW (Tier0 router) belongs to the same TZ # make sure the related GW (Tier0 router) belongs to the same TZ
# as the subnets attached to the Tier1 router # as the subnets attached to the Tier1 router
@ -2349,8 +2345,8 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
if not cfg.CONF.nsx_v3.native_dhcp_metadata: if not cfg.CONF.nsx_v3.native_dhcp_metadata:
nsx_rpc.handle_router_metadata_access(self, context, router_id, nsx_rpc.handle_router_metadata_access(self, context, router_id,
interface=None) interface=None)
router = self.get_router(context, router_id) gw_info = self._get_router_gw_info(context, router_id)
if router.get(l3_apidef.EXTERNAL_GW_INFO): if gw_info:
self._update_router_gw_info(context, router_id, {}) self._update_router_gw_info(context, router_id, {})
nsx_router_id = nsx_db.get_nsx_router_id(context.session, nsx_router_id = nsx_db.get_nsx_router_id(context.session,
router_id) router_id)
@ -2663,15 +2659,16 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
@nsx_plugin_common.api_replay_mode_wrapper @nsx_plugin_common.api_replay_mode_wrapper
def add_router_interface(self, context, router_id, interface_info): def add_router_interface(self, context, router_id, interface_info):
network_id = self._get_interface_network(context, interface_info) # In case on dual stack, neutron creates a separate interface per
# IP version
subnet = self._get_interface_subnet(context, interface_info)
network_id = self._get_interface_network_id(context, interface_info,
subnet=subnet)
extern_net = self._network_is_external(context, network_id) extern_net = self._network_is_external(context, network_id)
overlay_net = self._is_overlay_network(context, network_id) overlay_net = self._is_overlay_network(context, network_id)
router_db = self._get_router(context, router_id) router_db = self._get_router(context, router_id)
gw_network_id = (router_db.gw_port.network_id if router_db.gw_port gw_network_id = (router_db.gw_port.network_id if router_db.gw_port
else None) else None)
# In case on dual stack, neutron creates a separate interface per
# IP version
subnet = self._get_interface_subnet(context, interface_info)
with locking.LockManager.get_lock(str(network_id)): with locking.LockManager.get_lock(str(network_id)):
# disallow more than one subnets belong to same network being # disallow more than one subnets belong to same network being
@ -2699,15 +2696,14 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
# Update the interface of the neutron router # Update the interface of the neutron router
info = super(NsxV3Plugin, self).add_router_interface( info = super(NsxV3Plugin, self).add_router_interface(
context, router_id, interface_info) context, router_id, interface_info)
try: try:
subnet = self.get_subnet(context, info['subnet_ids'][0])
port = self.get_port(context, info['port_id'])
nsx_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id( nsx_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
context.session, port['id']) context.session, info['port_id'])
# If it is a no-snat router, interface address scope must be the # If it is a no-snat router, interface address scope must be the
# same as the gateways # same as the gateways
self._validate_interface_address_scope(context, router_db, info) self._validate_interface_address_scope(context, router_db, subnet)
nsx_router_id = nsx_db.get_nsx_router_id(context.session, nsx_router_id = nsx_db.get_nsx_router_id(context.session,
router_id) router_id)
@ -2716,7 +2712,8 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
display_name = utils.get_name_and_uuid( display_name = utils.get_name_and_uuid(
subnet['name'] or 'subnet', subnet['id']) subnet['name'] or 'subnet', subnet['id'])
tags = self.nsxlib.build_v3_tags_payload( tags = self.nsxlib.build_v3_tags_payload(
port, resource_type='os-neutron-rport-id', {'id': info['port_id'], 'project_id': context.project_id},
resource_type='os-neutron-rport-id',
project_name=context.tenant_name) project_name=context.tenant_name)
tags.append({'scope': 'os-subnet-id', 'tag': subnet['id']}) tags.append({'scope': 'os-subnet-id', 'tag': subnet['id']})
@ -2729,12 +2726,10 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
resource_type = (None if overlay_net else resource_type = (None if overlay_net else
nsxlib_consts.LROUTERPORT_CENTRALIZED) nsxlib_consts.LROUTERPORT_CENTRALIZED)
# Check GW & subnets TZ # Validate the TZ of the new subnet match the one of the router
subnets = self._find_router_subnets(context.elevated(),
router_id)
tier0_uuid = self._get_tier0_uuid_by_router(context.elevated(), tier0_uuid = self._get_tier0_uuid_by_router(context.elevated(),
router_db) router_db)
self._validate_router_tz(context.elevated(), tier0_uuid, subnets) self._validate_router_tz(context.elevated(), tier0_uuid, [subnet])
# create the interface ports on the NSX # create the interface ports on the NSX
self.nsxlib.router.create_logical_router_intf_port_by_ls_id( self.nsxlib.router.create_logical_router_intf_port_by_ls_id(
@ -2788,14 +2783,17 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
return info return info
def remove_router_interface(self, context, router_id, interface_info): def remove_router_interface(self, context, router_id, interface_info):
self._validate_interface_info(interface_info, for_removal=True)
# Get the interface port & subnet
subnet = None subnet = None
subnet_id = None subnet_id = None
port_id = None port_id = None
self._validate_interface_info(interface_info, for_removal=True) network_id = None
if 'port_id' in interface_info: if 'port_id' in interface_info:
port_id = interface_info['port_id'] port_id = interface_info['port_id']
# find subnet_id - it is need for removing the SNAT rule # find subnet_id - it is need for removing the SNAT rule
port = self._get_port(context, port_id) port = self._get_port(context, port_id)
network_id = port['network_id']
if port.get('fixed_ips'): if port.get('fixed_ips'):
for fip in port['fixed_ips']: for fip in port['fixed_ips']:
subnet_id = fip['subnet_id'] subnet_id = fip['subnet_id']
@ -2810,11 +2808,9 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
self._confirm_router_interface_not_in_use( self._confirm_router_interface_not_in_use(
context, router_id, subnet_id) context, router_id, subnet_id)
subnet = self._get_subnet(context, subnet_id) subnet = self._get_subnet(context, subnet_id)
rport_qry = context.session.query(models_v2.Port) network_id = subnet['network_id']
ports = rport_qry.filter_by( ports = self._get_router_interface_ports_by_network(
device_id=router_id, context, router_id, network_id)
device_owner=l3_db.DEVICE_OWNER_ROUTER_INTF,
network_id=subnet['network_id'])
for p in ports: for p in ports:
fip_subnet_ids = [fixed_ip['subnet_id'] fip_subnet_ids = [fixed_ip['subnet_id']
for fixed_ip in p['fixed_ips']] for fixed_ip in p['fixed_ips']]
@ -2833,10 +2829,11 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
nsx_net_id, _nsx_port_id = nsx_db.get_nsx_switch_and_port_id( nsx_net_id, _nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
context.session, port_id) context.session, port_id)
subnet = self.get_subnet(context, subnet_id) if not subnet:
subnet = self._get_subnet(context, subnet_id)
ports, address_groups = self._get_ports_and_address_groups( ports, address_groups = self._get_ports_and_address_groups(
context, router_id, subnet['network_id'], context, router_id, network_id,
exclude_sub_ids=[subnet['id']]) exclude_sub_ids=[subnet_id])
nsx_router_id = nsx_db.get_nsx_router_id( nsx_router_id = nsx_db.get_nsx_router_id(
context.session, router_id) context.session, router_id)
if len(ports) >= 1: if len(ports) >= 1:
@ -2865,7 +2862,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
LOG.error("router port on router %(router_id)s for net " LOG.error("router port on router %(router_id)s for net "
"%(net_id)s not found at the backend", "%(net_id)s not found at the backend",
{'router_id': router_id, {'router_id': router_id,
'net_id': subnet['network_id']}) 'net_id': network_id})
# inform the FWaaS that interface port was removed # inform the FWaaS that interface port was removed
if self.fwaas_callbacks: if self.fwaas_callbacks: