Refactoring of L3 agent notifications for router

The goal of this refactoring is to reduce duplication by
replacing the L3EventObservers mechanism (a specific
mechanism for L3 agent notifications), with the
CallbacksManager mechanism (a more general mechanism
currently in use), so that there is one method
used.

This is the first part of refactoring the L3 agent so that
it uses the new neutron.callbacks mechanism. To do this,
duplicate calls will be made for notifications related to
the router, only using the new callback mechanism.

This commit does two things. First, it puts in place the
notifiers for the new callback mechanism. Second, it updates
the metatdata proxy agent (which is in the same repo) to
use the new callback mechanism.

Later commits will update other repos from the old to new
callback mechanism, and to then remove the old callback
mechanism, once no longer used.

Change-Id: If134947957fd671aa99a0b2d2b37f7ec65e37766
Partial-Bug: #1433552
This commit is contained in:
Paul Michali 2015-03-26 08:01:58 -04:00
parent 7904c9c969
commit 593b64dee4
4 changed files with 72 additions and 35 deletions

View File

@ -35,6 +35,9 @@ from neutron.agent.linux import external_process
from neutron.agent.linux import ip_lib
from neutron.agent.metadata import driver as metadata_driver
from neutron.agent import rpc as agent_rpc
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common import constants as l3_constants
from neutron.common import exceptions as n_exc
from neutron.common import ipv6_utils
@ -220,7 +223,6 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
if self.conf.enable_metadata_proxy:
self.metadata_driver = metadata_driver.MetadataDriver(self)
self.event_observers.add(self.metadata_driver)
def _check_config_params(self):
"""Check items in configuration files.
@ -309,6 +311,8 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
ri = self._create_router(router_id, router)
self.event_observers.notify(
adv_svc.AdvancedService.before_router_added, ri)
registry.notify(resources.ROUTER, events.BEFORE_CREATE,
self, router=ri)
self.router_info[router_id] = ri
@ -326,12 +330,15 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
self.event_observers.notify(
adv_svc.AdvancedService.before_router_removed, ri)
registry.notify(resources.ROUTER, events.BEFORE_DELETE,
self, router=ri)
ri.delete(self)
del self.router_info[router_id]
self.event_observers.notify(
adv_svc.AdvancedService.after_router_removed, ri)
registry.notify(resources.ROUTER, events.AFTER_DELETE, self, router=ri)
def update_fip_statuses(self, ri, existing_floating_ips, fip_statuses):
# Identify floating IPs which were disabled
@ -413,15 +420,19 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
ri.process(self)
self.event_observers.notify(
adv_svc.AdvancedService.after_router_added, ri)
registry.notify(resources.ROUTER, events.AFTER_CREATE, self, router=ri)
def _process_updated_router(self, router):
ri = self.router_info[router['id']]
ri.router = router
self.event_observers.notify(
adv_svc.AdvancedService.before_router_updated, ri)
registry.notify(resources.ROUTER, events.BEFORE_UPDATE,
self, router=ri)
ri.process(self)
self.event_observers.notify(
adv_svc.AdvancedService.after_router_updated, ri)
registry.notify(resources.ROUTER, events.AFTER_UPDATE, self, router=ri)
def _process_router_update(self):
for rp, update in self._queue.each_update_to_next_router():

View File

@ -22,6 +22,9 @@ from neutron.agent.common import config
from neutron.agent.l3 import namespaces
from neutron.agent.linux import external_process
from neutron.agent.linux import utils
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common import exceptions
from neutron.services import advanced_service
@ -66,39 +69,10 @@ class MetadataDriver(advanced_service.AdvancedService):
super(MetadataDriver, self).__init__(l3_agent)
self.metadata_port = l3_agent.conf.metadata_port
self.metadata_access_mark = l3_agent.conf.metadata_access_mark
def after_router_added(self, router):
for c, r in self.metadata_filter_rules(self.metadata_port,
self.metadata_access_mark):
router.iptables_manager.ipv4['filter'].add_rule(c, r)
for c, r in self.metadata_mangle_rules(self.metadata_access_mark):
router.iptables_manager.ipv4['mangle'].add_rule(c, r)
for c, r in self.metadata_nat_rules(self.metadata_port):
router.iptables_manager.ipv4['nat'].add_rule(c, r)
router.iptables_manager.apply()
if not router.is_ha:
self.spawn_monitored_metadata_proxy(
self.l3_agent.process_monitor,
router.ns_name,
self.metadata_port,
self.l3_agent.conf,
router_id=router.router_id)
def before_router_removed(self, router):
for c, r in self.metadata_filter_rules(self.metadata_port,
self.metadata_access_mark):
router.iptables_manager.ipv4['filter'].remove_rule(c, r)
for c, r in self.metadata_mangle_rules(self.metadata_access_mark):
router.iptables_manager.ipv4['mangle'].remove_rule(c, r)
for c, r in self.metadata_nat_rules(self.metadata_port):
router.iptables_manager.ipv4['nat'].remove_rule(c, r)
router.iptables_manager.apply()
self.destroy_monitored_metadata_proxy(self.l3_agent.process_monitor,
router.router['id'],
router.ns_name,
self.l3_agent.conf)
registry.subscribe(
after_router_added, resources.ROUTER, events.AFTER_CREATE)
registry.subscribe(
before_router_removed, resources.ROUTER, events.BEFORE_DELETE)
@classmethod
def metadata_filter_rules(cls, port, mark):
@ -192,3 +166,42 @@ class MetadataDriver(advanced_service.AdvancedService):
uuid=router_id,
namespace=ns_name,
default_cmd_callback=callback)
def after_router_added(resource, event, l3_agent, **kwargs):
router = kwargs['router']
proxy = l3_agent.metadata_driver
for c, r in proxy.metadata_filter_rules(proxy.metadata_port,
proxy.metadata_access_mark):
router.iptables_manager.ipv4['filter'].add_rule(c, r)
for c, r in proxy.metadata_mangle_rules(proxy.metadata_access_mark):
router.iptables_manager.ipv4['mangle'].add_rule(c, r)
for c, r in proxy.metadata_nat_rules(proxy.metadata_port):
router.iptables_manager.ipv4['nat'].add_rule(c, r)
router.iptables_manager.apply()
if not router.is_ha:
proxy.spawn_monitored_metadata_proxy(
l3_agent.process_monitor,
router.ns_name,
proxy.metadata_port,
l3_agent.conf,
router_id=router.router_id)
def before_router_removed(resource, event, l3_agent, **kwargs):
router = kwargs['router']
proxy = l3_agent.metadata_driver
for c, r in proxy.metadata_filter_rules(proxy.metadata_port,
proxy.metadata_access_mark):
router.iptables_manager.ipv4['filter'].remove_rule(c, r)
for c, r in proxy.metadata_mangle_rules(proxy.metadata_access_mark):
router.iptables_manager.ipv4['mangle'].remove_rule(c, r)
for c, r in proxy.metadata_nat_rules(proxy.metadata_port):
router.iptables_manager.ipv4['nat'].remove_rule(c, r)
router.iptables_manager.apply()
proxy.destroy_monitored_metadata_proxy(l3_agent.process_monitor,
router.router['id'],
router.ns_name,
l3_agent.conf)

8
neutron/tests/functional/agent/test_l3_agent.py Normal file → Executable file
View File

@ -36,6 +36,8 @@ from neutron.agent.linux import dhcp
from neutron.agent.linux import external_process
from neutron.agent.linux import ip_lib
from neutron.agent.linux import utils
from neutron.callbacks import manager
from neutron.callbacks import registry
from neutron.common import config as common_config
from neutron.common import constants as l3_constants
from neutron.common import utils as common_utils
@ -60,6 +62,12 @@ class L3AgentTestFramework(base.BaseOVSLinuxTestCase):
def setUp(self):
super(L3AgentTestFramework, self).setUp()
mock.patch('neutron.agent.l3.agent.L3PluginApi').start()
# TODO(pcm): Move this to BaseTestCase, if we find that more tests
# use this mechanism.
self._callback_manager = manager.CallbacksManager()
mock.patch.object(registry, '_get_callback_manager',
return_value=self._callback_manager).start()
self.agent = self._configure_agent('agent1')
def _get_config_opts(self):

View File

@ -37,6 +37,8 @@ from neutron.agent.linux import external_process
from neutron.agent.linux import interface
from neutron.agent.linux import ra
from neutron.agent.metadata import driver as metadata_driver
from neutron.callbacks import manager
from neutron.callbacks import registry
from neutron.common import config as base_config
from neutron.common import constants as l3_constants
from neutron.common import exceptions as n_exc
@ -45,7 +47,6 @@ from neutron.openstack.common import uuidutils
from neutron.plugins.common import constants as p_const
from neutron.tests import base
_uuid = uuidutils.generate_uuid
HOSTNAME = 'myhost'
FAKE_ID = _uuid()
@ -310,6 +311,10 @@ class BasicRouterOperationsFramework(base.BaseTestCase):
self.ri_kwargs = {'agent_conf': self.conf,
'interface_driver': self.mock_driver}
self._callback_manager = manager.CallbacksManager()
mock.patch.object(registry, '_get_callback_manager',
return_value=self._callback_manager).start()
def _process_router_instance_for_agent(self, agent, ri, router):
ri.router = router
if not ri.radvd: