NSX|V: Fix error handling for distributed router interface

1. No need to rollback the interface creation in teh distributed router
driver. It is rolled back on the plugin level. the Double rollback causes
a new error to be raised.
2. In the plugin level - do not alert on the rollback faliure.
It may be legit
2. In the plugin level raise a proper error to neutron, instead of the
internal one.

Change-Id: I129f595d6cd17cd0af62fc9e2855451b97e73ff0
This commit is contained in:
asarfaty 2019-11-13 11:21:49 +02:00 committed by Adit Sarfaty
parent 47d2fc26fb
commit ce76dbab02
2 changed files with 34 additions and 39 deletions

View File

@ -14,7 +14,6 @@
import netaddr
from oslo_log import log as logging
from oslo_utils import excutils
from neutron.db import l3_db
@ -265,41 +264,32 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
address_groups = self.plugin._get_address_groups(
context, router_id, network_id)
edge_id = self._get_edge_id(context, router_id)
interface_created = False
try:
with locking.LockManager.get_lock(str(edge_id)):
edge_utils.add_vdr_internal_interface(self.nsx_v, context,
router_id, network_id,
address_groups,
router_db.admin_state_up)
interface_created = True
# Update edge's firewall rules to accept subnets flows.
self.plugin._update_subnets_and_dnat_firewall(context,
router_db)
with locking.LockManager.get_lock(str(edge_id)):
edge_utils.add_vdr_internal_interface(self.nsx_v, context,
router_id, network_id,
address_groups,
router_db.admin_state_up)
# Update edge's firewall rules to accept subnets flows.
self.plugin._update_subnets_and_dnat_firewall(context,
router_db)
if router_db.gw_port:
plr_id = self.edge_manager.get_plr_by_tlr_id(context,
router_id)
if router_db.enable_snat:
self.plugin._update_nat_rules(context,
router_db, plr_id)
if router_db.gw_port:
plr_id = self.edge_manager.get_plr_by_tlr_id(context,
router_id)
if router_db.enable_snat:
self.plugin._update_nat_rules(context,
router_db, plr_id)
# Open firewall flows on plr
self.plugin._update_subnets_and_dnat_firewall(
context, router_db, router_id=plr_id)
# Update static routes of plr
nexthop = self.plugin._get_external_attachment_info(
context, router_db)[2]
# Open firewall flows on plr
self.plugin._update_subnets_and_dnat_firewall(
context, router_db, router_id=plr_id)
# Update static routes of plr
nexthop = self.plugin._get_external_attachment_info(
context, router_db)[2]
self._update_routes(context, router_id,
nexthop)
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)
self._update_routes(context, router_id,
nexthop)
# In case of failure, rollbak will be done in teh plugin level
return info
def remove_router_interface(self, context, router_id, interface_info):

View File

@ -4098,14 +4098,19 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
try:
return router_driver.add_router_interface(
context, router_id, interface_info)
except vsh_exc.VcnsApiException:
with excutils.save_and_reraise_exception():
LOG.error("Failed to add interface_info %(info)s on "
"router %(router_id)s",
{'info': str(interface_info),
'router_id': router_id})
except vsh_exc.VcnsApiException as e:
LOG.error("Failed to add interface_info %(info)s on "
"router %(router_id)s: %(e)s",
{'info': str(interface_info),
'router_id': router_id,
'e': e.message})
try:
router_driver.remove_router_interface(
context, router_id, interface_info)
except Exception:
# Rollback may fail if creation failed too early
pass
raise nsx_exc.NsxPluginException(err_msg=e.message)
def remove_router_interface(self, context, router_id, interface_info):
# Get the router interface port id