From 71672344cfe98c7b5351deaef8c6620582207c1a Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Mon, 3 Jul 2017 08:46:55 +0300 Subject: [PATCH] NSX|V: Support QoS ingress rules Commit Ia13568879c2b6f80fb190ccafe7e19ca05b0c6a8 added the ingress direction BW rules. This patch adds this support for the NSX-V QoS driver. Change-Id: I7bf4715549fc2af26789ecd9e20c444a387ffd77 --- vmware_nsx/dvs/dvs.py | 25 ++++++++++--- vmware_nsx/services/qos/nsx_v/driver.py | 3 +- vmware_nsx/services/qos/nsx_v/utils.py | 37 ++++++++++++------- .../services/qos/test_nsxv_notification.py | 15 +++++++- 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/vmware_nsx/dvs/dvs.py b/vmware_nsx/dvs/dvs.py index f01839e648..4d65606c31 100644 --- a/vmware_nsx/dvs/dvs.py +++ b/vmware_nsx/dvs/dvs.py @@ -210,17 +210,31 @@ class DvsManager(VCManagerBase): # Note: openstack refers to the directions from the VM point of view, # while the NSX refers to the vswitch point of view. # so open stack egress is actually inShaping here. - outPol = port_conf.inShapingPolicy - if qos_data.bandwidthEnabled: + inPol = port_conf.inShapingPolicy + if qos_data.egress.bandwidthEnabled: + inPol.inherited = False + inPol.enabled.inherited = False + inPol.enabled.value = True + inPol.averageBandwidth.inherited = False + inPol.averageBandwidth.value = qos_data.egress.averageBandwidth + inPol.peakBandwidth.inherited = False + inPol.peakBandwidth.value = qos_data.egress.peakBandwidth + inPol.burstSize.inherited = False + inPol.burstSize.value = qos_data.egress.burstSize + else: + inPol.inherited = True + + outPol = port_conf.outShapingPolicy + if qos_data.ingress.bandwidthEnabled: outPol.inherited = False outPol.enabled.inherited = False outPol.enabled.value = True outPol.averageBandwidth.inherited = False - outPol.averageBandwidth.value = qos_data.averageBandwidth + outPol.averageBandwidth.value = qos_data.ingress.averageBandwidth outPol.peakBandwidth.inherited = False - outPol.peakBandwidth.value = qos_data.peakBandwidth + outPol.peakBandwidth.value = qos_data.ingress.peakBandwidth outPol.burstSize.inherited = False - outPol.burstSize.value = qos_data.burstSize + outPol.burstSize.value = qos_data.ingress.burstSize else: outPol.inherited = True @@ -633,7 +647,6 @@ class ClusterManager(VCManagerBase): def update_cluster_edge_failover(self, resource_id, vm_moids, host_group_names): """Updates cluster for vm placement using DRS""" - # DEBUG ADIT edge-id is never used session = self._session resource = vim_util.get_moref(resource_id, 'ResourcePool') # TODO(garyk): cache the cluster details diff --git a/vmware_nsx/services/qos/nsx_v/driver.py b/vmware_nsx/services/qos/nsx_v/driver.py index dcc82f06a5..ae03c684ea 100644 --- a/vmware_nsx/services/qos/nsx_v/driver.py +++ b/vmware_nsx/services/qos/nsx_v/driver.py @@ -29,7 +29,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} diff --git a/vmware_nsx/services/qos/nsx_v/utils.py b/vmware_nsx/services/qos/nsx_v/utils.py index dc6d9ff5dc..62fbcfa56d 100644 --- a/vmware_nsx/services/qos/nsx_v/utils.py +++ b/vmware_nsx/services/qos/nsx_v/utils.py @@ -14,6 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. +from neutron.common import constants as n_consts from neutron.services.qos import qos_consts from neutron_lib.plugins import constants as plugin_const from neutron_lib.plugins import directory @@ -24,6 +25,15 @@ from oslo_log import log as logging LOG = logging.getLogger(__name__) +class NsxVQosBWLimits(object): + # Data structure to hold the NSX-V representation + # of the neutron QoS Bandwidth rule + bandwidthEnabled = False + averageBandwidth = 0 + peakBandwidth = 0 + burstSize = 0 + + class NsxVQosRule(object): def __init__(self, context=None, qos_policy_id=None): @@ -32,11 +42,9 @@ class NsxVQosRule(object): self._qos_plugin = None # Data structure to hold the NSX-V representation - # of the neutron QoS Bandwidth rule - self.bandwidthEnabled = False - self.averageBandwidth = 0 - self.peakBandwidth = 0 - self.burstSize = 0 + # of the neutron QoS Bandwidth rule for both directions + self.egress = NsxVQosBWLimits() + self.ingress = NsxVQosBWLimits() # And data for the DSCP marking rule self.dscpMarkEnabled = False @@ -61,23 +69,26 @@ class NsxVQosRule(object): policy_obj = plugin.get_policy(context, qos_policy_id) if 'rules' in policy_obj and len(policy_obj['rules']) > 0: for rule_obj in policy_obj['rules']: - # TODO(asarfaty): for now we support one rule of each type - # This code should be fixed in order to support rules of - # different directions if (rule_obj['type'] == qos_consts.RULE_TYPE_BANDWIDTH_LIMIT): - self.bandwidthEnabled = True + # BW limit rule for one of the directions + if rule_obj['direction'] == n_consts.EGRESS_DIRECTION: + dir_obj = self.egress + else: + dir_obj = self.ingress + dir_obj.bandwidthEnabled = True # averageBandwidth: kbps (neutron) -> bps (nsxv) - self.averageBandwidth = rule_obj['max_kbps'] * 1024 + dir_obj.averageBandwidth = rule_obj['max_kbps'] * 1024 # peakBandwidth: a Multiplying on the average BW # because the neutron qos configuration supports # only 1 value - self.peakBandwidth = int(round( - self.averageBandwidth * + dir_obj.peakBandwidth = int(round( + dir_obj.averageBandwidth * cfg.CONF.NSX.qos_peak_bw_multiplier)) # burstSize: kbps (neutron) -> Bytes (nsxv) - self.burstSize = rule_obj['max_burst_kbps'] * 128 + dir_obj.burstSize = rule_obj['max_burst_kbps'] * 128 if rule_obj['type'] == qos_consts.RULE_TYPE_DSCP_MARKING: + # DSCP marking rule self.dscpMarkEnabled = True self.dscpMarkValue = rule_obj['dscp_mark'] diff --git a/vmware_nsx/tests/unit/services/qos/test_nsxv_notification.py b/vmware_nsx/tests/unit/services/qos/test_nsxv_notification.py index 1597e773f6..57037f30c4 100644 --- a/vmware_nsx/tests/unit/services/qos/test_nsxv_notification.py +++ b/vmware_nsx/tests/unit/services/qos/test_nsxv_notification.py @@ -74,6 +74,13 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase, 'max_kbps': 100, 'max_burst_kbps': 150, 'type': qos_consts.RULE_TYPE_BANDWIDTH_LIMIT}} + self.ingress_rule_data = { + 'bandwidth_limit_rule': { + 'id': uuidutils.generate_uuid(), + 'max_kbps': 200, + 'max_burst_kbps': 250, + 'direction': 'ingress', + 'type': qos_consts.RULE_TYPE_BANDWIDTH_LIMIT}} self.dscp_rule_data = { 'dscp_marking_rule': { 'id': uuidutils.generate_uuid(), @@ -83,8 +90,13 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase, self.policy = policy_object.QosPolicy( self.ctxt, **self.policy_data['policy']) + # egress bw rule self.rule = rule_object.QosBandwidthLimitRule( self.ctxt, **self.rule_data['bandwidth_limit_rule']) + # ingress bw rule + self.ingress_rule = rule_object.QosBandwidthLimitRule( + self.ctxt, **self.ingress_rule_data['bandwidth_limit_rule']) + # dscp marking rule self.dscp_rule = rule_object.QosDscpMarkingRule( self.ctxt, **self.dscp_rule_data['dscp_marking_rule']) @@ -128,7 +140,8 @@ class TestQosNsxVNotification(test_plugin.NsxVPluginV2TestCase, # Create a policy with a rule _policy = policy_object.QosPolicy( self.ctxt, **self.policy_data['policy']) - setattr(_policy, "rules", [self.rule, self.dscp_rule]) + setattr(_policy, "rules", [self.rule, self.ingress_rule, + self.dscp_rule]) with mock.patch('neutron.services.qos.qos_plugin.QoSPlugin.' 'get_policy',