Merge "Add QoS North Bound Functionality"

This commit is contained in:
Jenkins 2016-11-04 02:16:17 +00:00 committed by Gerrit Code Review
commit f3e56f2132
15 changed files with 486 additions and 13 deletions

View File

@ -17,7 +17,7 @@
# http://git.openstack.org/cgit/openstack-infra/project-config/tree/jenkins/jobs/dragonflow.yaml
#
export OVERRIDE_ENABLED_SERVICES=key,n-api,n-cpu,n-cond,n-sch,n-crt,n-cauth,n-obj,g-api,g-reg,c-sch,c-api,c-vol,horizon,rabbit,mysql,dstat,df-controller,df-redis,df-redis-server,q-svc,df-l3-agent,df-metadata
export OVERRIDE_ENABLED_SERVICES=key,n-api,n-cpu,n-cond,n-sch,n-crt,n-cauth,n-obj,g-api,g-reg,c-sch,c-api,c-vol,horizon,rabbit,mysql,dstat,df-controller,df-redis,df-redis-server,q-svc,df-l3-agent,df-metadata,q-qos
export DEVSTACK_LOCAL_CONFIG+=$'\n'"DF_REDIS_PUBSUB=True"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"DF_RUNNING_IN_GATE=True"
export DEVSTACK_LOCAL_CONFIG+=$'\n'"NEUTRON_CREATE_INITIAL_NETWORKS=False"

View File

@ -145,6 +145,32 @@ function configure_df_metadata_service {
fi
}
function configure_qos {
Q_SERVICE_PLUGIN_CLASSES+=",qos"
Q_ML2_PLUGIN_EXT_DRIVERS+=",qos"
iniset /$Q_PLUGIN_CONF_FILE ml2 extension_drivers "$Q_ML2_PLUGIN_EXT_DRIVERS"
# NOTE: QoS plugin use "message_queue" as default driver if no
# notification driver in neutron.conf, or it will use driver
# assigned in neutron.conf.
# If "df" is the only mech driver for ml2, we use
# "df_notification_driver" as notification driver.
# If ml2 has other mech driver except "df", we should add
# "message_queue,df_notification_driver" to existing
# notification driver
if [[ "$Q_ML2_PLUGIN_MECHANISM_DRIVERS" == "df" ]]; then
NOTIFICATION_DRIVER="df_notification_driver"
else
NOTIFICATION_DRIVER=$(iniget ${NEUTRON_CONF} qos notification_drivers)
if [[ "$NOTIFICATION_DRIVER" == "" ]]; then
NOTIFICATION_DRIVER="message_queue,df_notification_driver"
else
NOTIFICATION_DRIVER+=",df_notification_driver"
fi
fi
iniset $NEUTRON_CONF qos notification_drivers "$NOTIFICATION_DRIVER"
}
function configure_df_plugin {
echo "Configuring Neutron for Dragonflow"
@ -160,6 +186,9 @@ function configure_df_plugin {
Q_SERVICE_PLUGIN_CLASSES=""
else
DF_APPS_LIST=$ML2_APPS_LIST
if is_service_enabled q-qos ; then
configure_qos
fi
fi
# Generate configuration file

View File

@ -24,7 +24,7 @@ from dragonflow.common import utils as df_utils
cfg.CONF.register_opts(common_params.DF_OPTS, 'df')
db_tables = ['lport', 'lswitch', 'lrouter', 'chassis', 'secgroup',
'tunnel_key', 'floatingip', 'publisher']
'tunnel_key', 'floatingip', 'publisher', 'qospolicy']
usage_str = "The following commands are supported:\n" \
"1) df-db ls - print all the db tables \n" \

View File

@ -743,6 +743,40 @@ class NbApi(object):
topic,
)
def create_qos_policy(self, policy_id, topic, **columns):
policy = {'id': policy_id,
'topic': topic}
policy.update(columns)
policy_json = jsonutils.dumps(policy)
self.driver.create_key('qospolicy', policy_id, policy_json, topic)
self._send_db_change_event('qospolicy', policy_id, 'create',
policy_json, topic)
def update_qos_policy(self, policy_id, topic, **columns):
qospolicy_json = self.driver.get_key('qospolicy', policy_id, topic)
policy = jsonutils.loads(qospolicy_json)
policy.update(columns)
policy_json = jsonutils.dumps(policy)
self.driver.set_key('qospolicy', policy_id, policy_json, topic)
self._send_db_change_event('qospolicy', policy_id, 'set',
policy_json, topic)
def delete_qos_policy(self, policy_id, topic):
self.driver.delete_key('qospolicy', policy_id, topic)
self._send_db_change_event('qospolicy', policy_id, 'delete', policy_id,
topic)
def get_qos_policy(self, policy_id, topic=None):
try:
qospolicy_value = self.driver.get_key('qospolicy',
policy_id, topic)
return QosPolicy(qospolicy_value)
except Exception:
LOG.exception(_LE('Could not get qos policy %s'), policy_id)
return None
@six.add_metaclass(abc.ABCMeta)
class DbStoreObject(object):
@ -927,6 +961,9 @@ class LogicalPort(DbStoreObject):
def get_binding_vnic_type(self):
return self.lport.get('binding_vnic_type')
def get_qos_policy_id(self):
return self.lport.get('qos_policy_id')
def get_version(self):
return self.lport['version']
@ -1212,3 +1249,57 @@ class Publisher(DbStoreObject):
def __str__(self):
return str(self.publisher)
class QosPolicy(DbStoreObject):
def __init__(self, value):
self.qospolicy = jsonutils.loads(value)
def get_id(self):
return self.qospolicy.get('id')
def get_name(self):
return self.qospolicy.get('name')
def get_topic(self):
return self.qospolicy.get('topic')
def get_type(self):
return self.qospolicy.get('type')
def get_version(self):
return self.qospolicy.get('version')
def get_max_burst_kbps(self):
rules = self.qospolicy.get('rules')
max_burst_kbps = None
for rule in rules:
if rule['type'] == 'bandwidth_limit':
max_burst_kbps = rule.get('max_burst_kbps')
break
return max_burst_kbps
def get_max_kbps(self):
rules = self.qospolicy.get('rules')
max_kbps = None
for rule in rules:
if rule['type'] == 'bandwidth_limit':
max_kbps = rule.get('max_kbps')
break
return max_kbps
def get_dscp_marking(self):
rules = self.qospolicy.get('rules')
dscp_marking = None
for rule in rules:
if rule['type'] == 'dscp_marking':
dscp_marking = rule.get('dscp_mark')
break
return dscp_marking
def __str__(self):
return str(self.qospolicy)

