Merge "NSX-V3| Validate Qos burst size before rule creation"
This commit is contained in:
commit
93cf1a5128
@ -28,7 +28,11 @@ from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.db import db as nsx_db
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
MAX_KBPS_MIN_VALUE = 1024
|
||||
# The max limit is calculated so that the value sent to the backed will
|
||||
# be smaller than 2**31
|
||||
MAX_BURST_MAX_VALUE = int((2 ** 31 - 1) / 128)
|
||||
|
||||
|
||||
def handle_qos_notification(context, resource_type, policies_list,
|
||||
@ -125,6 +129,29 @@ class QosNotificationsHandler(object):
|
||||
name=policy.name,
|
||||
description=policy.description)
|
||||
|
||||
def _validate_bw_values(self, bw_rule):
|
||||
"""Validate that the configured values are allowed by the NSX backend.
|
||||
|
||||
Since failing the action from the notification callback
|
||||
is not possible, just log the warning and use the minimal/maximal
|
||||
values.
|
||||
"""
|
||||
# Validate the max bandwidth value minimum value
|
||||
# (max value is above what neutron allows so no need to check it)
|
||||
if (bw_rule.max_kbps < MAX_KBPS_MIN_VALUE):
|
||||
LOG.warning(_LW("Invalid input for max_kbps. "
|
||||
"The minimal legal value is %s"),
|
||||
MAX_KBPS_MIN_VALUE)
|
||||
bw_rule.max_kbps = MAX_KBPS_MIN_VALUE
|
||||
|
||||
# validate the burst size value max value
|
||||
# (max value is 0, and neutron already validates this)
|
||||
if (bw_rule.max_burst_kbps > MAX_BURST_MAX_VALUE):
|
||||
LOG.warning(_LW("Invalid input for burst_size. "
|
||||
"The maximal legal value is %s"),
|
||||
MAX_BURST_MAX_VALUE)
|
||||
bw_rule.max_burst_kbps = MAX_BURST_MAX_VALUE
|
||||
|
||||
def _get_bw_values_from_rule(self, bw_rule):
|
||||
"""Translate the neutron bandwidth_limit_rule values, into the
|
||||
values expected by the NSX-v3 QoS switch profile,
|
||||
@ -132,19 +159,7 @@ class QosNotificationsHandler(object):
|
||||
"""
|
||||
if bw_rule:
|
||||
shaping_enabled = True
|
||||
|
||||
# validate the max_kbps - it must be at least 1Mbps for the
|
||||
# switch profile configuration to succeed.
|
||||
if (bw_rule.max_kbps < MAX_KBPS_MIN_VALUE):
|
||||
# Since failing the action from the notification callback
|
||||
# is not possible, just log the warning and use the
|
||||
# minimal value.
|
||||
LOG.warning(_LW("Invalid input for max_kbps. "
|
||||
"The minimal legal value is 1024"))
|
||||
bw_rule.max_kbps = MAX_KBPS_MIN_VALUE
|
||||
|
||||
# 'None' value means we will keep the old value
|
||||
burst_size = peak_bandwidth = average_bandwidth = None
|
||||
self._validate_bw_values(bw_rule)
|
||||
|
||||
# translate kbps -> bytes
|
||||
burst_size = int(bw_rule.max_burst_kbps) * 128
|
||||
|
@ -218,6 +218,48 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
|
||||
qos_marking='trusted'
|
||||
)
|
||||
|
||||
@mock.patch.object(policy_object.QosPolicy, 'reload_rules')
|
||||
def test_bw_rule_create_profile_maximal_val(self, *mocks):
|
||||
# test the switch profile update when a QoS rule is created
|
||||
# with an invalid burst value
|
||||
bad_burst = qos_utils.MAX_BURST_MAX_VALUE + 1
|
||||
rule_data = {
|
||||
'bandwidth_limit_rule': {'id': uuidutils.generate_uuid(),
|
||||
'max_kbps': 1025,
|
||||
'max_burst_kbps': bad_burst}}
|
||||
|
||||
rule = rule_object.QosBandwidthLimitRule(
|
||||
self.ctxt, **rule_data['bandwidth_limit_rule'])
|
||||
|
||||
_policy = policy_object.QosPolicy(
|
||||
self.ctxt, **self.policy_data['policy'])
|
||||
# add a rule to the policy
|
||||
setattr(_policy, "rules", [rule])
|
||||
with mock.patch('neutron.objects.qos.policy.QosPolicy.get_object',
|
||||
return_value=_policy):
|
||||
with mock.patch(
|
||||
'vmware_nsxlib.v3.NsxLibQosSwitchingProfile.update_shaping'
|
||||
) as update_profile:
|
||||
with mock.patch('neutron.objects.db.api.update_object',
|
||||
return_value=rule_data):
|
||||
self.qos_plugin.update_policy_bandwidth_limit_rule(
|
||||
self.ctxt, rule.id, _policy.id, rule_data)
|
||||
|
||||
# validate the data on the profile
|
||||
rule_dict = rule_data['bandwidth_limit_rule']
|
||||
expected_burst = qos_utils.MAX_BURST_MAX_VALUE * 128
|
||||
expected_bw = int(rule_dict['max_kbps'] / 1024)
|
||||
expected_peak = int(expected_bw * self.peak_bw_multiplier)
|
||||
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,
|
||||
dscp=0,
|
||||
qos_marking='trusted'
|
||||
)
|
||||
|
||||
@mock.patch.object(policy_object.QosPolicy, 'reload_rules')
|
||||
def test_dscp_rule_create_profile(self, *mocks):
|
||||
# test the switch profile update when a QoS DSCP rule is created
|
||||
|
Loading…
x
Reference in New Issue
Block a user