Merge "NSXv: Adding notifications for router service edge events"

This commit is contained in:
Jenkins 2017-04-09 15:00:22 +00:00 committed by Gerrit Code Review
commit 17961d4edd
4 changed files with 127 additions and 84 deletions

View File

@ -16,10 +16,13 @@ import abc
import six import six
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.db import l3_db from neutron.db import l3_db
from neutron.db import models_v2 from neutron.db import models_v2
from vmware_nsx._i18n import _ from vmware_nsx._i18n import _
from vmware_nsx.common import exceptions as nsxv_exc from vmware_nsx.common import exceptions as nsxv_exc
from vmware_nsx.common import nsxv_constants
from vmware_nsx.plugins.nsx_v.vshield import edge_utils from vmware_nsx.plugins.nsx_v.vshield import edge_utils
@ -73,6 +76,15 @@ class RouterBaseDriver(RouterAbstractDriver):
self.edge_manager = plugin.edge_manager self.edge_manager = plugin.edge_manager
self.vcns = self.nsx_v.vcns self.vcns = self.nsx_v.vcns
def _notify_after_router_edge_association(self, context, router):
registry.notify(nsxv_constants.SERVICE_EDGE, events.AFTER_CREATE,
self, context=context, router=router)
def _notify_before_router_edge_association(self, context, router,
edge_id=None):
registry.notify(nsxv_constants.SERVICE_EDGE, events.BEFORE_DELETE,
self, context=context, router=router, edge_id=edge_id)
def _get_external_network_id_by_router(self, context, router_id): def _get_external_network_id_by_router(self, context, router_id):
"""Get router's external network id if it has.""" """Get router's external network id if it has."""
router = self.plugin.get_router(context, router_id) router = self.plugin.get_router(context, router_id)

View File