View File

@ -47,6 +47,8 @@ RESOURCE_ML2_CORE = 2 # network, subnet, port
RESOURCE_ML2_SECURITY_GROUP = 3
RESOURCE_ML2_SECURITY_GROUP_RULE_CREATE = 4
RESOURCE_ML2_SECURITY_GROUP_RULE_DELETE = 5
RESOURCE_QOS_POLICY_CREATE_OR_UPDATE = 6
RESOURCE_QOS_POLICY_DELETE = 7
LOG = log.getLogger(__name__)
@ -107,6 +109,11 @@ def _get_lock_id_by_resource_type(type, *args, **kwargs):
lock_id = args[1]['security_group_rule']['tenant_id']
elif RESOURCE_ML2_SECURITY_GROUP_RULE_DELETE == type:
lock_id = args[1]['context'].tenant_id
elif RESOURCE_QOS_POLICY_CREATE_OR_UPDATE == type:
lock_id = args[0][2]['tenant_id']
elif RESOURCE_QOS_POLICY_DELETE == type:
# when delete qos policy, there's no tenant_id in args.
lock_id = GLOBAL_LOCK_ID
if not lock_id:
lock_id = GLOBAL_LOCK_ID

View File

@ -246,7 +246,8 @@ class DFMechDriver(driver_api.MechanismDriver):
router_external=network['router:external'],
mtu=network.get('mtu'),
version=network['revision_number'],
subnets=[])
subnets=[],
qos_policy_id=network.get('qos_policy_id'))
LOG.info(_LI("DFMechDriver: create network %s"), network['id'])
return network
@ -263,9 +264,28 @@ class DFMechDriver(driver_api.MechanismDriver):
except df_exceptions.DBKeyNotFound:
LOG.debug("lswitch %s is not found in DF DB, might have "
"been deleted concurrently" % network_id)
return
LOG.info(_LI("DFMechDriver: delete network %s"), network_id)
@lock_db.wrap_db_lock(lock_db.RESOURCE_ML2_CORE)
def update_network_postcommit(self, context):
network = context.current
self.nb_api.update_lswitch(
id=network['id'],
topic=network['tenant_id'],
name=network.get('name', df_const.DF_NETWORK_DEFAULT_NAME),
network_type=network.get('provider:network_type'),
segmentation_id=network.get('provider:segmentation_id'),
router_external=network.get('router:external'),
mtu=network.get('mtu'),
version=network['revision_number'],
qos_policy_id=network.get('qos_policy_id'))
LOG.info(_LI("DFMechDriver: update network %s"), network['id'])
return network
def _get_dhcp_port_for_subnet(self, context, subnet_id):
filters = {'fixed_ips': {'subnet_id': [subnet_id]},
'device_owner': [n_const.DEVICE_OWNER_DHCP]}
@ -370,8 +390,9 @@ class DFMechDriver(driver_api.MechanismDriver):
dhcp_ip, dhcp_port = self._handle_create_subnet_dhcp(
plugin_context,
subnet)
except Exception as e:
LOG.exception(e)
except Exception:
LOG.exception(
_LE("Failed to create dhcp port for subnet %s"), subnet['id'])
return None
self.nb_api.add_subnet(
@ -447,8 +468,10 @@ class DFMechDriver(driver_api.MechanismDriver):
plugin_context,
old_subnet,
new_subnet)
except Exception as e:
LOG.exception(e)
except Exception:
LOG.exception(
_LE("Failed to create dhcp port for subnet %s"),
new_subnet['id'])
return None
self.nb_api.update_subnet(
@ -489,6 +512,7 @@ class DFMechDriver(driver_api.MechanismDriver):
except df_exceptions.DBKeyNotFound:
LOG.debug("network %s is not found in DB, might have "
"been deleted concurrently" % net_id)
return
LOG.info(_LI("DFMechDriver: delete subnet %s"), subnet_id)
@ -532,7 +556,8 @@ class DFMechDriver(driver_api.MechanismDriver):
remote_vtep=remote_vtep,
allowed_address_pairs=port.get(addr_pair.ADDRESS_PAIRS, []),
binding_profile=port.get(portbindings.PROFILE, None),
binding_vnic_type=port.get(portbindings.VNIC_TYPE, None))
binding_vnic_type=port.get(portbindings.VNIC_TYPE, None),
qos_policy_id=port.get('qos_policy_id', None))
LOG.info(_LI("DFMechDriver: create port %s"), port['id'])
return port
@ -629,8 +654,8 @@ class DFMechDriver(driver_api.MechanismDriver):
[]),
binding_profile=updated_port.get(portbindings.PROFILE, None),
binding_vnic_type=updated_port.get(portbindings.VNIC_TYPE, None),
version=updated_port['revision_number'],
remote_vtep=remote_vtep)
version=updated_port['revision_number'], remote_vtep=remote_vtep,
qos_policy_id=updated_port.get('qos_policy_id'))
LOG.info(_LI("DFMechDriver: update port %s"), updated_port['id'])
return updated_port
@ -646,6 +671,7 @@ class DFMechDriver(driver_api.MechanismDriver):
except df_exceptions.DBKeyNotFound:
LOG.debug("port %s is not found in DF DB, might have "
"been deleted concurrently" % port_id)
return
LOG.info(_LI("DFMechDriver: delete port %s"), port_id)

