Add object versioning to QoS DSCP.

- Changes RULE_TYPE_DSCP_MARK to RULE_TYPE_DSCP_MARKING to conform
  with the rules name.
- Added object versioning to qos related objects.
 - qos/rule: Throws a QosRuleVersionUnavailable exception when
   the QosDscpMarkingRule version is < '1.1'.
- removed test object version incrementation TODO from test_policy.py
 - Object versioning can not be used to increment the object version.

Change-Id: I4f10ef3c1cbaa2a868de2b8e3abc4c39eb1f44c7
Partial-Bug: #1468353
This commit is contained in:
David Shaughnessy 2016-03-14 16:27:54 +00:00
parent 253bef21e0
commit 1bb95a4554
10 changed files with 50 additions and 13 deletions

View File

@ -17,7 +17,9 @@ import abc
import sys import sys
from neutron_lib import constants from neutron_lib import constants
from oslo_utils import versionutils
from oslo_versionedobjects import base as obj_base from oslo_versionedobjects import base as obj_base
from oslo_versionedobjects import exception
from oslo_versionedobjects import fields as obj_fields from oslo_versionedobjects import fields as obj_fields
import six import six
@ -107,4 +109,11 @@ class QosDscpMarkingRule(QosRule):
DSCP_MARK: common_types.DscpMarkField(), DSCP_MARK: common_types.DscpMarkField(),
} }
rule_type = qos_consts.RULE_TYPE_DSCP_MARK rule_type = qos_consts.RULE_TYPE_DSCP_MARKING
def obj_make_compatible(self, primitive, target_version):
_target_version = versionutils.convert_version_to_tuple(target_version)
if _target_version < (1, 1):
raise exception.IncompatibleObjectVersion(
objver=target_version,
objname="QosDscpMarkingRule")

View File

@ -32,7 +32,6 @@ class QosRuleType(base.NeutronObject):
# Version 1.1: Added DscpMarkingRule # Version 1.1: Added DscpMarkingRule
VERSION = '1.1' VERSION = '1.1'
#TODO(davidsha) add obj_make_compatible and associated tests.
fields = { fields = {
'type': RuleTypeField(), 'type': RuleTypeField(),
} }

View File

@ -42,7 +42,7 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
""" """
supported_qos_rule_types = [qos_consts.RULE_TYPE_BANDWIDTH_LIMIT, supported_qos_rule_types = [qos_consts.RULE_TYPE_BANDWIDTH_LIMIT,
qos_consts.RULE_TYPE_DSCP_MARK] qos_consts.RULE_TYPE_DSCP_MARKING]
def __init__(self): def __init__(self):
sg_enabled = securitygroups_rpc.is_firewall_enabled() sg_enabled = securitygroups_rpc.is_firewall_enabled()

View File

@ -14,8 +14,8 @@
# under the License. # under the License.
RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth_limit' RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth_limit'
RULE_TYPE_DSCP_MARK = 'dscp_marking' RULE_TYPE_DSCP_MARKING = 'dscp_marking'
VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT, RULE_TYPE_DSCP_MARK] VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT, RULE_TYPE_DSCP_MARKING]
QOS_POLICY_ID = 'qos_policy_id' QOS_POLICY_ID = 'qos_policy_id'

View File

@ -190,7 +190,7 @@ class TestDscpMarkingQoS(BaseQoSRuleTestCase):
rule = self.safe_client.create_dscp_marking_rule( rule = self.safe_client.create_dscp_marking_rule(
self.tenant_id, qos_policy_id, dscp_mark) self.tenant_id, qos_policy_id, dscp_mark)
# Make it consistent with GET reply # Make it consistent with GET reply
rule['type'] = qos_consts.RULE_TYPE_DSCP_MARK rule['type'] = qos_consts.RULE_TYPE_DSCP_MARKING
rule['qos_policy_id'] = qos_policy_id rule['qos_policy_id'] = qos_policy_id
qos_policy['rules'].append(rule) qos_policy['rules'].append(rule)

View File

@ -737,7 +737,7 @@ class QosDscpMarkingRuleTestJSON(base.BaseAdminNetworkTest):
policy_rules = retrieved_policy['policy']['rules'] policy_rules = retrieved_policy['policy']['rules']
self.assertEqual(1, len(policy_rules)) self.assertEqual(1, len(policy_rules))
self.assertEqual(rule['id'], policy_rules[0]['id']) self.assertEqual(rule['id'], policy_rules[0]['id'])
self.assertEqual(qos_consts.RULE_TYPE_DSCP_MARK, self.assertEqual(qos_consts.RULE_TYPE_DSCP_MARKING,
policy_rules[0]['type']) policy_rules[0]['type'])
@test.idempotent_id('08553ffe-030f-4037-b486-7e0b8fb9385a') @test.idempotent_id('08553ffe-030f-4037-b486-7e0b8fb9385a')

