Merge "Refactor router delete processing"
This commit is contained in:
commit
4578129a83
@ -88,8 +88,8 @@ class DvrEdgeHaRouter(DvrEdgeRouter, HaRouter):
|
|||||||
self._create_snat_namespace()
|
self._create_snat_namespace()
|
||||||
super(DvrEdgeHaRouter, self).initialize(process_monitor)
|
super(DvrEdgeHaRouter, self).initialize(process_monitor)
|
||||||
|
|
||||||
def process(self, agent, delete=False):
|
def process(self, agent):
|
||||||
super(DvrEdgeHaRouter, self).process(agent, delete)
|
super(DvrEdgeHaRouter, self).process(agent)
|
||||||
if self.ha_port:
|
if self.ha_port:
|
||||||
self.enable_keepalived()
|
self.enable_keepalived()
|
||||||
|
|
||||||
|
@ -414,11 +414,11 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||||||
def _handle_router_snat_rules(self, ex_gw_port, interface_name):
|
def _handle_router_snat_rules(self, ex_gw_port, interface_name):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def process_external(self, agent, delete=False):
|
def process_external(self, agent):
|
||||||
ex_gw_port = self.get_ex_gw_port()
|
ex_gw_port = self.get_ex_gw_port()
|
||||||
if ex_gw_port:
|
if ex_gw_port:
|
||||||
self.create_dvr_fip_interfaces(ex_gw_port)
|
self.create_dvr_fip_interfaces(ex_gw_port)
|
||||||
super(DvrLocalRouter, self).process_external(agent, delete)
|
super(DvrLocalRouter, self).process_external(agent)
|
||||||
|
|
||||||
def create_dvr_fip_interfaces(self, ex_gw_port):
|
def create_dvr_fip_interfaces(self, ex_gw_port):
|
||||||
floating_ips = self.get_floating_ips()
|
floating_ips = self.get_floating_ips()
|
||||||
@ -455,10 +455,10 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||||||
# configured
|
# configured
|
||||||
self.agent.process_router_add(self)
|
self.agent.process_router_add(self)
|
||||||
|
|
||||||
def process(self, agent, delete=False):
|
def process(self, agent):
|
||||||
ex_gw_port = self.get_ex_gw_port()
|
ex_gw_port = self.get_ex_gw_port()
|
||||||
if ex_gw_port:
|
if ex_gw_port:
|
||||||
self.fip_ns = agent.get_fip_ns(ex_gw_port['network_id'])
|
self.fip_ns = agent.get_fip_ns(ex_gw_port['network_id'])
|
||||||
self.fip_ns.scan_fip_ports(self)
|
self.fip_ns.scan_fip_ports(self)
|
||||||
|
|
||||||
super(DvrLocalRouter, self).process(agent, delete)
|
super(DvrLocalRouter, self).process(agent)
|
||||||
|
@ -26,8 +26,8 @@ class DvrRouterBase(router.RouterInfo):
|
|||||||
self.agent = agent
|
self.agent = agent
|
||||||
self.host = host
|
self.host = host
|
||||||
|
|
||||||
def process(self, agent, delete=False):
|
def process(self, agent):
|
||||||
super(DvrRouterBase, self).process(agent, delete)
|
super(DvrRouterBase, self).process(agent)
|
||||||
# NOTE: Keep a copy of the interfaces around for when they are removed
|
# NOTE: Keep a copy of the interfaces around for when they are removed
|
||||||
self.snat_ports = self.get_snat_interfaces()
|
self.snat_ports = self.get_snat_interfaces()
|
||||||
|
|
||||||
|
@ -380,8 +380,8 @@ class HaRouter(router.RouterInfo):
|
|||||||
self.ha_network_removed()
|
self.ha_network_removed()
|
||||||
self.disable_keepalived()
|
self.disable_keepalived()
|
||||||
|
|
||||||
def process(self, agent, delete=False):
|
def process(self, agent):
|
||||||
super(HaRouter, self).process(agent, delete)
|
super(HaRouter, self).process(agent)
|
||||||
|
|
||||||
if self.ha_port:
|
if self.ha_port:
|
||||||
self.enable_keepalived()
|
self.enable_keepalived()
|
||||||
|
@ -255,7 +255,7 @@ class RouterInfo(object):
|
|||||||
self.router['gw_port'] = None
|
self.router['gw_port'] = None
|
||||||
self.router[l3_constants.INTERFACE_KEY] = []
|
self.router[l3_constants.INTERFACE_KEY] = []
|
||||||
self.router[l3_constants.FLOATINGIP_KEY] = []
|
self.router[l3_constants.FLOATINGIP_KEY] = []
|
||||||
self.process(agent, delete=True)
|
self.process_delete(agent)
|
||||||
self.disable_radvd()
|
self.disable_radvd()
|
||||||
self.router_namespace.delete()
|
self.router_namespace.delete()
|
||||||
|
|
||||||
@ -646,35 +646,50 @@ class RouterInfo(object):
|
|||||||
self.iptables_manager,
|
self.iptables_manager,
|
||||||
interface_name)
|
interface_name)
|
||||||
|
|
||||||
def process_external(self, agent, delete=False):
|
def _process_external_on_delete(self, agent):
|
||||||
fip_statuses = {}
|
fip_statuses = {}
|
||||||
if not delete:
|
try:
|
||||||
try:
|
|
||||||
with self.iptables_manager.defer_apply():
|
|
||||||
ex_gw_port = self.get_ex_gw_port()
|
|
||||||
self._process_external_gateway(ex_gw_port, agent.pd)
|
|
||||||
if not ex_gw_port:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Process SNAT/DNAT rules and addresses for floating IPs
|
|
||||||
self.process_snat_dnat_for_fip()
|
|
||||||
|
|
||||||
# Once NAT rules for floating IPs are safely in place
|
|
||||||
# configure their addresses on the external gateway port
|
|
||||||
interface_name = self.get_external_device_interface_name(
|
|
||||||
ex_gw_port)
|
|
||||||
fip_statuses = self.configure_fip_addresses(interface_name)
|
|
||||||
|
|
||||||
except (n_exc.FloatingIpSetupException,
|
|
||||||
n_exc.IpTablesApplyException):
|
|
||||||
# All floating IPs must be put in error state
|
|
||||||
LOG.exception(_LE("Failed to process floating IPs."))
|
|
||||||
fip_statuses = self.put_fips_in_error_state()
|
|
||||||
finally:
|
|
||||||
self.update_fip_statuses(agent, fip_statuses)
|
|
||||||
else:
|
|
||||||
ex_gw_port = self.get_ex_gw_port()
|
ex_gw_port = self.get_ex_gw_port()
|
||||||
self._process_external_gateway(ex_gw_port, agent.pd)
|
self._process_external_gateway(ex_gw_port, agent.pd)
|
||||||
|
if not ex_gw_port:
|
||||||
|
return
|
||||||
|
|
||||||
|
interface_name = self.get_external_device_interface_name(
|
||||||
|
ex_gw_port)
|
||||||
|
fip_statuses = self.configure_fip_addresses(interface_name)
|
||||||
|
|
||||||
|
except (n_exc.FloatingIpSetupException):
|
||||||
|
# All floating IPs must be put in error state
|
||||||
|
LOG.exception(_LE("Failed to process floating IPs."))
|
||||||
|
fip_statuses = self.put_fips_in_error_state()
|
||||||
|
finally:
|
||||||
|
self.update_fip_statuses(agent, fip_statuses)
|
||||||
|
|
||||||
|
def process_external(self, agent):
|
||||||
|
fip_statuses = {}
|
||||||
|
try:
|
||||||
|
with self.iptables_manager.defer_apply():
|
||||||
|
ex_gw_port = self.get_ex_gw_port()
|
||||||
|
self._process_external_gateway(ex_gw_port, agent.pd)
|
||||||
|
if not ex_gw_port:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Process SNAT/DNAT rules and addresses for floating IPs
|
||||||
|
self.process_snat_dnat_for_fip()
|
||||||
|
|
||||||
|
# Once NAT rules for floating IPs are safely in place
|
||||||
|
# configure their addresses on the external gateway port
|
||||||
|
interface_name = self.get_external_device_interface_name(
|
||||||
|
ex_gw_port)
|
||||||
|
fip_statuses = self.configure_fip_addresses(interface_name)
|
||||||
|
|
||||||
|
except (n_exc.FloatingIpSetupException,
|
||||||
|
n_exc.IpTablesApplyException):
|
||||||
|
# All floating IPs must be put in error state
|
||||||
|
LOG.exception(_LE("Failed to process floating IPs."))
|
||||||
|
fip_statuses = self.put_fips_in_error_state()
|
||||||
|
finally:
|
||||||
|
self.update_fip_statuses(agent, fip_statuses)
|
||||||
|
|
||||||
def update_fip_statuses(self, agent, fip_statuses):
|
def update_fip_statuses(self, agent, fip_statuses):
|
||||||
# Identify floating IPs which were disabled
|
# Identify floating IPs which were disabled
|
||||||
@ -693,19 +708,34 @@ class RouterInfo(object):
|
|||||||
agent.context, self.router_id, fip_statuses)
|
agent.context, self.router_id, fip_statuses)
|
||||||
|
|
||||||
@common_utils.exception_logger()
|
@common_utils.exception_logger()
|
||||||
def process(self, agent, delete=False):
|
def process_delete(self, agent):
|
||||||
|
"""Process the delete of this router
|
||||||
|
|
||||||
|
This method is the point where the agent requests that this router
|
||||||
|
be deleted. This is a separate code path from process in that it
|
||||||
|
avoids any changes to the qrouter namespace that will be removed
|
||||||
|
at the end of the operation.
|
||||||
|
|
||||||
|
:param agent: Passes the agent in order to send RPC messages.
|
||||||
|
"""
|
||||||
|
LOG.debug("process router delete")
|
||||||
|
self._process_internal_ports(agent.pd)
|
||||||
|
agent.pd.sync_router(self.router['id'])
|
||||||
|
self._process_external_on_delete(agent)
|
||||||
|
|
||||||
|
@common_utils.exception_logger()
|
||||||
|
def process(self, agent):
|
||||||
"""Process updates to this router
|
"""Process updates to this router
|
||||||
|
|
||||||
This method is the point where the agent requests that updates be
|
This method is the point where the agent requests that updates be
|
||||||
applied to this router.
|
applied to this router.
|
||||||
|
|
||||||
:param agent: Passes the agent in order to send RPC messages.
|
:param agent: Passes the agent in order to send RPC messages.
|
||||||
:param delete: Indicates whether this update is from a delete operation
|
|
||||||
"""
|
"""
|
||||||
LOG.debug("process router updates")
|
LOG.debug("process router updates")
|
||||||
self._process_internal_ports(agent.pd)
|
self._process_internal_ports(agent.pd)
|
||||||
agent.pd.sync_router(self.router['id'])
|
agent.pd.sync_router(self.router['id'])
|
||||||
self.process_external(agent, delete)
|
self.process_external(agent)
|
||||||
# Process static routes for router
|
# Process static routes for router
|
||||||
self.routes_updated(self.routes, self.router['routes'])
|
self.routes_updated(self.routes, self.router['routes'])
|
||||||
self.routes = self.router['routes']
|
self.routes = self.router['routes']
|
||||||
|
@ -172,6 +172,13 @@ class TestDvrRouter(framework.L3AgentTestFramework):
|
|||||||
self._assert_onlink_subnet_routes(
|
self._assert_onlink_subnet_routes(
|
||||||
router, ip_versions, snat_ns_name)
|
router, ip_versions, snat_ns_name)
|
||||||
self._assert_extra_routes(router, namespace=snat_ns_name)
|
self._assert_extra_routes(router, namespace=snat_ns_name)
|
||||||
|
|
||||||
|
# During normal operation, a router-gateway-clear followed by
|
||||||
|
# a router delete results in two notifications to the agent. This
|
||||||
|
# code flow simulates the exceptional case where the notification of
|
||||||
|
# the clearing of the gateway hast been missed, so we are checking
|
||||||
|
# that the L3 agent is robust enough to handle that case and delete
|
||||||
|
# the router correctly.
|
||||||
self._delete_router(self.agent, router.router_id)
|
self._delete_router(self.agent, router.router_id)
|
||||||
self._assert_fip_namespace_deleted(ext_gateway_port)
|
self._assert_fip_namespace_deleted(ext_gateway_port)
|
||||||
self._assert_router_does_not_exist(router)
|
self._assert_router_does_not_exist(router)
|
||||||
|
Loading…
Reference in New Issue
Block a user