Merge "Refactor router delete processing"

This commit is contained in:
Jenkins 2016-01-17 22:10:14 +00:00 committed by Gerrit Code Review
commit 4578129a83
6 changed files with 77 additions and 40 deletions

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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()

View File

@ -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']

View File

@ -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)