View File

@ -0,0 +1,75 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from neutron import manager
from neutron.plugins.common import constants as service_constants
from neutron.plugins.ml2 import plugin as ml2_plugin
from neutron.services.qos.notification_drivers import qos_base
from dragonflow.db.neutron import lockedobjects_db as lock_db
class DFQosServiceNotificationDriver(
qos_base.QosServiceNotificationDriverBase):
"""Dragonflow notification driver for QoS."""
def __init__(self):
self._nb_api = None
def get_description(self):
return "Notification driver for Dragonflow"
@property
def _plugin(self):
return manager.NeutronManager.get_service_plugins().get(
service_constants.QOS)
@property
def nb_api(self):
if self._nb_api is None:
plugin = manager.NeutronManager.get_plugin()
if isinstance(plugin, ml2_plugin.Ml2Plugin):
mech_driver = plugin.mechanism_manager.mech_drivers['df'].obj
self._nb_api = mech_driver.nb_api
else:
# DF neutron plugin
self._nb_api = plugin.nb_api
return self._nb_api
@lock_db.wrap_db_lock(lock_db.RESOURCE_QOS_POLICY_CREATE_OR_UPDATE)
def create_policy(self, context, policy):
self.nb_api.create_qos_policy(policy['id'],
policy['tenant_id'],
name=policy['name'],
rules=policy.get('rules', []),
version=policy['revision_number'])
@lock_db.wrap_db_lock(lock_db.RESOURCE_QOS_POLICY_CREATE_OR_UPDATE)
def update_policy(self, context, policy):
policy_id = policy['id']
# NOTE: Neutron will not pass policy with latest revision_number
# in argument. Get the latest policy from neutron.
policy_neutron = self._plugin.get_policy(context, policy_id)
self.nb_api.update_qos_policy(
policy_id, policy_neutron['tenant_id'],
name=policy['name'], rules=policy_neutron['rules'],
version=policy_neutron['revision_number'])
@lock_db.wrap_db_lock(lock_db.RESOURCE_QOS_POLICY_DELETE)
def delete_policy(self, context, policy):
policy_id = policy['id']
# Only id will be in policy in the argument. Get full policy from
# neutron.
policy_neutron = self._plugin.get_policy(context, policy_id)
self.nb_api.delete_qos_policy(policy_id, policy_neutron['tenant_id'])

