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:
parent
e98e3b563a
commit
cf33e4698a
@ -116,8 +116,9 @@ 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):
|
||||||
subnet = self.get_subnet(context, subnet_id)
|
if not subnet:
|
||||||
|
subnet = self.get_subnet(context, subnet_id)
|
||||||
if not subnet['subnetpool_id']:
|
if not subnet['subnetpool_id']:
|
||||||
return
|
return
|
||||||
subnetpool = self.get_subnetpool(context, subnet['subnetpool_id'])
|
subnetpool = self.get_subnetpool(context, subnet['subnetpool_id'])
|
||||||
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
@ -1964,26 +1952,26 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
|||||||
|
|
||||||
# Update the interface of the neutron router
|
# Update the interface of the neutron router
|
||||||
info = super(NsxPolicyPlugin, self).add_router_interface(
|
info = super(NsxPolicyPlugin, self).add_router_interface(
|
||||||
context, router_id, interface_info)
|
context, router_id, interface_info)
|
||||||
|
|
||||||
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)
|
||||||
|
@ -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
|
||||||
@ -2698,16 +2695,15 @@ 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:
|
||||||
|
Loading…
Reference in New Issue
Block a user