View File

@ -384,10 +384,10 @@ class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase,
self.assertIn(rule_obj_band, policy_obj_v1_1.rules) self.assertIn(rule_obj_band, policy_obj_v1_1.rules)
self.assertIn(rule_obj_dscp, policy_obj_v1_1.rules) self.assertIn(rule_obj_dscp, policy_obj_v1_1.rules)
self.assertEqual(policy_obj.VERSION, '1.1')
#TODO(davidsha) add testing for object version incrementation
def test_object_version_degradation_1_1_to_1_0(self): def test_object_version_degradation_1_1_to_1_0(self):
#NOTE(mangelajo): we should not check .VERSION, since that's the
# local version on the class definition
policy_obj, rule_obj_band, rule_obj_dscp = ( policy_obj, rule_obj_band, rule_obj_dscp = (
self._create_test_policy_with_bw_and_dscp()) self._create_test_policy_with_bw_and_dscp())
@ -395,8 +395,6 @@ class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase,
self.assertIn(rule_obj_band, policy_obj_v1_0.rules) self.assertIn(rule_obj_band, policy_obj_v1_0.rules)
self.assertNotIn(rule_obj_dscp, policy_obj_v1_0.rules) self.assertNotIn(rule_obj_dscp, policy_obj_v1_0.rules)
#NOTE(mangelajo): we should not check .VERSION, since that's the
# local version on the class definition
def test_filter_by_shared(self): def test_filter_by_shared(self):
policy_obj = policy.QosPolicy( policy_obj = policy.QosPolicy(

View File

@ -12,6 +12,8 @@
from neutron_lib import constants from neutron_lib import constants
from oslo_versionedobjects import exception
from neutron.objects.qos import policy from neutron.objects.qos import policy
from neutron.objects.qos import rule from neutron.objects.qos import rule
from neutron.services.qos import qos_consts from neutron.services.qos import qos_consts
@ -91,6 +93,19 @@ class QosDscpMarkingRuleObjectTestCase(test_base.BaseObjectIfaceTestCase):
_test_class = rule.QosDscpMarkingRule _test_class = rule.QosDscpMarkingRule
def test_dscp_object_version_degradation(self):
dscp_rule = rule.QosDscpMarkingRule()
self.assertRaises(exception.IncompatibleObjectVersion,
dscp_rule.obj_to_primitive, '1.0')
def test_dscp_object_version(self):
dscp_rule = rule.QosDscpMarkingRule()
prim = dscp_rule.obj_to_primitive('1.1')
self.assertTrue(prim)
class QosDscpMarkingRuleDbObjectTestCase(test_base.BaseDbObjectTestCase, class QosDscpMarkingRuleDbObjectTestCase(test_base.BaseDbObjectTestCase,
testlib_api.SqlTestCase): testlib_api.SqlTestCase):

View File

@ -44,3 +44,19 @@ class QosRuleTypeObjectTestCase(test_base.BaseTestCase):
def test_wrong_type(self): def test_wrong_type(self):
self.assertRaises(ValueError, rule_type.QosRuleType, type='bad_type') self.assertRaises(ValueError, rule_type.QosRuleType, type='bad_type')
@staticmethod
def _policy_through_version(obj, version):
primitive = obj.obj_to_primitive(target_version=version)
return rule_type.QosRuleType.clean_obj_from_primitive(primitive)
def test_object_version(self):
qos_rule_type = rule_type.QosRuleType()
rule_type_v1_1 = self._policy_through_version(qos_rule_type, '1.1')
self.assertIn(qos_consts.RULE_TYPE_BANDWIDTH_LIMIT,
tuple(rule_type_v1_1.fields['type'].AUTO_TYPE.
_valid_values))
self.assertIn(qos_consts.RULE_TYPE_DSCP_MARKING,
tuple(rule_type_v1_1.fields['type'].AUTO_TYPE.
_valid_values))

View File

@ -6,6 +6,6 @@ prelude: >
features: features:
- Neutron can apply a QoS rule to ports that mark outgoing - Neutron can apply a QoS rule to ports that mark outgoing
traffic's type of service packet header field. traffic's type of service packet header field.
- The Open vSwitch Neutron agent has been extended to mark the type of - The Open vSwitch Neutron agent has been extended to mark the Type of
service packet header field of packets egressing from the VM when the Service IP header field of packets egressing from the VM when the
QoS rule has been applied. QoS rule has been applied.