View File

@ -14,11 +14,15 @@ import contextlib
from neutronclient.common import exceptions as n_exc
from oslo_concurrency import lockutils
from oslo_config import cfg
from dragonflow.tests.common import utils
from dragonflow.tests.fullstack import test_base
from dragonflow.tests.fullstack import test_objects as objects
# TODO(xiaohhui): This should be removed, once the DFPlugin has been removed.
DF_PLUGIN = 'dragonflow.neutron.plugin.DFPlugin'
class TestNeutronAPIandDB(test_base.DFTestBase):
@ -174,6 +178,75 @@ class TestNeutronAPIandDB(test_base.DFTestBase):
network.close()
self.assertFalse(network.exists())
def test_create_port_with_qospolicy(self):
if cfg.CONF.core_plugin == DF_PLUGIN:
return
network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
network_id = network.create()
self.assertTrue(network.exists())
qospolicy = self.store(objects.QosPolicyTestObj(self.neutron,
self.nb_api))
qos_policy_id = qospolicy.create()
self.assertTrue(qospolicy.exists())
port = self.store(objects.PortTestObj(self.neutron,
self.nb_api,
network_id))
port_param = {
'admin_state_up': True,
'name': 'port1',
'network_id': network_id,
'qos_policy_id': qos_policy_id
}
port.create(port_param)
self.assertTrue(port.exists())
self.assertEqual(qos_policy_id,
port.get_logical_port().get_qos_policy_id())
port.close()
self.assertFalse(port.exists())
network.close()
self.assertFalse(network.exists())
qospolicy.close()
self.assertFalse(qospolicy.exists())
def test_update_port_with_qospolicy(self):
if cfg.CONF.core_plugin == DF_PLUGIN:
return
network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
network_id = network.create()
self.assertTrue(network.exists())
qospolicy = self.store(objects.QosPolicyTestObj(self.neutron,
self.nb_api))
qos_policy_id = qospolicy.create()
self.assertTrue(qospolicy.exists())
port = self.store(objects.PortTestObj(self.neutron,
self.nb_api,
network_id))
port.create()
self.assertTrue(port.exists())
port_param = {
'admin_state_up': True,
'name': 'port1',
'qos_policy_id': qos_policy_id
}
port.update(port_param)
self.assertEqual(qos_policy_id,
port.get_logical_port().get_qos_policy_id())
port.close()
self.assertFalse(port.exists())
network.close()
self.assertFalse(network.exists())
qospolicy.close()
self.assertFalse(qospolicy.exists())
def test_delete_router_interface_port(self):
router = self.store(objects.RouterTestObj(self.neutron, self.nb_api))
network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api))
@ -241,6 +314,20 @@ class TestNeutronAPIandDB(test_base.DFTestBase):
secgroup.close()
self.assertFalse(secgroup.exists())
def test_create_delete_qos_policy(self):
if cfg.CONF.core_plugin == DF_PLUGIN:
return
qospolicy = self.store(
objects.QosPolicyTestObj(self.neutron, self.nb_api))
policy_id = qospolicy.create()
self.assertTrue(qospolicy.exists())
rule = {'max_kbps': '1000', 'max_burst_kbps': '100'}
qospolicy.create_rule(policy_id, rule)
self.assertTrue(qospolicy.exists())
qospolicy.close()
self.assertFalse(qospolicy.exists())
@contextlib.contextmanager
def _prepare_ext_net(self):
external_net = objects.find_first_network(self.neutron,

View File

@ -13,10 +13,13 @@
import contextlib
from oslo_concurrency import lockutils
from oslo_config import cfg
from dragonflow.tests.fullstack import test_base
from dragonflow.tests.fullstack import test_objects as objects
DF_PLUGIN = 'dragonflow.neutron.plugin.DFPlugin'
class TestObjectVersion(test_base.DFTestBase):
@ -127,6 +130,25 @@ class TestObjectVersion(test_base.DFTestBase):
secgroup.close()
self.assertFalse(secgroup.exists())
def test_qospolicy_version(self):
if cfg.CONF.core_plugin == DF_PLUGIN:
return
qospolicy = self.store(objects.QosPolicyTestObj(self.neutron,
self.nb_api))
policy_id = qospolicy.create()
self.assertTrue(qospolicy.exists())
version = self.nb_api.get_qos_policy(policy_id).get_version()
rule = {'max_kbps': '1000', 'max_burst_kbps': '100'}
qospolicy.create_rule(policy_id, rule)
self.assertTrue(qospolicy.exists())
new_version = self.nb_api.get_qos_policy(policy_id).get_version()
self.assertGreater(new_version, version)
qospolicy.close()
self.assertFalse(qospolicy.exists())
@contextlib.contextmanager
def _prepare_ext_net(self):
external_net = objects.find_first_network(self.neutron,

View File

@ -444,3 +444,34 @@ class FloatingipTestObj(object):
return True
return False
utils.wait_until_true(internal_predicate, timeout, sleep, exception)
class QosPolicyTestObj(object):
def __init__(self, neutron, nb_api):
self.policy_id = None
self.neutron = neutron
self.nb_api = nb_api
self.closed = False
def create(self, qospolicy={'name': 'myqospolicy1'}):
new_qospolicy = self.neutron.create_qos_policy({'policy':
qospolicy})
self.policy_id = new_qospolicy['policy']['id']
return self.policy_id
def create_rule(self, policy_id, rule):
self.neutron.create_bandwidth_limit_rule(
policy_id, {'bandwidth_limit_rule': rule})
return
def close(self):
if self.closed or self.policy_id is None:
return
self.neutron.delete_qos_policy(self.policy_id)
self.closed = True
def exists(self):
qospolicy = self.nb_api.get_qos_policy(self.policy_id)
if qospolicy:
return True
return False

View File

@ -0,0 +1,98 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from neutron.conf.services import qos_driver_manager as driver_mgr_config
from neutron import manager
from neutron.objects.qos import rule
from neutron.plugins.ml2 import config as ml2_config
from dragonflow.tests.unit import test_mech_driver
class TestDFQosNotificationDriver(test_mech_driver.DFMechanismDriverTestCase):
"""Test case of df qos notification drvier"""
_extension_drivers = ['qos']
def get_additional_service_plugins(self):
p = super(TestDFQosNotificationDriver,
self).get_additional_service_plugins()
p.update({'qos_plugin_name': 'qos'})
return p
def setUp(self):
ml2_config.cfg.CONF.set_override('extension_drivers',
self._extension_drivers,
group='ml2')
driver_mgr_config.register_qos_plugin_opts(ml2_config.cfg.CONF)
ml2_config.cfg.CONF.set_override('notification_drivers',
['df_notification_driver'], 'qos')
super(TestDFQosNotificationDriver, self).setUp()
self.plugin = (manager.NeutronManager.
get_service_plugins()['QOS'])
self.driver = (
self.plugin.notification_driver_manager.notification_drivers[0])
def _test_create_policy(self):
qos_policy = {'policy': {'name': "policy1", 'tenant_id': "tenant1"}}
qos_obj = self.plugin.create_policy(self.context, qos_policy)
self.assertGreater(qos_obj['revision_number'], 0)
self.driver.nb_api.create_qos_policy.assert_called_with(
mock.ANY, 'tenant1', name='policy1',
rules=[], version=qos_obj['revision_number'])
return qos_obj
def test_create_policy(self):
self._test_create_policy()
def test_update_policy(self):
qos_obj = self._test_create_policy()
new_qos_obj = self.plugin.update_policy(
self.context, qos_obj['id'], {'policy': {'name': 'policy2'}})
self.assertGreater(new_qos_obj['revision_number'],
qos_obj['revision_number'])
self.driver.nb_api.update_qos_policy.assert_called_with(
qos_obj['id'], 'tenant1', name='policy2',
rules=[], version=new_qos_obj['revision_number'])
def test_create_delete_policy_rule(self):
qos_obj = self._test_create_policy()
qos_rule = {'max_burst_kbps': 1000,
'max_kbps': 100}
qos_rule_obj = self.plugin.create_policy_rule(
self.context, rule.QosBandwidthLimitRule,
qos_obj['id'], {'bandwidth_limit_rule': qos_rule})
new_qos_obj = self.plugin.get_policy(self.context, qos_obj['id'])
self.assertGreater(new_qos_obj['revision_number'],
qos_obj['revision_number'])
self.driver.nb_api.update_qos_policy.assert_called_with(
qos_obj['id'], 'tenant1', name='policy1',
rules=[qos_rule_obj], version=new_qos_obj['revision_number'])
self.plugin.delete_policy_rule(self.context,
rule.QosBandwidthLimitRule,
qos_rule_obj['id'],
qos_obj['id'])
newer_qos_obj = self.plugin.get_policy(self.context, qos_obj['id'])
self.assertGreater(newer_qos_obj['revision_number'],
new_qos_obj['revision_number'])
self.driver.nb_api.update_qos_policy.assert_called_with(
qos_obj['id'], 'tenant1', name='policy1',
rules=[], version=newer_qos_obj['revision_number'])
def test_delete_policy(self):
qos_obj = self._test_create_policy()
self.plugin.delete_policy(self.context, qos_obj['id'])
self.driver.nb_api.delete_qos_policy.assert_called_with(
qos_obj['id'], 'tenant1')

View File

@ -123,7 +123,8 @@ class TestDFMechDriver(DFMechanismDriverTestCase):
physical_network=network['provider:physical_network'],
router_external=network['router:external'],
mtu=network['mtu'], version=network['revision_number'],
subnets=[])
subnets=[],
qos_policy_id=None)
return network
def test_create_network_revision(self):
@ -221,7 +222,8 @@ class TestDFMechDriver(DFMechanismDriverTestCase):
remote_vtep=False,
allowed_address_pairs=mock.ANY,
binding_profile=mock.ANY,
binding_vnic_type=mock.ANY)
binding_vnic_type=mock.ANY,
qos_policy_id=None)
data = {'port': {'name': 'updated'}}
req = self.new_update_request('ports', data, port['id'])
@ -244,7 +246,8 @@ class TestDFMechDriver(DFMechanismDriverTestCase):
port_security_enabled=mock.ANY,
allowed_address_pairs=mock.ANY,
binding_profile=mock.ANY,
binding_vnic_type=mock.ANY)
binding_vnic_type=mock.ANY,
qos_policy_id=None)
def test_delete_network(self):
network = self._test_create_network_revision()
@ -272,6 +275,7 @@ class TestDFMechDriver(DFMechanismDriverTestCase):
device_id=port['device_id'],
security_groups=mock.ANY,
port_security_enabled=mock.ANY,
qos_policy_id=mock.ANY,
remote_vtep=True,
allowed_address_pairs=mock.ANY,
binding_profile=profile,
@ -291,6 +295,7 @@ class TestDFMechDriver(DFMechanismDriverTestCase):
version=mock.ANY,
device_owner=port['device_owner'],
device_id=port['device_id'],
qos_policy_id=mock.ANY,
remote_vtep=True,
security_groups=mock.ANY,
port_security_enabled=mock.ANY,

View File

@ -48,6 +48,8 @@ output_file = dragonflow/locale/dragonflow.pot
[entry_points]
neutron.qos.notification_drivers =
df_notification_driver = dragonflow.neutron.services.qos.notification_drivers.df_qos_notification_driver:DFQosServiceNotificationDriver
neutron.ml2.mechanism_drivers =
df = dragonflow.neutron.ml2.mech_driver:DFMechDriver
neutron.db.alembic_migrations =