Merge "NSX|V3: Support QoS ingress rules"
This commit is contained in:
commit
63154b510b
@ -33,7 +33,8 @@ SUPPORTED_RULES = {
|
||||
qos_consts.MAX_BURST: {
|
||||
'type:range': [0, n_consts.DB_INTEGER_MAX_VALUE]},
|
||||
qos_consts.DIRECTION: {
|
||||
'type:values': [n_consts.EGRESS_DIRECTION]}
|
||||
'type:values': [n_consts.EGRESS_DIRECTION,
|
||||
n_consts.INGRESS_DIRECTION]}
|
||||
},
|
||||
qos_consts.RULE_TYPE_DSCP_MARKING: {
|
||||
qos_consts.DSCP_MARK: {'type:values': n_consts.VALID_DSCP_MARKS}
|
||||
@ -67,17 +68,8 @@ class NSXv3QosDriver(base.DriverBase):
|
||||
|
||||
def update_policy(self, context, policy):
|
||||
if (hasattr(policy, "rules")):
|
||||
# we may have up to 1 rule of each type
|
||||
bw_rule = None
|
||||
dscp_rule = None
|
||||
for rule in policy["rules"]:
|
||||
if rule.rule_type == qos_consts.RULE_TYPE_BANDWIDTH_LIMIT:
|
||||
bw_rule = rule
|
||||
else:
|
||||
dscp_rule = rule
|
||||
|
||||
self.handler.update_policy_rules(
|
||||
context, policy.id, bw_rule, dscp_rule)
|
||||
context, policy.id, policy["rules"])
|
||||
|
||||
# May also need to update name / description
|
||||
self.handler.update_policy(context, policy.id, policy)
|
||||
|
@ -17,6 +17,7 @@
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
from neutron.common import constants as n_consts
|
||||
from neutron.services.qos import qos_consts
|
||||
from neutron_lib.api import validators
|
||||
from neutron_lib import exceptions as n_exc
|
||||
@ -150,25 +151,45 @@ class QosNotificationsHandler(object):
|
||||
|
||||
return qos_marking, dscp
|
||||
|
||||
def update_policy_rules(self, context, policy_id, bw_rule, dscp_rule):
|
||||
def update_policy_rules(self, context, policy_id, rules):
|
||||
"""Update the QoS switch profile with the BW limitations and
|
||||
DSCP marking configuration
|
||||
"""
|
||||
profile_id = nsx_db.get_switch_profile_by_qos_policy(
|
||||
context.session, policy_id)
|
||||
|
||||
(shaping_enabled, burst_size, peak_bw,
|
||||
average_bw) = self._get_bw_values_from_rule(bw_rule)
|
||||
ingress_bw_rule = None
|
||||
egress_bw_rule = None
|
||||
dscp_rule = None
|
||||
for rule in rules:
|
||||
if rule.rule_type == qos_consts.RULE_TYPE_BANDWIDTH_LIMIT:
|
||||
if rule.direction == n_consts.EGRESS_DIRECTION:
|
||||
egress_bw_rule = rule
|
||||
else:
|
||||
ingress_bw_rule = rule
|
||||
else:
|
||||
dscp_rule = rule
|
||||
|
||||
# the NSX direction is opposite to the neutron direction
|
||||
(ingress_bw_enabled, ingress_burst_size, ingress_peak_bw,
|
||||
ingress_average_bw) = self._get_bw_values_from_rule(egress_bw_rule)
|
||||
|
||||
(egress_bw_enabled, egress_burst_size, egress_peak_bw,
|
||||
egress_average_bw) = self._get_bw_values_from_rule(ingress_bw_rule)
|
||||
|
||||
qos_marking, dscp = self._get_dscp_values_from_rule(dscp_rule)
|
||||
self._nsxlib_qos.update_shaping(
|
||||
|
||||
self._nsxlib_qos.set_profile_shaping(
|
||||
profile_id,
|
||||
shaping_enabled=shaping_enabled,
|
||||
burst_size=burst_size,
|
||||
peak_bandwidth=peak_bw,
|
||||
average_bandwidth=average_bw,
|
||||
qos_marking=qos_marking,
|
||||
dscp=dscp)
|
||||
ingress_bw_enabled=ingress_bw_enabled,
|
||||
ingress_burst_size=ingress_burst_size,
|
||||
ingress_peak_bandwidth=ingress_peak_bw,
|
||||
ingress_average_bandwidth=ingress_average_bw,
|
||||
egress_bw_enabled=egress_bw_enabled,
|
||||
egress_burst_size=egress_burst_size,
|
||||
egress_peak_bandwidth=egress_peak_bw,
|
||||
egress_average_bandwidth=egress_average_bw,
|
||||
qos_marking=qos_marking, dscp=dscp)
|
||||
|
||||
def validate_policy_rule(self, context, policy_id, rule):
|
||||
"""Raise an exception if the rule values are not supported"""
|
||||
|
@ -57,6 +57,11 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
'bandwidth_limit_rule': {'id': uuidutils.generate_uuid(),
|
||||
'max_kbps': 2000,
|
||||
'max_burst_kbps': 150}}
|
||||
self.ingress_rule_data = {
|
||||
'bandwidth_limit_rule': {'id': uuidutils.generate_uuid(),
|
||||
'max_kbps': 3000,
|
||||
'max_burst_kbps': 350,
|
||||
'direction': 'ingress'}}
|
||||
self.dscp_rule_data = {
|
||||
'dscp_marking_rule': {'id': uuidutils.generate_uuid(),
|
||||
'dscp_mark': 22}}
|
||||
@ -64,8 +69,12 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
self.policy = policy_object.QosPolicy(
|
||||
self.ctxt, **self.policy_data['policy'])
|
||||
|
||||
# egress BW limit rule
|
||||
self.rule = rule_object.QosBandwidthLimitRule(
|
||||
self.ctxt, **self.rule_data['bandwidth_limit_rule'])
|
||||
# ingress bw limit rule
|
||||
self.ingress_rule = rule_object.QosBandwidthLimitRule(
|
||||
self.ctxt, **self.ingress_rule_data['bandwidth_limit_rule'])
|
||||
self.dscp_rule = rule_object.QosDscpMarkingRule(
|
||||
self.ctxt, **self.dscp_rule_data['dscp_marking_rule'])
|
||||
|
||||
@ -140,7 +149,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
|
||||
@mock.patch.object(policy_object.QosPolicy, '_reload_rules')
|
||||
def test_bw_rule_create_profile(self, *mocks):
|
||||
# test the switch profile update when a QoS BW rule is created
|
||||
# test the switch profile update when a egress QoS BW rule is created
|
||||
_policy = policy_object.QosPolicy(
|
||||
self.ctxt, **self.policy_data['policy'])
|
||||
# add a rule to the policy
|
||||
@ -149,7 +158,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
return_value=_policy):
|
||||
with mock.patch(
|
||||
'vmware_nsxlib.v3.core_resources.NsxLibQosSwitchingProfile.'
|
||||
'update_shaping'
|
||||
'set_profile_shaping'
|
||||
) as update_profile:
|
||||
with mock.patch('neutron.objects.db.api.update_object',
|
||||
return_value=self.rule_data):
|
||||
@ -162,14 +171,59 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
rule_dict['max_kbps']) / 1024))
|
||||
expected_burst = rule_dict['max_burst_kbps'] * 128
|
||||
expected_peak = int(expected_bw * self.peak_bw_multiplier)
|
||||
# egress neutron rule -> ingress nsx args
|
||||
update_profile.assert_called_once_with(
|
||||
self.fake_profile_id,
|
||||
average_bandwidth=expected_bw,
|
||||
burst_size=expected_burst,
|
||||
peak_bandwidth=expected_peak,
|
||||
shaping_enabled=True,
|
||||
qos_marking='trusted',
|
||||
dscp=0
|
||||
ingress_bw_enabled=True,
|
||||
ingress_burst_size=expected_burst,
|
||||
ingress_peak_bandwidth=expected_peak,
|
||||
ingress_average_bandwidth=expected_bw,
|
||||
egress_bw_enabled=False,
|
||||
egress_burst_size=None,
|
||||
egress_peak_bandwidth=None,
|
||||
egress_average_bandwidth=None,
|
||||
dscp=0,
|
||||
qos_marking='trusted'
|
||||
)
|
||||
|
||||
@mock.patch.object(policy_object.QosPolicy, '_reload_rules')
|
||||
def test_ingress_bw_rule_create_profile(self, *mocks):
|
||||
# test the switch profile update when a ingress QoS BW rule is created
|
||||
_policy = policy_object.QosPolicy(
|
||||
self.ctxt, **self.policy_data['policy'])
|
||||
# add a rule to the policy
|
||||
setattr(_policy, "rules", [self.ingress_rule])
|
||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
||||
return_value=_policy):
|
||||
with mock.patch(
|
||||
'vmware_nsxlib.v3.core_resources.NsxLibQosSwitchingProfile.'
|
||||
'set_profile_shaping'
|
||||
) as update_profile:
|
||||
with mock.patch('neutron.objects.db.api.update_object',
|
||||
return_value=self.ingress_rule_data):
|
||||
self.qos_plugin.update_policy_bandwidth_limit_rule(
|
||||
self.ctxt, self.ingress_rule.id, _policy.id,
|
||||
self.ingress_rule_data)
|
||||
|
||||
# validate the data on the profile
|
||||
rule_dict = self.ingress_rule_data['bandwidth_limit_rule']
|
||||
expected_bw = int(round(float(
|
||||
rule_dict['max_kbps']) / 1024))
|
||||
expected_burst = rule_dict['max_burst_kbps'] * 128
|
||||
expected_peak = int(expected_bw * self.peak_bw_multiplier)
|
||||
# ingress neutron rule -> egress nsx args
|
||||
update_profile.assert_called_once_with(
|
||||
self.fake_profile_id,
|
||||
egress_bw_enabled=True,
|
||||
egress_burst_size=expected_burst,
|
||||
egress_peak_bandwidth=expected_peak,
|
||||
egress_average_bandwidth=expected_bw,
|
||||
ingress_bw_enabled=False,
|
||||
ingress_burst_size=None,
|
||||
ingress_peak_bandwidth=None,
|
||||
ingress_average_bandwidth=None,
|
||||
dscp=0,
|
||||
qos_marking='trusted'
|
||||
)
|
||||
|
||||
@mock.patch.object(policy_object.QosPolicy, '_reload_rules')
|
||||
@ -233,7 +287,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
return_value=_policy):
|
||||
with mock.patch(
|
||||
'vmware_nsxlib.v3.core_resources.NsxLibQosSwitchingProfile.'
|
||||
'update_shaping'
|
||||
'set_profile_shaping'
|
||||
) as update_profile:
|
||||
with mock.patch('neutron.objects.db.api.'
|
||||
'update_object', return_value=self.dscp_rule_data):
|
||||
@ -246,12 +300,16 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
dscp_mark = rule_dict['dscp_mark']
|
||||
update_profile.assert_called_once_with(
|
||||
self.fake_profile_id,
|
||||
average_bandwidth=None,
|
||||
burst_size=None,
|
||||
peak_bandwidth=None,
|
||||
shaping_enabled=False,
|
||||
qos_marking='untrusted',
|
||||
dscp=dscp_mark
|
||||
ingress_bw_enabled=False,
|
||||
ingress_burst_size=None,
|
||||
ingress_peak_bandwidth=None,
|
||||
ingress_average_bandwidth=None,
|
||||
egress_bw_enabled=False,
|
||||
egress_burst_size=None,
|
||||
egress_peak_bandwidth=None,
|
||||
egress_average_bandwidth=None,
|
||||
dscp=dscp_mark,
|
||||
qos_marking='untrusted'
|
||||
)
|
||||
|
||||
def test_rule_delete_profile(self):
|
||||
@ -264,7 +322,7 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
return_value=_policy):
|
||||
with mock.patch(
|
||||
'vmware_nsxlib.v3.core_resources.NsxLibQosSwitchingProfile.'
|
||||
'update_shaping'
|
||||
'set_profile_shaping'
|
||||
) as update_profile:
|
||||
setattr(_policy, "rules", [self.rule])
|
||||
self.qos_plugin.delete_policy_bandwidth_limit_rule(
|
||||
@ -272,11 +330,15 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
# validate the data on the profile
|
||||
update_profile.assert_called_once_with(
|
||||
self.fake_profile_id,
|
||||
shaping_enabled=False,
|
||||
average_bandwidth=None,
|
||||
burst_size=None,
|
||||
ingress_bw_enabled=False,
|
||||
ingress_burst_size=None,
|
||||
ingress_peak_bandwidth=None,
|
||||
ingress_average_bandwidth=None,
|
||||
egress_bw_enabled=False,
|
||||
egress_burst_size=None,
|
||||
egress_peak_bandwidth=None,
|
||||
egress_average_bandwidth=None,
|
||||
dscp=0,
|
||||
peak_bandwidth=None,
|
||||
qos_marking='trusted'
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user