@ -225,6 +225,9 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
md_gw_data = self._get_metadata_gw_data(context, router_id) md_gw_data = self._get_metadata_gw_data(context, router_id)
self._update_routes(context, router_id, newnexthop, md_gw_data) self._update_routes(context, router_id, newnexthop, md_gw_data)
if new_ext_net_id:
self._notify_after_router_edge_association(context, router)
def _validate_multiple_subnets_routers(self, context, router_id, def _validate_multiple_subnets_routers(self, context, router_id,
interface_info): interface_info):
_nsxv_plugin = self.plugin _nsxv_plugin = self.plugin
@ -262,26 +265,23 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
network_id = subnet['network_id'] network_id = subnet['network_id']
address_groups = self.plugin._get_address_groups( address_groups = self.plugin._get_address_groups(
context, router_id, network_id) context, router_id, network_id)
with locking.LockManager.get_lock(self._get_edge_id(context, edge_id = self._get_edge_id(context, router_id)
router_id)): interface_created = False
port = self.plugin.get_port(context, info['port_id']) port = self.plugin.get_port(context, info['port_id'])
try: try:
with locking.LockManager.get_lock(str(edge_id)):
edge_utils.add_vdr_internal_interface(self.nsx_v, context, edge_utils.add_vdr_internal_interface(self.nsx_v, context,
router_id, network_id, router_id, network_id,
address_groups, address_groups,
router_db.admin_state_up) router_db.admin_state_up)
except Exception: interface_created = True
with excutils.save_and_reraise_exception():
super(nsx_v.NsxVPluginV2, self.plugin
).remove_router_interface(context,
router_id,
interface_info)
# Update edge's firewall rules to accept subnets flows. # Update edge's firewall rules to accept subnets flows.
self.plugin._update_subnets_and_dnat_firewall(context, router_db) self.plugin._update_subnets_and_dnat_firewall(context,
router_db)
sids = self.plugin.get_subnets(context,
filters = {'network_id': [network_id], filters = {'network_id': [network_id],
'enable_dhcp': [True]}, 'enable_dhcp': [True]}
sids = self.plugin.get_subnets(context, filters=filters,
fields=['id']) fields=['id'])
is_dhcp_network = len(sids) > 0 is_dhcp_network = len(sids) > 0
do_metadata = False do_metadata = False
@ -298,7 +298,8 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
plr_id = self.edge_manager.get_plr_by_tlr_id(context, plr_id = self.edge_manager.get_plr_by_tlr_id(context,
router_id) router_id)
if router_db.enable_snat: if router_db.enable_snat:
self.plugin._update_nat_rules(context, router_db, plr_id) self.plugin._update_nat_rules(context,
router_db, plr_id)
# Open firewall flows on plr # Open firewall flows on plr
self.plugin._update_subnets_and_dnat_firewall( self.plugin._update_subnets_and_dnat_firewall(
@ -307,15 +308,24 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
nexthop = self.plugin._get_external_attachment_info( nexthop = self.plugin._get_external_attachment_info(
context, router_db)[2] context, router_db)[2]
if do_metadata: if do_metadata:
md_gw_data = self._get_metadata_gw_data(context, router_id) md_gw_data = self._get_metadata_gw_data(context,
router_id)
else: else:
md_gw_data = None md_gw_data = None
self._update_routes(context, router_id, nexthop, md_gw_data) self._update_routes(context, router_id,
nexthop, md_gw_data)
elif do_metadata and self._metadata_cfg_required_after_port_add( elif do_metadata and (
context, router_id, subnet): self._metadata_cfg_required_after_port_add(
context, router_id, subnet)):
self._metadata_route_update(context, router_id) self._metadata_route_update(context, router_id)
except Exception:
with excutils.save_and_reraise_exception():
if not interface_created:
super(nsx_v.NsxVPluginV2,
self.plugin).remove_router_interface(
context, router_id, interface_info)
return info return info
def _metadata_route_update(self, context, router_id): def _metadata_route_update(self, context, router_id):

View File

@ -192,6 +192,8 @@ class RouterExclusiveDriver(router_driver.RouterBaseDriver):
# Update static routes in all. # Update static routes in all.
self.plugin._update_routes(context, router_id, newnexthop) self.plugin._update_routes(context, router_id, newnexthop)
if new_ext_net_id:
self._notify_after_router_edge_association(context, router)
def add_router_interface(self, context, router_id, interface_info): def add_router_interface(self, context, router_id, interface_info):
self.plugin._check_intf_number_of_router(context, router_id) self.plugin._check_intf_number_of_router(context, router_id)

View File

@ -331,6 +331,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
is_conflict = self.edge_manager.is_router_conflict_on_edge( is_conflict = self.edge_manager.is_router_conflict_on_edge(
context, router_id, conflict_router_ids, [], 0) context, router_id, conflict_router_ids, [], 0)
if is_conflict: if is_conflict:
self._notify_before_router_edge_association(context, router_db)
with locking.LockManager.get_lock(str(edge_id)): with locking.LockManager.get_lock(str(edge_id)):
self._remove_router_services_on_edge(context, router_id) self._remove_router_services_on_edge(context, router_id)
self._unbind_router_on_edge(context, router_id) self._unbind_router_on_edge(context, router_id)
@ -341,6 +342,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
with locking.LockManager.get_lock(str(new_edge_id)): with locking.LockManager.get_lock(str(new_edge_id)):
self._add_router_services_on_available_edge(context, self._add_router_services_on_available_edge(context,
router_id) router_id)
self._notify_after_router_edge_association(context, router_db)
else: else:
with locking.LockManager.get_lock(str(edge_id)): with locking.LockManager.get_lock(str(edge_id)):
router_ids = self.edge_manager.get_routers_on_same_edge( router_ids = self.edge_manager.get_routers_on_same_edge(
@ -669,7 +671,6 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
# UPDATE gw info only if the router has been attached to an edge # UPDATE gw info only if the router has been attached to an edge
else: else:
is_migrated = False is_migrated = False
with locking.LockManager.get_lock(str(edge_id)):
router_ids = self.edge_manager.get_routers_on_same_edge( router_ids = self.edge_manager.get_routers_on_same_edge(
context, router_id) context, router_id)
org_ext_net_id = (router.gw_port_id and org_ext_net_id = (router.gw_port_id and
@ -684,8 +685,8 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
router.gw_port.network_id) router.gw_port.network_id)
new_enable_snat = router.enable_snat new_enable_snat = router.enable_snat
newaddr, newmask, newnexthop = ( newaddr, newmask, newnexthop = (
self.plugin._get_external_attachment_info( self.plugin._get_external_attachment_info(context, router))
context, router)) with locking.LockManager.get_lock(str(edge_id)):
if new_ext_net_id and new_ext_net_id != org_ext_net_id: if new_ext_net_id and new_ext_net_id != org_ext_net_id:
# Check whether the gw address has overlapping # Check whether the gw address has overlapping
# with networks attached to the same edge # with networks attached to the same edge
@ -745,12 +746,15 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
self._update_routes_on_routers( self._update_routes_on_routers(
context, router_id, router_ids) context, router_id, router_ids)
if is_migrated: if is_migrated:
self._notify_before_router_edge_association(context,
router, edge_id)
self._bind_router_on_available_edge( self._bind_router_on_available_edge(
context, router_id, router.admin_state_up) context, router_id, router.admin_state_up)
edge_id = edge_utils.get_router_edge_id(context, router_id) edge_id = edge_utils.get_router_edge_id(context, router_id)
with locking.LockManager.get_lock(str(edge_id)): with locking.LockManager.get_lock(str(edge_id)):
self._add_router_services_on_available_edge(context, self._add_router_services_on_available_edge(context,
router_id) router_id)
self._notify_after_router_edge_association(context, router)
def _base_add_router_interface(self, context, router_id, interface_info): def _base_add_router_interface(self, context, router_id, interface_info):
with locking.LockManager.get_lock('nsx-shared-router-pool'): with locking.LockManager.get_lock('nsx-shared-router-pool'):
@ -764,12 +768,12 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
if edge_id: if edge_id:
is_migrated = False is_migrated = False
with locking.LockManager.get_lock('nsx-shared-router-pool'): with locking.LockManager.get_lock('nsx-shared-router-pool'):
with locking.LockManager.get_lock(str(edge_id)):
router_ids = self.edge_manager.get_routers_on_same_edge(
context, router_id)
info = super(nsx_v.NsxVPluginV2, info = super(nsx_v.NsxVPluginV2,
self.plugin).add_router_interface( self.plugin).add_router_interface(
context, router_id, interface_info) context, router_id, interface_info)
with locking.LockManager.get_lock(str(edge_id)):
router_ids = self.edge_manager.get_routers_on_same_edge(
context, router_id)
subnet = self.plugin.get_subnet(context, info['subnet_id']) subnet = self.plugin.get_subnet(context, info['subnet_id'])
network_id = subnet['network_id'] network_id = subnet['network_id']
# Collect all conflict networks whose cidr are overlapped # Collect all conflict networks whose cidr are overlapped
@ -823,12 +827,15 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
context, router_id, router_ids, context, router_id, router_ids,
allow_external=True) allow_external=True)
if is_migrated: if is_migrated:
self._notify_before_router_edge_association(context,
router_db, edge_id)
self._bind_router_on_available_edge( self._bind_router_on_available_edge(
context, router_id, router_db.admin_state_up) context, router_id, router_db.admin_state_up)
edge_id = edge_utils.get_router_edge_id(context, router_id) edge_id = edge_utils.get_router_edge_id(context, router_id)
with locking.LockManager.get_lock(str(edge_id)): with locking.LockManager.get_lock(str(edge_id)):
self._add_router_services_on_available_edge(context, self._add_router_services_on_available_edge(context,
router_id) router_id)
self._notify_after_router_edge_association(context, router_db)
else: else:
info = self._base_add_router_interface(context, router_id, info = self._base_add_router_interface(context, router_id,
interface_info) interface_info)
@ -839,19 +846,23 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
with locking.LockManager.get_lock(str(edge_id)): with locking.LockManager.get_lock(str(edge_id)):
self._add_router_services_on_available_edge(context, self._add_router_services_on_available_edge(context,
router_id) router_id)
self._notify_after_router_edge_association(context, router_db)
return info return info
def remove_router_interface(self, context, router_id, interface_info): def remove_router_interface(self, context, router_id, interface_info):
detach = False
edge_id = edge_utils.get_router_edge_id(context, router_id) edge_id = edge_utils.get_router_edge_id(context, router_id)
with locking.LockManager.get_lock(str(edge_id)): with locking.LockManager.get_lock('nsx-shared-router-pool'):
info = super( info = super(
nsx_v.NsxVPluginV2, self.plugin).remove_router_interface( nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
context, router_id, interface_info) context, router_id, interface_info)
with locking.LockManager.get_lock(str(edge_id)):
subnet = self.plugin.get_subnet(context, info['subnet_id']) subnet = self.plugin.get_subnet(context, info['subnet_id'])
network_id = subnet['network_id'] network_id = subnet['network_id']
router_ids = self.edge_manager.get_routers_on_same_edge( router_ids = self.edge_manager.get_routers_on_same_edge(
context, router_id) context, router_id)
self._update_nat_rules_on_routers(context, router_id, router_ids) self._update_nat_rules_on_routers(context, router_id,
router_ids)
self._update_subnets_and_dnat_firewall_on_routers( self._update_subnets_and_dnat_firewall_on_routers(
context, router_id, router_ids, allow_external=True) context, router_id, router_ids, allow_external=True)
ports = self.plugin._get_router_interface_ports_by_network( ports = self.plugin._get_router_interface_ports_by_network(
@ -859,16 +870,24 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
if not ports: if not ports:
edge_utils.delete_interface(self.nsx_v, context, edge_utils.delete_interface(self.nsx_v, context,
router_id, network_id) router_id, network_id)
# unbind all services if no interfaces attached to the router # unbind all services if no interfaces attached to the
# router
if not self.plugin._get_internal_network_ids_by_router( if not self.plugin._get_internal_network_ids_by_router(
context, router_id): context, router_id):
self._remove_router_services_on_edge(context, router_id) detach = True
self._unbind_router_on_edge(context, router_id)
else: else:
address_groups = self.plugin._get_address_groups( address_groups = self.plugin._get_address_groups(
context, router_id, network_id) context, router_id, network_id)
edge_utils.update_internal_interface( edge_utils.update_internal_interface(self.nsx_v, context,
self.nsx_v, context, router_id, network_id, address_groups) router_id,
network_id,
address_groups)
if detach:
router = self.plugin._get_router(context, router_id)
self._notify_before_router_edge_association(context, router)
with locking.LockManager.get_lock(str(edge_id)):
self._remove_router_services_on_edge(context, router_id)
self._unbind_router_on_edge(context, router_id)
return info return info
def _update_edge_router(self, context, router_id): def _update_edge_router(self, context, router_id):