From d0c735928a02194ab809a3fc50239e51b266b1e2 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Fri, 29 Jul 2016 14:27:45 +0100 Subject: [PATCH] Add QoS DSCP marking rule object and CRUD commands. Closes-Bug: 1611014 Depends-On: Idf319cd182304952071bc976a2e56c42fbcb8468 Change-Id: I6f30ac8d4588b8de2eac4b9436129038e5def582 --- doc/source/users/resources/network/index.rst | 1 + .../network/v2/qos_dscp_marking_rule.rst | 12 ++ openstack/network/v2/_proxy.py | 125 ++++++++++++++++++ openstack/network/v2/qos_dscp_marking_rule.py | 44 ++++++ .../network/v2/test_qos_dscp_marking_rule.py | 81 ++++++++++++ openstack/tests/unit/network/v2/test_proxy.py | 48 +++++++ .../network/v2/test_qos_dscp_marking_rule.py | 44 ++++++ 7 files changed, 355 insertions(+) create mode 100644 doc/source/users/resources/network/v2/qos_dscp_marking_rule.rst create mode 100644 openstack/network/v2/qos_dscp_marking_rule.py create mode 100644 openstack/tests/functional/network/v2/test_qos_dscp_marking_rule.py create mode 100644 openstack/tests/unit/network/v2/test_qos_dscp_marking_rule.py diff --git a/doc/source/users/resources/network/index.rst b/doc/source/users/resources/network/index.rst index a312575c5..a2bf9c278 100644 --- a/doc/source/users/resources/network/index.rst +++ b/doc/source/users/resources/network/index.rst @@ -19,6 +19,7 @@ Network Resources v2/pool v2/pool_member v2/port + v2/qos_dscp_marking_rule v2/qos_minimum_bandwidth_rule v2/qos_policy v2/quota diff --git a/doc/source/users/resources/network/v2/qos_dscp_marking_rule.rst b/doc/source/users/resources/network/v2/qos_dscp_marking_rule.rst new file mode 100644 index 000000000..6d2cf9a45 --- /dev/null +++ b/doc/source/users/resources/network/v2/qos_dscp_marking_rule.rst @@ -0,0 +1,12 @@ +openstack.network.v2.qos_dscp_marking_rule +========================================== + +.. automodule:: openstack.network.v2.qos_dscp_marking_rule + +The QoSDSCPMarkingRule Class +---------------------------- + +The ``QoSDSCPMarkingRule`` class inherits from :class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.network.v2.qos_dscp_marking_rule.QoSDSCPMarkingRule + :members: diff --git a/openstack/network/v2/_proxy.py b/openstack/network/v2/_proxy.py index 2c20e0ba7..07915cbc3 100644 --- a/openstack/network/v2/_proxy.py +++ b/openstack/network/v2/_proxy.py @@ -25,6 +25,8 @@ from openstack.network.v2 import network_ip_availability from openstack.network.v2 import pool as _pool from openstack.network.v2 import pool_member as _pool_member from openstack.network.v2 import port as _port +from openstack.network.v2 import qos_dscp_marking_rule as \ + _qos_dscp_marking_rule from openstack.network.v2 import qos_minimum_bandwidth_rule as \ _qos_minimum_bandwidth_rule from openstack.network.v2 import qos_policy as _qos_policy @@ -1146,6 +1148,129 @@ class Proxy(proxy.BaseProxy): result.append(puerta) return result + def create_qos_dscp_marking_rule(self, qos_policy, **attrs): + """Create a new QoS DSCP marking rule + + :param dict attrs: Keyword arguments which will be used to create + a :class:`~openstack.network.v2. + qos_dscp_marking_rule.QoSDSCPMarkingRule`, + comprised of the properties on the + QosDscpMarkingRule class. + :param qos_policy: The value can be the ID of the QoS policy that the + rule belongs or a :class:`~openstack.network.v2. + qos_policy.QoSPolicy` instance. + + :returns: The results of router creation + :rtype: :class:`~openstack.network.v2.qos_dscp_marking_rule. + QoSDSCPMarkingRule` + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._create( + _qos_dscp_marking_rule.QoSDSCPMarkingRule, + path_args={'qos_policy_id': qos_policy_id}, **attrs) + + def delete_qos_dscp_marking_rule(self, qos_rule, qos_policy, + ignore_missing=True): + """Delete a QoS DSCP marking rule + + :param qos_rule: The value can be either the ID of a minimum bandwidth + rule or a :class:`~openstack.network.v2. + qos_dscp_marking_rule.QoSDSCPMarkingRule` + instance. + :param qos_policy: The value can be the ID of the QoS policy that the + rule belongs or a :class:`~openstack.network.v2. + qos_policy.QoSPolicy` instance. + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be + raised when the resource does not exist. + When set to ``True``, no exception will be set when + attempting to delete a nonexistent minimum bandwidth rule. + + :returns: ``None`` + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + self._delete(_qos_dscp_marking_rule.QoSDSCPMarkingRule, + qos_rule, ignore_missing=ignore_missing, + path_args={'qos_policy_id': qos_policy_id}) + + def find_qos_dscp_marking_rule(self, qos_rule_id, qos_policy, + ignore_missing=True): + """Find a QoS DSCP marking rule + + :param qos_rule_id: The ID of a QoS DSCP marking rule. + :param qos_policy: The value can be the ID of the QoS policy that the + rule belongs or a :class:`~openstack.network.v2. + qos_policy.QoSPolicy` instance. + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be + raised when the resource does not exist. + When set to ``True``, None will be returned when + attempting to find a nonexistent resource. + :returns: One :class:`~openstack.network.v2.qos_dscp_marking_rule. + QoSDSCPMarkingRule` or None + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._find(_qos_dscp_marking_rule.QoSDSCPMarkingRule, + qos_rule_id, ignore_missing=ignore_missing, + path_args={'qos_policy_id': qos_policy_id}) + + def get_qos_dscp_marking_rule(self, qos_rule, qos_policy): + """Get a single QoS DSCP marking rule + + :param qos_rule: The value can be the ID of a minimum bandwidth rule or + a :class:`~openstack.network.v2.qos_dscp_marking_rule. + QoSDSCPMarkingRule` instance. + :param qos_policy: The value can be the ID of the QoS policy that the + rule belongs or a :class:`~openstack.network.v2. + qos_policy.QoSPolicy` instance. + :returns: One :class:`~openstack.network.v2.qos_dscp_marking_rule. + QoSDSCPMarkingRule` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._get(_qos_dscp_marking_rule.QoSDSCPMarkingRule, + qos_rule, path_args={'qos_policy_id': qos_policy_id}) + + def qos_dscp_marking_rules(self, qos_policy, **query): + """Return a generator of QoS DSCP marking rules + + :param qos_policy: The value can be the ID of the QoS policy that the + rule belongs or a :class:`~openstack.network.v2. + qos_policy.QoSPolicy` instance. + :param kwargs \*\*query: Optional query parameters to be sent to limit + the resources being returned. + :returns: A generator of QoS DSCP marking rule objects + :rtype: :class:`~openstack.network.v2.qos_dscp_marking_rule. + QoSDSCPMarkingRule` + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._list(_qos_dscp_marking_rule.QoSDSCPMarkingRule, + paginated=False, + path_args={'qos_policy_id': qos_policy_id}, **query) + + def update_qos_dscp_marking_rule(self, qos_rule, qos_policy, **attrs): + """Update a QoS DSCP marking rule + + :param qos_rule: Either the id of a minimum bandwidth rule or a + :class:`~openstack.network.v2.qos_dscp_marking_rule. + QoSDSCPMarkingRule` instance. + :param qos_policy: The value can be the ID of the QoS policy that the + rule belongs or a :class:`~openstack.network.v2. + qos_policy.QoSPolicy` instance. + :attrs kwargs: The attributes to update on the QoS DSCP marking rule + represented by ``value``. + + :returns: The updated QoS DSCP marking rule + :rtype: :class:`~openstack.network.v2.qos_dscp_marking_rule. + QoSDSCPMarkingRule` + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._update(_qos_dscp_marking_rule.QoSDSCPMarkingRule, + qos_rule, + path_args={'qos_policy_id': qos_policy_id}, + **attrs) + def create_qos_minimum_bandwidth_rule(self, qos_policy, **attrs): """Create a new minimum bandwidth rule diff --git a/openstack/network/v2/qos_dscp_marking_rule.py b/openstack/network/v2/qos_dscp_marking_rule.py new file mode 100644 index 000000000..dfec1a67e --- /dev/null +++ b/openstack/network/v2/qos_dscp_marking_rule.py @@ -0,0 +1,44 @@ +# 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 openstack.network import network_service +from openstack import resource + + +class QoSDSCPMarkingRule(resource.Resource): + resource_key = 'dscp_marking_rule' + resources_key = 'dscp_marking_rules' + base_path = '/qos/policies/%(qos_policy_id)s/dscp_marking_rules' + service = network_service.NetworkService() + + # capabilities + allow_create = True + allow_retrieve = True + allow_update = True + allow_delete = True + allow_list = True + + # Properties + #: QoS DSCP marking rule id. + id = resource.prop('id') + #: The ID of the QoS policy who owns rule. + qos_policy_id = resource.prop('qos_policy_id') + #: DSCP mark field. + dscp_mark = resource.prop('dscp_mark') + + @classmethod + def _get_create_body(cls, attrs): + # Exclude qos_policy_id from attrs since it is not expected by QoS API. + if 'qos_policy_id' in attrs: + attrs.pop('qos_policy_id') + + return {cls.resource_key: attrs} diff --git a/openstack/tests/functional/network/v2/test_qos_dscp_marking_rule.py b/openstack/tests/functional/network/v2/test_qos_dscp_marking_rule.py new file mode 100644 index 000000000..3930587c0 --- /dev/null +++ b/openstack/tests/functional/network/v2/test_qos_dscp_marking_rule.py @@ -0,0 +1,81 @@ +# 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 uuid + +from openstack.network.v2 import (qos_dscp_marking_rule as + _qos_dscp_marking_rule) +from openstack.tests.functional import base + + +class TestQoSDSCPMarkingRule(base.BaseFunctionalTest): + + QOS_POLICY_ID = None + QOS_POLICY_NAME = uuid.uuid4().hex + QOS_IS_SHARED = False + QOS_POLICY_DESCRIPTION = "QoS policy description" + RULE_ID = uuid.uuid4().hex + RULE_DSCP_MARK = 36 + RULE_DSCP_MARK_NEW = 40 + + @classmethod + def setUpClass(cls): + super(TestQoSDSCPMarkingRule, cls).setUpClass() + qos_policy = cls.conn.network.create_qos_policy( + description=cls.QOS_POLICY_DESCRIPTION, + name=cls.QOS_POLICY_NAME, + shared=cls.QOS_IS_SHARED, + ) + cls.QOS_POLICY_ID = qos_policy.id + qos_rule = cls.conn.network.create_qos_dscp_marking_rule( + cls.QOS_POLICY_ID, dscp_mark=cls.RULE_DSCP_MARK, + ) + assert isinstance(qos_rule, _qos_dscp_marking_rule.QoSDSCPMarkingRule) + cls.assertIs(cls.RULE_DSCP_MARK, qos_rule.dscp_mark) + cls.RULE_ID = qos_rule.id + + @classmethod + def tearDownClass(cls): + rule = cls.conn.network.delete_qos_minimum_bandwidth_rule( + cls.RULE_ID, + cls.QOS_POLICY_ID) + qos_policy = cls.conn.network.delete_qos_policy(cls.QOS_POLICY_ID) + cls.assertIs(None, rule) + cls.assertIs(None, qos_policy) + + def test_find(self): + sot = self.conn.network.find_qos_dscp_marking_rule( + self.RULE_ID, + self.QOS_POLICY_ID) + self.assertEqual(self.RULE_ID, sot.id) + self.assertEqual(self.RULE_DSCP_MARK, sot.dscp_mark) + + def test_get(self): + sot = self.conn.network.get_qos_dscp_marking_rule( + self.RULE_ID, + self.QOS_POLICY_ID) + self.assertEqual(self.RULE_ID, sot.id) + self.assertEqual(self.QOS_POLICY_ID, sot.qos_policy_id) + self.assertEqual(self.RULE_DSCP_MARK, sot.dscp_mark) + + def test_list(self): + rule_ids = [o.id for o in + self.conn.network.qos_dscp_marking_rules( + self.QOS_POLICY_ID)] + self.assertIn(self.RULE_ID, rule_ids) + + def test_update(self): + sot = self.conn.network.update_qos_dscp_marking_rule( + self.RULE_ID, + self.QOS_POLICY_ID, + dscp_mark=self.RULE_DSCP_MARK_NEW) + self.assertEqual(self.RULE_DSCP_MARK_NEW, sot.dscp_mark) diff --git a/openstack/tests/unit/network/v2/test_proxy.py b/openstack/tests/unit/network/v2/test_proxy.py index fbd67d0bd..d70214aca 100644 --- a/openstack/tests/unit/network/v2/test_proxy.py +++ b/openstack/tests/unit/network/v2/test_proxy.py @@ -29,6 +29,7 @@ from openstack.network.v2 import network_ip_availability from openstack.network.v2 import pool from openstack.network.v2 import pool_member from openstack.network.v2 import port +from openstack.network.v2 import qos_dscp_marking_rule from openstack.network.v2 import qos_minimum_bandwidth_rule from openstack.network.v2 import qos_policy from openstack.network.v2 import quota @@ -389,6 +390,53 @@ class TestNetworkProxy(test_proxy_base.TestProxyBase): def test_port_update(self): self.verify_update(self.proxy.update_port, port.Port) + def test_qos_dscp_marking_rule_create_attrs(self): + self.verify_create( + self.proxy.create_qos_dscp_marking_rule, + qos_dscp_marking_rule.QoSDSCPMarkingRule, + method_kwargs={'qos_policy': QOS_POLICY_ID}, + expected_kwargs={'path_args': {'qos_policy_id': QOS_POLICY_ID}}) + + def test_qos_dscp_marking_rule_delete(self): + self.verify_delete( + self.proxy.delete_qos_dscp_marking_rule, + qos_dscp_marking_rule.QoSDSCPMarkingRule, + False, input_path_args=["resource_or_id", QOS_POLICY_ID], + expected_path_args={'qos_policy_id': QOS_POLICY_ID},) + + def test_qos_dscp_marking_rule_delete_ignore(self): + self.verify_delete( + self.proxy.delete_qos_dscp_marking_rule, + qos_dscp_marking_rule.QoSDSCPMarkingRule, + True, input_path_args=["resource_or_id", QOS_POLICY_ID], + expected_path_args={'qos_policy_id': QOS_POLICY_ID}, ) + + def test_qos_dscp_marking_rule_find(self): + self.verify_find(self.proxy.find_qos_dscp_marking_rule, + qos_dscp_marking_rule.QoSDSCPMarkingRule, + path_args={'qos_policy_id': QOS_POLICY_ID}) + + def test_qos_dscp_marking_rule_get(self): + self.verify_get( + self.proxy.get_qos_dscp_marking_rule, + qos_dscp_marking_rule.QoSDSCPMarkingRule, + method_kwargs={'qos_policy': QOS_POLICY_ID}, + expected_kwargs={'path_args': {'qos_policy_id': QOS_POLICY_ID}}) + + def test_qos_dscp_marking_rules(self): + self.verify_list( + self.proxy.qos_dscp_marking_rules, + qos_dscp_marking_rule.QoSDSCPMarkingRule, + paginated=False, + method_kwargs={'qos_policy': QOS_POLICY_ID}, + expected_kwargs={'path_args': {'qos_policy_id': QOS_POLICY_ID}}) + + def test_qos_dscp_marking_rule_update(self): + self.verify_update( + self.proxy.update_qos_dscp_marking_rule, + qos_dscp_marking_rule.QoSDSCPMarkingRule, + path_args={'qos_policy_id': QOS_POLICY_ID}) + def test_qos_minimum_bandwidth_rule_create_attrs(self): self.verify_create( self.proxy.create_qos_minimum_bandwidth_rule, diff --git a/openstack/tests/unit/network/v2/test_qos_dscp_marking_rule.py b/openstack/tests/unit/network/v2/test_qos_dscp_marking_rule.py new file mode 100644 index 000000000..49f216839 --- /dev/null +++ b/openstack/tests/unit/network/v2/test_qos_dscp_marking_rule.py @@ -0,0 +1,44 @@ +# 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 testtools +import uuid + +from openstack.network.v2 import qos_dscp_marking_rule + +EXAMPLE = { + 'id': 'IDENTIFIER', + 'qos_policy_id': 'qos-policy-' + uuid.uuid4().hex, + 'dscp_mark': 40, +} + + +class TestQoSDSCPMarkingRule(testtools.TestCase): + + def test_basic(self): + sot = qos_dscp_marking_rule.QoSDSCPMarkingRule() + self.assertEqual('dscp_marking_rule', sot.resource_key) + self.assertEqual('dscp_marking_rules', sot.resources_key) + self.assertEqual('/qos/policies/%(qos_policy_id)s/dscp_marking_rules', + sot.base_path) + self.assertEqual('network', sot.service.service_type) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_retrieve) + self.assertTrue(sot.allow_update) + self.assertTrue(sot.allow_delete) + self.assertTrue(sot.allow_list) + + def test_make_it(self): + sot = qos_dscp_marking_rule.QoSDSCPMarkingRule(EXAMPLE) + self.assertEqual(EXAMPLE['id'], sot.id) + self.assertEqual(EXAMPLE['qos_policy_id'], sot.qos_policy_id) + self.assertEqual(EXAMPLE['dscp_mark'], sot.dscp_mark)