From a7fd67507ced9cbb5cfd00ad8057199c0d9bcfbe Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Wed, 10 Aug 2016 16:59:42 +0100 Subject: [PATCH] Add QoS bandwidth limit rule object and CRUD commands. Closes-Bug: 1611830 Depends-On: Idf319cd182304952071bc976a2e56c42fbcb8468 Change-Id: I2ad5f09eebd3374f29b3d67887c542ec6ca60c81 --- doc/source/users/resources/network/index.rst | 1 + .../network/v2/qos_bandwidth_limit_rule.rst | 12 ++ openstack/network/v2/_proxy.py | 128 ++++++++++++++++++ .../network/v2/qos_bandwidth_limit_rule.py | 49 +++++++ .../v2/test_qos_bandwidth_limit_rule.py | 94 +++++++++++++ openstack/tests/unit/network/v2/test_proxy.py | 48 +++++++ .../v2/test_qos_bandwidth_limit_rule.py | 51 +++++++ 7 files changed, 383 insertions(+) create mode 100644 doc/source/users/resources/network/v2/qos_bandwidth_limit_rule.rst create mode 100644 openstack/network/v2/qos_bandwidth_limit_rule.py create mode 100644 openstack/tests/functional/network/v2/test_qos_bandwidth_limit_rule.py create mode 100644 openstack/tests/unit/network/v2/test_qos_bandwidth_limit_rule.py diff --git a/doc/source/users/resources/network/index.rst b/doc/source/users/resources/network/index.rst index a2bf9c278..19be0887e 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_bandwidth_limit_rule v2/qos_dscp_marking_rule v2/qos_minimum_bandwidth_rule v2/qos_policy diff --git a/doc/source/users/resources/network/v2/qos_bandwidth_limit_rule.rst b/doc/source/users/resources/network/v2/qos_bandwidth_limit_rule.rst new file mode 100644 index 000000000..115a55de5 --- /dev/null +++ b/doc/source/users/resources/network/v2/qos_bandwidth_limit_rule.rst @@ -0,0 +1,12 @@ +openstack.network.v2.qos_bandwidth_limit_rule +============================================= + +.. automodule:: openstack.network.v2.qos_bandwidth_limit_rule + +The QoSBandwidthLimitRule Class +------------------------------- + +The ``QoSBandwidthLimitRule`` class inherits from :class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.network.v2.qos_bandwidth_limit_rule.QoSBandwidthLimitRule + :members: diff --git a/openstack/network/v2/_proxy.py b/openstack/network/v2/_proxy.py index 07915cbc3..a6e65fccb 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_bandwidth_limit_rule as \ + _qos_bandwidth_limit_rule from openstack.network.v2 import qos_dscp_marking_rule as \ _qos_dscp_marking_rule from openstack.network.v2 import qos_minimum_bandwidth_rule as \ @@ -1148,6 +1150,132 @@ class Proxy(proxy.BaseProxy): result.append(puerta) return result + def create_qos_bandwidth_limit_rule(self, qos_policy, **attrs): + """Create a new bandwidth limit rule + + :param dict attrs: Keyword arguments which will be used to create + a :class:`~openstack.network.v2. + qos_bandwidth_limit_rule.QoSBandwidthLimitRule`, + comprised of the properties on the + QoSBandwidthLimitRule 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 resource creation + :rtype: :class:`~openstack.network.v2.qos_bandwidth_limit_rule. + QoSBandwidthLimitRule` + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._create( + _qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + path_args={'qos_policy_id': qos_policy_id}, **attrs) + + def delete_qos_bandwidth_limit_rule(self, qos_rule, qos_policy, + ignore_missing=True): + """Delete a bandwidth limit rule + + :param qos_rule: The value can be either the ID of a bandwidth limit + rule or a :class:`~openstack.network.v2. + qos_bandwidth_limit_rule.QoSBandwidthLimitRule` + 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 bandwidth limit rule. + + :returns: ``None`` + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + self._delete(_qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + qos_rule, ignore_missing=ignore_missing, + path_args={'qos_policy_id': qos_policy_id}) + + def find_qos_bandwidth_limit_rule(self, qos_rule_id, qos_policy, + ignore_missing=True): + """Find a bandwidth limit rule + + :param qos_rule_id: The ID of a bandwidth limit 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_bandwidth_limit_rule. + QoSBandwidthLimitRule` or None + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._find(_qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + qos_rule_id, ignore_missing=ignore_missing, + path_args={'qos_policy_id': qos_policy_id}) + + def get_qos_bandwidth_limit_rule(self, qos_rule, qos_policy): + """Get a single bandwidth limit rule + + :param qos_rule: The value can be the ID of a minimum bandwidth rule or + a :class:`~openstack.network.v2. + qos_bandwidth_limit_rule.QoSBandwidthLimitRule` + 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_bandwidth_limit_rule. + QoSBandwidthLimitRule` + :raises: :class:`~openstack.exceptions.ResourceNotFound` + when no resource can be found. + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._get(_qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + qos_rule, path_args={'qos_policy_id': qos_policy_id}) + + def qos_bandwidth_limit_rules(self, qos_policy, **query): + """Return a generator of bandwidth limit 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 bandwidth limit rule objects + :rtype: :class:`~openstack.network.v2.qos_bandwidth_limit_rule. + QoSBandwidthLimitRule` + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._list(_qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + paginated=False, + path_args={'qos_policy_id': qos_policy_id}, **query) + + def update_qos_bandwidth_limit_rule(self, qos_rule, qos_policy, + **attrs): + """Update a bandwidth limit rule + + :param qos_rule: Either the id of a bandwidth limit rule or a + :class:`~openstack.network.v2. + qos_bandwidth_limit_rule.QoSBandwidthLimitRule` + 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 bandwidth limit rule + represented by ``value``. + + :returns: The updated minimum bandwidth rule + :rtype: :class:`~openstack.network.v2.qos_bandwidth_limit_rule. + QoSBandwidthLimitRule` + """ + qos_policy_id = resource.Resource.get_id(qos_policy) + return self._update(_qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + qos_rule, + path_args={'qos_policy_id': qos_policy_id}, + **attrs) + def create_qos_dscp_marking_rule(self, qos_policy, **attrs): """Create a new QoS DSCP marking rule diff --git a/openstack/network/v2/qos_bandwidth_limit_rule.py b/openstack/network/v2/qos_bandwidth_limit_rule.py new file mode 100644 index 000000000..059cbc141 --- /dev/null +++ b/openstack/network/v2/qos_bandwidth_limit_rule.py @@ -0,0 +1,49 @@ +# 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 QoSBandwidthLimitRule(resource.Resource): + resource_key = 'bandwidth_limit_rule' + resources_key = 'bandwidth_limit_rules' + base_path = '/qos/policies/%(qos_policy_id)s/bandwidth_limit_rules' + service = network_service.NetworkService() + + # capabilities + allow_create = True + allow_retrieve = True + allow_update = True + allow_delete = True + allow_list = True + + # Properties + #: QoS bandwidth limit rule id. + id = resource.prop('id') + #: The ID of the QoS policy who owns rule. + qos_policy_id = resource.prop('qos_policy_id') + #: Maximum bandwidth in kbps. + max_kbps = resource.prop('max_kbps') + #: Maximum burst bandwidth in kbps. + max_burst_kbps = resource.prop('max_burst_kbps') + # NOTE(ralonsoh): to be implemented in bug 1560961 + #: Traffic direction from the tenant point of view ('egress', 'ingress'). + # direction = resource.prop('direction') + + @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_bandwidth_limit_rule.py b/openstack/tests/functional/network/v2/test_qos_bandwidth_limit_rule.py new file mode 100644 index 000000000..84e7aee86 --- /dev/null +++ b/openstack/tests/functional/network/v2/test_qos_bandwidth_limit_rule.py @@ -0,0 +1,94 @@ +# 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_bandwidth_limit_rule as + _qos_bandwidth_limit_rule) +from openstack.tests.functional import base + + +class TestQoSBandwidthLimitRule(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_MAX_KBPS = 1500 + RULE_MAX_KBPS_NEW = 1800 + RULE_MAX_BURST_KBPS = 1100 + RULE_MAX_BURST_KBPS_NEW = 1300 + # NOTE(ralonsoh): to be implemented in bug 1560961. + # New checks must be added. + # RULE_DIRECTION = 'egress' + # RULE_DIRECTION_NEW = 'ingress' + + @classmethod + def setUpClass(cls): + super(TestQoSBandwidthLimitRule, 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_bandwidth_limit_rule( + cls.QOS_POLICY_ID, max_kbps=cls.RULE_MAX_KBPS, + max_burst_kbps=cls.RULE_MAX_BURST_KBPS, + ) + assert isinstance(qos_rule, + _qos_bandwidth_limit_rule.QoSBandwidthLimitRule) + cls.assertIs(cls.RULE_MAX_KBPS, qos_rule.max_kbps) + cls.assertIs(cls.RULE_MAX_BURST_KBPS, qos_rule.max_burst_kbps) + 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_bandwidth_limit_rule( + self.RULE_ID, + self.QOS_POLICY_ID) + self.assertEqual(self.RULE_ID, sot.id) + self.assertEqual(self.RULE_MAX_KBPS, sot.max_kbps) + self.assertEqual(self.RULE_MAX_BURST_KBPS, sot.max_burst_kbps) + + def test_get(self): + sot = self.conn.network.get_qos_bandwidth_limit_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_MAX_KBPS, sot.max_kbps) + self.assertEqual(self.RULE_MAX_BURST_KBPS, sot.max_burst_kbps) + + def test_list(self): + rule_ids = [o.id for o in + self.conn.network.qos_bandwidth_limit_rules( + self.QOS_POLICY_ID)] + self.assertIn(self.RULE_ID, rule_ids) + + def test_update(self): + sot = self.conn.network.update_qos_bandwidth_limit_rule( + self.RULE_ID, + self.QOS_POLICY_ID, + max_kbps=self.RULE_MAX_KBPS_NEW, + max_burst_kbps=self.RULE_MAX_BURST_KBPS_NEW) + self.assertEqual(self.RULE_MAX_KBPS_NEW, sot.max_kbps) + self.assertEqual(self.RULE_MAX_BURST_KBPS_NEW, sot.max_burst_kbps) diff --git a/openstack/tests/unit/network/v2/test_proxy.py b/openstack/tests/unit/network/v2/test_proxy.py index d70214aca..8ed4b3aba 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_bandwidth_limit_rule 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 @@ -390,6 +391,53 @@ class TestNetworkProxy(test_proxy_base.TestProxyBase): def test_port_update(self): self.verify_update(self.proxy.update_port, port.Port) + def test_qos_bandwidth_limit_rule_create_attrs(self): + self.verify_create( + self.proxy.create_qos_bandwidth_limit_rule, + qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + method_kwargs={'qos_policy': QOS_POLICY_ID}, + expected_kwargs={'path_args': {'qos_policy_id': QOS_POLICY_ID}}) + + def test_qos_bandwidth_limit_rule_delete(self): + self.verify_delete( + self.proxy.delete_qos_bandwidth_limit_rule, + qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + False, input_path_args=["resource_or_id", QOS_POLICY_ID], + expected_path_args={'qos_policy_id': QOS_POLICY_ID},) + + def test_qos_bandwidth_limit_rule_delete_ignore(self): + self.verify_delete( + self.proxy.delete_qos_bandwidth_limit_rule, + qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + True, input_path_args=["resource_or_id", QOS_POLICY_ID], + expected_path_args={'qos_policy_id': QOS_POLICY_ID}, ) + + def test_qos_bandwidth_limit_rule_find(self): + self.verify_find(self.proxy.find_qos_bandwidth_limit_rule, + qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + path_args={'qos_policy_id': QOS_POLICY_ID}) + + def test_qos_bandwidth_limit_rule_get(self): + self.verify_get( + self.proxy.get_qos_bandwidth_limit_rule, + qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + method_kwargs={'qos_policy': QOS_POLICY_ID}, + expected_kwargs={'path_args': {'qos_policy_id': QOS_POLICY_ID}}) + + def test_qos_bandwidth_limit_rules(self): + self.verify_list( + self.proxy.qos_bandwidth_limit_rules, + qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + paginated=False, + method_kwargs={'qos_policy': QOS_POLICY_ID}, + expected_kwargs={'path_args': {'qos_policy_id': QOS_POLICY_ID}}) + + def test_qos_bandwidth_limit_rule_update(self): + self.verify_update( + self.proxy.update_qos_bandwidth_limit_rule, + qos_bandwidth_limit_rule.QoSBandwidthLimitRule, + path_args={'qos_policy_id': QOS_POLICY_ID}) + def test_qos_dscp_marking_rule_create_attrs(self): self.verify_create( self.proxy.create_qos_dscp_marking_rule, diff --git a/openstack/tests/unit/network/v2/test_qos_bandwidth_limit_rule.py b/openstack/tests/unit/network/v2/test_qos_bandwidth_limit_rule.py new file mode 100644 index 000000000..5af9b173b --- /dev/null +++ b/openstack/tests/unit/network/v2/test_qos_bandwidth_limit_rule.py @@ -0,0 +1,51 @@ +# 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_bandwidth_limit_rule + +EXAMPLE = { + 'id': 'IDENTIFIER', + 'qos_policy_id': 'qos-policy-' + uuid.uuid4().hex, + 'max_kbps': 1500, + 'max_burst_kbps': 1200, + # NOTE(ralonsoh): to be implemented in bug 1560961 + # 'direction': 'egress', +} + + +class TestQoSBandwidthLimitRule(testtools.TestCase): + + def test_basic(self): + sot = qos_bandwidth_limit_rule.QoSBandwidthLimitRule() + self.assertEqual('bandwidth_limit_rule', sot.resource_key) + self.assertEqual('bandwidth_limit_rules', sot.resources_key) + self.assertEqual( + '/qos/policies/%(qos_policy_id)s/bandwidth_limit_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_bandwidth_limit_rule.QoSBandwidthLimitRule(EXAMPLE) + self.assertEqual(EXAMPLE['id'], sot.id) + self.assertEqual(EXAMPLE['qos_policy_id'], sot.qos_policy_id) + self.assertEqual(EXAMPLE['max_kbps'], sot.max_kbps) + self.assertEqual(EXAMPLE['max_burst_kbps'], sot.max_burst_kbps) + # NOTE(ralonsoh): to be implemented in bug 1560961 + # self.assertEqual(EXAMPLE['direction'], sot.direction)