add physical_networks option to filter phynet

Change-Id: I9ed4adb7743603663ec14e97cae60748a1a0aa35
This commit is contained in:
Moshe Levi 2017-05-17 13:52:37 +03:00
parent d8e9ecc922
commit c9a0157b8e
5 changed files with 104 additions and 29 deletions

View File

@ -55,4 +55,10 @@
# row back to pending state.
#
# processing_timeout = 100
# Example: maintenance_interval = 200
# Example: maintenance_interval = 200
# (ListOpt) Comma-separated list of <physical_network>
# that it will send notification. * means all physical_networks
#
# physical_networks = *
# Example: physical_networks = datacenter1, datacenter3

View File

@ -15,6 +15,7 @@
from oslo_config import cfg
from networking_mlnx._i18n import _
from networking_mlnx.plugins.ml2.drivers.sdn import constants as sdn_const
sdn_opts = [
cfg.StrOpt('url',
@ -30,7 +31,8 @@ sdn_opts = [
),
cfg.StrOpt('password',
help=_("HTTP password for authentication."),
secret=True
secret=True,
default='123456'
),
cfg.IntOpt('timeout',
help=_("HTTP timeout in seconds."),
@ -54,4 +56,9 @@ sdn_opts = [
cfg.IntOpt('processing_timeout', default='100',
help=_("Time in seconds to wait before a "
"processing row is marked back to pending.")),
cfg.ListOpt('physical_networks',
default=sdn_const.ANY,
help=_("Comma-separated list of <physical_network> "
"that it will send notification. * "
"means all physical_networks")),
]

View File

@ -38,3 +38,6 @@ PROCESSING = 'processing'
MONITORING = 'monitoring'
FAILED = 'failed'
COMPLETED = 'completed'
# Constants for physical_networks option
ANY = '*'

View File

@ -19,6 +19,7 @@ from neutron.db import api as db_api
from neutron.objects.qos import policy as policy_object
from neutron.plugins.common import constants
from neutron.plugins.ml2 import driver_api as api
from oslo_config import cfg
from oslo_log import log
from networking_mlnx._i18n import _LE
@ -26,9 +27,11 @@ from networking_mlnx.journal import cleanup
from networking_mlnx.journal import journal
from networking_mlnx.journal import maintenance
from networking_mlnx.plugins.ml2.drivers.sdn import client
from networking_mlnx.plugins.ml2.drivers.sdn import config
from networking_mlnx.plugins.ml2.drivers.sdn import constants as sdn_const
LOG = log.getLogger(__name__)
cfg.CONF.register_opts(config.sdn_opts, sdn_const.GROUP_OPT)
NETWORK_QOS_POLICY = 'network_qos_policy'
@ -40,9 +43,9 @@ def context_validator(context_type=None):
if context_type == sdn_const.PORT:
# port context contain network_context
# which include the segments
segments = getattr(context._network_context, "_segments", None)
segments = getattr(context.network, "network_segments", None)
elif context_type == sdn_const.NETWORK:
segments = getattr(context, "_segments", None)
segments = getattr(context, "network_segments", None)
else:
segments = getattr(context, "segments_to_bind", None)
if segments and getattr(instance, "check_segments", None):
@ -78,6 +81,20 @@ class SDNMechanismDriver(api.MechanismDriver):
self.client = client.SdnRestClient.create_client()
self.journal = journal.SdnJournalThread()
self._start_maintenance_thread()
self.allowed_physical_networks = cfg.CONF.sdn.physical_networks
def _is_allowed_physical_network(self, physical_network):
if (sdn_const.ANY in self.allowed_physical_networks or
physical_network in self.allowed_physical_networks):
return True
return False
def _is_allowed_physical_networks(self, network_context):
for network_segment in network_context.network_segments:
physical_network = network_segment.get('physical_network')
if not self._is_allowed_physical_network(physical_network):
return False
return True
def _start_maintenance_thread(self):
# start the maintenance thread and register all the maintenance
@ -103,7 +120,8 @@ class SDNMechanismDriver(api.MechanismDriver):
@error_handler
def create_network_precommit(self, context):
network_dic = context.current
if network_dic.get('provider:segmentation_id'):
if (self._is_allowed_physical_networks(context) and
network_dic.get('provider:segmentation_id')):
network_dic[NETWORK_QOS_POLICY] = (
self._get_network_qos_policy(context, network_dic['id']))
SDNMechanismDriver._record_in_journal(
@ -113,7 +131,8 @@ class SDNMechanismDriver(api.MechanismDriver):
@error_handler
def bind_port(self, context):
port_dic = context.current
if self._is_send_bind_port(port_dic):
if (self._is_allowed_physical_networks(context.network) and
self._is_send_bind_port(port_dic)):
port_dic[NETWORK_QOS_POLICY] = (
self._get_network_qos_policy(context, port_dic['network_id']))
SDNMechanismDriver._record_in_journal(
@ -123,12 +142,15 @@ class SDNMechanismDriver(api.MechanismDriver):
@error_handler
def update_network_precommit(self, context):
network_dic = context.current
network_dic[NETWORK_QOS_POLICY] = (
self._get_network_qos_policy(context, network_dic['id']))
SDNMechanismDriver._record_in_journal(
context, sdn_const.NETWORK, sdn_const.PUT, network_dic)
if (self._is_allowed_physical_networks(context)):
network_dic[NETWORK_QOS_POLICY] = (
self._get_network_qos_policy(context, network_dic['id']))
SDNMechanismDriver._record_in_journal(
context, sdn_const.NETWORK, sdn_const.PUT, network_dic)
def update_port_precommit(self, context):
if not self._is_allowed_physical_networks(context.network):
return
port_dic = context.current
port_dic[NETWORK_QOS_POLICY] = (
self._get_network_qos_policy(context, port_dic['network_id']))
@ -138,6 +160,8 @@ class SDNMechanismDriver(api.MechanismDriver):
@context_validator(sdn_const.NETWORK)
@error_handler
def delete_network_precommit(self, context):
if not self._is_allowed_physical_networks(context):
return
network_dic = context.current
network_dic[NETWORK_QOS_POLICY] = (
self._get_network_qos_policy(context, network_dic['id']))
@ -147,6 +171,8 @@ class SDNMechanismDriver(api.MechanismDriver):
@context_validator(sdn_const.PORT)
@error_handler
def delete_port_precommit(self, context):
if not self._is_allowed_physical_networks(context.network):
return
port_dic = context.current
port_dic[NETWORK_QOS_POLICY] = (
self._get_network_qos_policy(context, port_dic['network_id']))

View File

@ -18,11 +18,11 @@ import requests
from neutron.db import api as neutron_db_api
from neutron.plugins.common import constants
from neutron.plugins.ml2 import config
from neutron.plugins.ml2 import plugin
from neutron.tests.unit.plugins.ml2 import test_plugin
from neutron.tests.unit import testlib_api
from oslo_config import cfg
from oslo_config import fixture as fixture_config
from oslo_serialization import jsonutils
from oslo_utils import uuidutils
@ -30,6 +30,7 @@ from networking_mlnx.db import db
from networking_mlnx.journal import cleanup
from networking_mlnx.journal import journal
from networking_mlnx.plugins.ml2.drivers.sdn import client
from networking_mlnx.plugins.ml2.drivers.sdn import config
from networking_mlnx.plugins.ml2.drivers.sdn import constants as sdn_const
from networking_mlnx.plugins.ml2.drivers.sdn import sdn_mech_driver
from networking_mlnx.plugins.ml2.drivers.sdn import utils as sdn_utils
@ -44,13 +45,15 @@ class SdnConfigBase(test_plugin.Ml2PluginV2TestCase):
def setUp(self):
super(SdnConfigBase, self).setUp()
config.cfg.CONF.set_override('mechanism_drivers',
['logger', MECHANISM_DRIVER_NAME],
'ml2')
config.cfg.CONF.set_override('url', 'http://127.0.0.1/neo',
sdn_const.GROUP_OPT)
config.cfg.CONF.set_override('username', 'admin', sdn_const.GROUP_OPT)
config.cfg.CONF.set_override('password', 'admin', sdn_const.GROUP_OPT)
self.conf_fixture = self.useFixture(fixture_config.Config())
self.conf = self.conf_fixture.conf
self.conf.register_opts(config.sdn_opts, sdn_const.GROUP_OPT)
self.conf.set_override('mechanism_drivers',
['logger', MECHANISM_DRIVER_NAME],
'ml2')
self.conf.set_override('url', 'http://127.0.0.1/neo',
sdn_const.GROUP_OPT)
self.conf.set_override('username', 'admin', sdn_const.GROUP_OPT)
class SdnTestCase(SdnConfigBase):
@ -73,12 +76,15 @@ class SdnMechanismConfigTests(testlib_api.SqlTestCase):
def _set_config(self, url='http://127.0.0.1/neo',
username='admin',
password='admin'):
config.cfg.CONF.set_override('mechanism_drivers',
['logger', MECHANISM_DRIVER_NAME],
'ml2')
config.cfg.CONF.set_override('url', url, sdn_const.GROUP_OPT)
config.cfg.CONF.set_override('username', username, sdn_const.GROUP_OPT)
config.cfg.CONF.set_override('password', password, sdn_const.GROUP_OPT)
self.conf_fixture = self.useFixture(fixture_config.Config())
self.conf = self.conf_fixture.conf
self.conf.register_opts(config.sdn_opts, sdn_const.GROUP_OPT)
self.conf.set_override('mechanism_drivers',
['logger', MECHANISM_DRIVER_NAME],
'ml2')
self.conf.set_override('url', url, sdn_const.GROUP_OPT)
self.conf.set_override('username', username, sdn_const.GROUP_OPT)
self.conf.set_override('password', password, sdn_const.GROUP_OPT)
def _test_missing_config(self, **kwargs):
self._set_config(**kwargs)
@ -154,7 +160,8 @@ class SdnDriverTestCase(SdnConfigBase):
'provider:network_type': 'vlan',
'network_qos_policy': None}
context = mock.Mock(current=current, _network=current,
_segments=self._get_segments_list())
_segments=self._get_segments_list(),
network_segments=self._get_segments_list())
context._plugin_context.session = neutron_db_api.get_session()
return context
@ -173,10 +180,10 @@ class SdnDriverTestCase(SdnConfigBase):
# The port context should have NetwrokContext object that contain
# the segments list
network_context = type('NetworkContext', (object,),
{"_segments": self._get_segments_list()})
{"network_segments": self._get_segments_list()})
context = mock.Mock(current=current, _port=current,
_network_context=network_context)
network=network_context)
context._plugin_context.session = neutron_db_api.get_session()
return context
@ -192,8 +199,13 @@ class SdnDriverTestCase(SdnConfigBase):
'device_owner': DEVICE_OWNER_COMPUTE,
'network_id': 'c13bba05-eb07-45ba-ace2-765706b2d701',
'network_qos_policy': None}
# The port context should have NetwrokContext object that contain
# the segments list
network_context = type('NetworkContext', (object,),
{"network_segments": self._get_segments_list()})
context = mock.Mock(current=current, _port=current,
segments_to_bind=self._get_segments_list())
segments_to_bind=self._get_segments_list(),
network=network_context)
context._plugin_context.session = neutron_db_api.get_session()
return context
@ -474,7 +486,7 @@ class SdnDriverTestCase(SdnConfigBase):
self._test_parent_delete_pending_child_delete(
sdn_const.NETWORK, sdn_const.PORT)
def test_port1(self):
def test_port(self):
self._test_object_type(sdn_const.PORT)
def test_port_update_pending_port_create(self):
@ -541,3 +553,24 @@ class SdnDriverTestCase(SdnConfigBase):
# first row should be set back to 'pending' because it was not valid
rows = db.get_all_db_rows_by_state(self.db_session, sdn_const.PENDING)
self.assertEqual(3, len(rows))
def test_network_filter_phynset(self):
self.conf.set_override(
'physical_networks', 'datacenter', sdn_const.GROUP_OPT)
self.mech = sdn_mech_driver.SDNMechanismDriver()
self.mech.initialize()
self._test_filtered_object_type(sdn_const.NETWORK)
def test_port_filter_phynset(self):
self.conf.set_override(
'physical_networks', 'datacenter', sdn_const.GROUP_OPT)
self.mech = sdn_mech_driver.SDNMechanismDriver()
self.mech.initialize()
self._test_filtered_object_type(sdn_const.PORT)
def _test_filtered_object_type(self, object_type):
# Add and process create request.
for operation in (sdn_const.POST, sdn_const.PUT, sdn_const.DELETE):
self._call_operation_object(operation, object_type)
rows = db.get_all_db_rows(self.db_session)
self.assertEqual(0, len(rows))