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:
parent
47d2fc26fb
commit
ce76dbab02
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue