l2pop: Allow network types overridable

Currently "tunnel_types" is used for two different purposes; l2pop and
check_segment_for_agent.  This commit introduces a new agent
configuration "l2pop_network_types" to allow overriding the former.

This will be used by ofagent, which wants l2pop info for TYPE_VLAN
as well.

Related: blueprint ofagent-l2pop
Related: blueprint ofagent-merge-bridges
Change-Id: Ia83a94b6661aa36afa8bfeb073101171ffde62a9
This commit is contained in:
YAMAMOTO Takashi 2014-05-07 14:57:57 +09:00
parent fea200a180
commit 538007c8f2
3 changed files with 75 additions and 11 deletions

View File

@ -48,6 +48,10 @@ class L2populationDbMixin(base_db.CommonDbMixin):
configuration = jsonutils.loads(agent.configurations) configuration = jsonutils.loads(agent.configurations)
return configuration.get('tunnel_types') return configuration.get('tunnel_types')
def get_agent_l2pop_network_types(self, agent):
configuration = jsonutils.loads(agent.configurations)
return configuration.get('l2pop_network_types')
def get_agent_by_host(self, session, agent_host): def get_agent_by_host(self, session, agent_host):
with session.begin(subtransactions=True): with session.begin(subtransactions=True):
query = session.query(agents_db.Agent) query = session.query(agents_db.Agent)

View File

@ -175,8 +175,10 @@ class L2populationMechanismDriver(api.MechanismDriver,
{'port': port['id'], 'agent': agent}) {'port': port['id'], 'agent': agent})
return return
tunnel_types = self.get_agent_tunnel_types(agent) network_types = self.get_agent_l2pop_network_types(agent)
if segment['network_type'] not in tunnel_types: if network_types is None:
network_types = self.get_agent_tunnel_types(agent)
if segment['network_type'] not in network_types:
return return
fdb_entries = self._get_port_fdb_entries(port) fdb_entries = self._get_port_fdb_entries(port)

View File

@ -28,7 +28,6 @@ from neutron.extensions import providernet as pnet
from neutron import manager from neutron import manager
from neutron.openstack.common import timeutils from neutron.openstack.common import timeutils
from neutron.plugins.ml2 import config as config from neutron.plugins.ml2 import config as config
from neutron.plugins.ml2.drivers.l2pop import constants as l2_consts
from neutron.plugins.ml2 import managers from neutron.plugins.ml2 import managers
from neutron.plugins.ml2 import rpc from neutron.plugins.ml2 import rpc
from neutron.tests.unit import test_db_plugin as test_plugin from neutron.tests.unit import test_db_plugin as test_plugin
@ -78,6 +77,19 @@ L2_AGENT_4 = {
'start_flag': True 'start_flag': True
} }
L2_AGENT_5 = {
'binary': 'neutron-ofagent-agent',
'host': HOST + '_5',
'topic': constants.L2_AGENT_TOPIC,
'configurations': {'tunneling_ip': '20.0.0.5',
'tunnel_types': [],
'bridge_mappings': {'phys1': 'br'},
'l2pop_network_types': ['vlan']},
'agent_type': constants.AGENT_TYPE_OFA,
'tunnel_type': [],
'start_flag': True
}
PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin' PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin'
NOTIFIER = 'neutron.plugins.ml2.rpc.AgentNotifierApi' NOTIFIER = 'neutron.plugins.ml2.rpc.AgentNotifierApi'
DEVICE_OWNER_COMPUTE = 'compute:None' DEVICE_OWNER_COMPUTE = 'compute:None'
@ -91,8 +103,11 @@ class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase):
# driver apis. # driver apis.
config.cfg.CONF.set_override('mechanism_drivers', config.cfg.CONF.set_override('mechanism_drivers',
['openvswitch', 'linuxbridge', ['openvswitch', 'linuxbridge',
'l2population'], 'ofagent', 'l2population'],
'ml2') 'ml2')
config.cfg.CONF.set_override('network_vlan_ranges',
['phys1:1:100'],
'ml2_type_vlan')
super(TestL2PopulationRpcTestCase, self).setUp(PLUGIN_NAME) super(TestL2PopulationRpcTestCase, self).setUp(PLUGIN_NAME)
self.adminContext = context.get_admin_context() self.adminContext = context.get_admin_context()
@ -101,9 +116,6 @@ class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase):
self.notifier = rpc.AgentNotifierApi(topics.AGENT) self.notifier = rpc.AgentNotifierApi(topics.AGENT)
self.callbacks = rpc.RpcCallbacks(self.notifier, self.type_manager) self.callbacks = rpc.RpcCallbacks(self.notifier, self.type_manager)
self.orig_supported_agents = l2_consts.SUPPORTED_AGENT_TYPES
l2_consts.SUPPORTED_AGENT_TYPES = [constants.AGENT_TYPE_OVS]
net_arg = {pnet.NETWORK_TYPE: 'vxlan', net_arg = {pnet.NETWORK_TYPE: 'vxlan',
pnet.SEGMENTATION_ID: '1'} pnet.SEGMENTATION_ID: '1'}
self._network = self._make_network(self.fmt, 'net1', True, self._network = self._make_network(self.fmt, 'net1', True,
@ -111,6 +123,15 @@ class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase):
pnet.SEGMENTATION_ID,), pnet.SEGMENTATION_ID,),
**net_arg) **net_arg)
net_arg = {pnet.NETWORK_TYPE: 'vlan',
pnet.PHYSICAL_NETWORK: 'phys1',
pnet.SEGMENTATION_ID: '2'}
self._network2 = self._make_network(self.fmt, 'net2', True,
arg_list=(pnet.NETWORK_TYPE,
pnet.PHYSICAL_NETWORK,
pnet.SEGMENTATION_ID,),
**net_arg)
notifier_patch = mock.patch(NOTIFIER) notifier_patch = mock.patch(NOTIFIER)
notifier_patch.start() notifier_patch.start()
@ -130,10 +151,6 @@ class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase):
uptime_patch = mock.patch(uptime, return_value=190) uptime_patch = mock.patch(uptime, return_value=190)
uptime_patch.start() uptime_patch.start()
def tearDown(self):
l2_consts.SUPPORTED_AGENT_TYPES = self.orig_supported_agents
super(TestL2PopulationRpcTestCase, self).tearDown()
def _register_ml2_agents(self): def _register_ml2_agents(self):
callback = agents_db.AgentExtRpcCallback() callback = agents_db.AgentExtRpcCallback()
callback.report_state(self.adminContext, callback.report_state(self.adminContext,
@ -148,6 +165,9 @@ class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase):
callback.report_state(self.adminContext, callback.report_state(self.adminContext,
agent_state={'agent_state': L2_AGENT_4}, agent_state={'agent_state': L2_AGENT_4},
time=timeutils.strtime()) time=timeutils.strtime())
callback.report_state(self.adminContext,
agent_state={'agent_state': L2_AGENT_5},
time=timeutils.strtime())
def test_fdb_add_called(self): def test_fdb_add_called(self):
self._register_ml2_agents() self._register_ml2_agents()
@ -208,6 +228,44 @@ class TestL2PopulationRpcTestCase(test_plugin.NeutronDbPluginV2TestCase):
self.assertFalse(self.mock_fanout.called) self.assertFalse(self.mock_fanout.called)
def test_fdb_add_called_for_l2pop_network_types(self):
self._register_ml2_agents()
host = HOST + '_5'
with self.subnet(network=self._network2) as subnet:
host_arg = {portbindings.HOST_ID: host}
with self.port(subnet=subnet,
device_owner=DEVICE_OWNER_COMPUTE,
arg_list=(portbindings.HOST_ID,),
**host_arg) as port1:
with self.port(subnet=subnet,
arg_list=(portbindings.HOST_ID,),
**host_arg):
p1 = port1['port']
device = 'tap' + p1['id']
self.mock_fanout.reset_mock()
self.callbacks.update_device_up(self.adminContext,
agent_id=host,
device=device)
p1_ips = [p['ip_address'] for p in p1['fixed_ips']]
expected = {'args':
{'fdb_entries':
{p1['network_id']:
{'ports':
{'20.0.0.5': [constants.FLOODING_ENTRY,
[p1['mac_address'],
p1_ips[0]]]},
'network_type': 'vlan',
'segment_id': 2}}},
'namespace': None,
'method': 'add_fdb_entries'}
self.mock_fanout.assert_called_with(
mock.ANY, expected, topic=self.fanout_topic)
def test_fdb_add_two_agents(self): def test_fdb_add_two_agents(self):
self._register_ml2_agents() self._register_ml2_agents()