Add QoS egress minimum bandwidth rule to neutronclient
The following patch implements the QoS egress minimum bandwidth assurance in neutronclient. Change-Id: I025522f73a9a8e3a9f69f097cedaeba330b9914a Depends-On: I6b619a96a2bfde164646c71409b671352bc6ce7d Depends-On: I13c54be22f35ac7eb5835d8424a919d0b61a8e95 Partial-Bug: #1560963
This commit is contained in:

committed by
Ihar Hrachyshka

parent
25e4314e8b
commit
a6cdd1dace
111
neutronclient/neutron/v2_0/qos/minimum_bandwidth_rule.py
Normal file
111
neutronclient/neutron/v2_0/qos/minimum_bandwidth_rule.py
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# Copyright (c) 2016 Intel Corporation.
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# 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 neutronclient._i18n import _
|
||||||
|
from neutronclient.common import utils
|
||||||
|
from neutronclient.neutron import v2_0 as neutronv20
|
||||||
|
from neutronclient.neutron.v2_0.qos import rule as qos_rule
|
||||||
|
|
||||||
|
|
||||||
|
MINIMUM_BANDWIDTH_RULE_RESOURCE = 'minimum_bandwidth_rule'
|
||||||
|
|
||||||
|
|
||||||
|
def add_minimum_bandwidth_arguments(parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'--min-kbps',
|
||||||
|
required=True,
|
||||||
|
type=str,
|
||||||
|
help=_('QoS minimum bandwidth assurance, expressed in kilobits '
|
||||||
|
'per second.'))
|
||||||
|
# NOTE(ralonsoh): the only direction implemented is "egress". Please,
|
||||||
|
# refer to the spec (https://review.openstack.org/#/c/316082/).
|
||||||
|
parser.add_argument(
|
||||||
|
'--direction',
|
||||||
|
# NOTE(ihrachys): though server picks the default for us (egress), it's
|
||||||
|
# better to require the argument to make the UI more explicit and the
|
||||||
|
# intentions more clear in the future when we add other values for the
|
||||||
|
# attribute on server side.
|
||||||
|
required=True,
|
||||||
|
type=utils.convert_to_lowercase,
|
||||||
|
choices=['egress'],
|
||||||
|
help=_('Traffic direction.'))
|
||||||
|
|
||||||
|
|
||||||
|
def update_minimum_bandwidth_args2body(parsed_args, body):
|
||||||
|
neutronv20.update_dict(parsed_args, body, ['min_kbps', 'direction'])
|
||||||
|
|
||||||
|
|
||||||
|
class CreateQoSMinimumBandwidthRule(qos_rule.QosRuleMixin,
|
||||||
|
neutronv20.CreateCommand):
|
||||||
|
"""Create a qos minimum bandwidth rule."""
|
||||||
|
|
||||||
|
resource = MINIMUM_BANDWIDTH_RULE_RESOURCE
|
||||||
|
|
||||||
|
def add_known_arguments(self, parser):
|
||||||
|
super(CreateQoSMinimumBandwidthRule, self).add_known_arguments(
|
||||||
|
parser)
|
||||||
|
add_minimum_bandwidth_arguments(parser)
|
||||||
|
|
||||||
|
def args2body(self, parsed_args):
|
||||||
|
body = {}
|
||||||
|
update_minimum_bandwidth_args2body(parsed_args, body)
|
||||||
|
return {self.resource: body}
|
||||||
|
|
||||||
|
|
||||||
|
class ListQoSMinimumBandwidthRules(qos_rule.QosRuleMixin,
|
||||||
|
neutronv20.ListCommand):
|
||||||
|
"""List all qos minimum bandwidth rules belonging to the specified policy.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
resource = MINIMUM_BANDWIDTH_RULE_RESOURCE
|
||||||
|
_formatters = {}
|
||||||
|
pagination_support = True
|
||||||
|
sorting_support = True
|
||||||
|
|
||||||
|
|
||||||
|
class ShowQoSMinimumBandwidthRule(qos_rule.QosRuleMixin,
|
||||||
|
neutronv20.ShowCommand):
|
||||||
|
"""Show information about the given qos minimum bandwidth rule."""
|
||||||
|
|
||||||
|
resource = MINIMUM_BANDWIDTH_RULE_RESOURCE
|
||||||
|
allow_names = False
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateQoSMinimumBandwidthRule(qos_rule.QosRuleMixin,
|
||||||
|
neutronv20.UpdateCommand):
|
||||||
|
"""Update the given qos minimum bandwidth rule."""
|
||||||
|
|
||||||
|
resource = MINIMUM_BANDWIDTH_RULE_RESOURCE
|
||||||
|
allow_names = False
|
||||||
|
|
||||||
|
def add_known_arguments(self, parser):
|
||||||
|
super(UpdateQoSMinimumBandwidthRule, self).add_known_arguments(
|
||||||
|
parser)
|
||||||
|
add_minimum_bandwidth_arguments(parser)
|
||||||
|
|
||||||
|
def args2body(self, parsed_args):
|
||||||
|
body = {}
|
||||||
|
update_minimum_bandwidth_args2body(parsed_args, body)
|
||||||
|
return {self.resource: body}
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteQoSMinimumBandwidthRule(qos_rule.QosRuleMixin,
|
||||||
|
neutronv20.DeleteCommand):
|
||||||
|
"""Delete a given qos minimum bandwidth rule."""
|
||||||
|
|
||||||
|
resource = MINIMUM_BANDWIDTH_RULE_RESOURCE
|
||||||
|
allow_names = False
|
@@ -73,6 +73,7 @@ from neutronclient.neutron.v2_0 import port
|
|||||||
from neutronclient.neutron.v2_0 import purge
|
from neutronclient.neutron.v2_0 import purge
|
||||||
from neutronclient.neutron.v2_0.qos import bandwidth_limit_rule
|
from neutronclient.neutron.v2_0.qos import bandwidth_limit_rule
|
||||||
from neutronclient.neutron.v2_0.qos import dscp_marking_rule
|
from neutronclient.neutron.v2_0.qos import dscp_marking_rule
|
||||||
|
from neutronclient.neutron.v2_0.qos import minimum_bandwidth_rule
|
||||||
from neutronclient.neutron.v2_0.qos import policy as qos_policy
|
from neutronclient.neutron.v2_0.qos import policy as qos_policy
|
||||||
from neutronclient.neutron.v2_0.qos import rule as qos_rule
|
from neutronclient.neutron.v2_0.qos import rule as qos_rule
|
||||||
from neutronclient.neutron.v2_0 import quota
|
from neutronclient.neutron.v2_0 import quota
|
||||||
@@ -397,6 +398,21 @@ COMMAND_V2 = {
|
|||||||
'qos-dscp-marking-rule-delete': (
|
'qos-dscp-marking-rule-delete': (
|
||||||
dscp_marking_rule.DeleteQoSDscpMarkingRule
|
dscp_marking_rule.DeleteQoSDscpMarkingRule
|
||||||
),
|
),
|
||||||
|
'qos-minimum-bandwidth-rule-create': (
|
||||||
|
minimum_bandwidth_rule.CreateQoSMinimumBandwidthRule
|
||||||
|
),
|
||||||
|
'qos-minimum-bandwidth-rule-show': (
|
||||||
|
minimum_bandwidth_rule.ShowQoSMinimumBandwidthRule
|
||||||
|
),
|
||||||
|
'qos-minimum-bandwidth-rule-list': (
|
||||||
|
minimum_bandwidth_rule.ListQoSMinimumBandwidthRules
|
||||||
|
),
|
||||||
|
'qos-minimum-bandwidth-rule-update': (
|
||||||
|
minimum_bandwidth_rule.UpdateQoSMinimumBandwidthRule
|
||||||
|
),
|
||||||
|
'qos-minimum-bandwidth-rule-delete': (
|
||||||
|
minimum_bandwidth_rule.DeleteQoSMinimumBandwidthRule
|
||||||
|
),
|
||||||
'qos-available-rule-types': qos_rule.ListQoSRuleTypes,
|
'qos-available-rule-types': qos_rule.ListQoSRuleTypes,
|
||||||
'flavor-list': flavor.ListFlavor,
|
'flavor-list': flavor.ListFlavor,
|
||||||
'flavor-show': flavor.ShowFlavor,
|
'flavor-show': flavor.ShowFlavor,
|
||||||
|
@@ -0,0 +1,142 @@
|
|||||||
|
# Copyright (c) 2016 Intel Corporation.
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# 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 sys
|
||||||
|
|
||||||
|
from neutronclient.neutron.v2_0.qos import minimum_bandwidth_rule as bw_rule
|
||||||
|
from neutronclient.tests.unit import test_cli20
|
||||||
|
|
||||||
|
|
||||||
|
class CLITestV20QoSMinimumBandwidthRuleJSON(test_cli20.CLITestV20Base):
|
||||||
|
|
||||||
|
non_admin_status_resources = ['minimum_bandwidth_rule']
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(CLITestV20QoSMinimumBandwidthRuleJSON, self).setUp()
|
||||||
|
self.res = 'minimum_bandwidth_rule'
|
||||||
|
self.cmd_res = 'qos_minimum_bandwidth_rule'
|
||||||
|
self.ress = self.res + 's'
|
||||||
|
self.cmd_ress = self.cmd_res + 's'
|
||||||
|
|
||||||
|
def test_create_minimum_bandwidth_rule_min_kbps_only(self):
|
||||||
|
cmd = bw_rule.CreateQoSMinimumBandwidthRule(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
my_id = 'my-id'
|
||||||
|
min_kbps = '1500'
|
||||||
|
policy_id = 'policy_id'
|
||||||
|
args = ['--min-kbps', min_kbps,
|
||||||
|
policy_id]
|
||||||
|
position_names = ['min_kbps']
|
||||||
|
position_values = [min_kbps]
|
||||||
|
self.assertRaises(SystemExit, self._test_create_resource,
|
||||||
|
self.res, cmd, '', my_id, args,
|
||||||
|
position_names, position_values,
|
||||||
|
cmd_resource=self.cmd_res,
|
||||||
|
parent_id=policy_id,
|
||||||
|
no_api_call=True)
|
||||||
|
|
||||||
|
def test_create_minimum_bandwidth_rule_direction_only(self):
|
||||||
|
cmd = bw_rule.CreateQoSMinimumBandwidthRule(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
my_id = 'my-id'
|
||||||
|
direction = 'egress'
|
||||||
|
policy_id = 'policy_id'
|
||||||
|
args = ['--direction', direction,
|
||||||
|
policy_id]
|
||||||
|
position_names = ['direction']
|
||||||
|
position_values = [direction]
|
||||||
|
self.assertRaises(SystemExit, self._test_create_resource,
|
||||||
|
self.res, cmd, '', my_id, args,
|
||||||
|
position_names, position_values,
|
||||||
|
cmd_resource=self.cmd_res,
|
||||||
|
parent_id=policy_id,
|
||||||
|
no_api_call=True)
|
||||||
|
|
||||||
|
def test_create_minimum_bandwidth_rule_none(self):
|
||||||
|
cmd = bw_rule.CreateQoSMinimumBandwidthRule(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
my_id = 'my-id'
|
||||||
|
policy_id = 'policy_id'
|
||||||
|
args = [policy_id]
|
||||||
|
position_names = []
|
||||||
|
position_values = []
|
||||||
|
self.assertRaises(SystemExit, self._test_create_resource,
|
||||||
|
self.res, cmd, '', my_id, args,
|
||||||
|
position_names, position_values,
|
||||||
|
cmd_resource=self.cmd_res,
|
||||||
|
parent_id=policy_id,
|
||||||
|
no_api_call=True)
|
||||||
|
|
||||||
|
def test_create_minimum_bandwidth_rule_all(self):
|
||||||
|
cmd = bw_rule.CreateQoSMinimumBandwidthRule(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
my_id = 'my-id'
|
||||||
|
min_kbps = '1500'
|
||||||
|
direction = 'egress'
|
||||||
|
policy_id = 'policy_id'
|
||||||
|
args = ['--min-kbps', min_kbps,
|
||||||
|
'--direction', direction,
|
||||||
|
policy_id]
|
||||||
|
position_names = ['direction', 'min_kbps']
|
||||||
|
position_values = [direction, min_kbps]
|
||||||
|
self._test_create_resource(self.res, cmd, '', my_id, args,
|
||||||
|
position_names, position_values,
|
||||||
|
cmd_resource=self.cmd_res,
|
||||||
|
parent_id=policy_id)
|
||||||
|
|
||||||
|
def test_update_minimum_bandwidth_rule(self):
|
||||||
|
cmd = bw_rule.UpdateQoSMinimumBandwidthRule(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
my_id = 'my-id'
|
||||||
|
min_kbps = '1200'
|
||||||
|
direction = 'egress'
|
||||||
|
policy_id = 'policy_id'
|
||||||
|
args = ['--min-kbps', min_kbps,
|
||||||
|
'--direction', direction,
|
||||||
|
my_id, policy_id]
|
||||||
|
self._test_update_resource(self.res, cmd, my_id, args,
|
||||||
|
{'min_kbps': min_kbps,
|
||||||
|
'direction': direction},
|
||||||
|
cmd_resource=self.cmd_res,
|
||||||
|
parent_id=policy_id)
|
||||||
|
|
||||||
|
def test_delete_minimum_bandwidth_rule(self):
|
||||||
|
cmd = bw_rule.DeleteQoSMinimumBandwidthRule(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
my_id = 'my-id'
|
||||||
|
policy_id = 'policy_id'
|
||||||
|
args = [my_id, policy_id]
|
||||||
|
self._test_delete_resource(self.res, cmd, my_id, args,
|
||||||
|
cmd_resource=self.cmd_res,
|
||||||
|
parent_id=policy_id)
|
||||||
|
|
||||||
|
def test_show_minimum_bandwidth_rule(self):
|
||||||
|
cmd = bw_rule.ShowQoSMinimumBandwidthRule(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
policy_id = 'policy_id'
|
||||||
|
args = [self.test_id, policy_id]
|
||||||
|
self._test_show_resource(self.res, cmd, self.test_id, args,
|
||||||
|
[], cmd_resource=self.cmd_res,
|
||||||
|
parent_id=policy_id)
|
||||||
|
|
||||||
|
def test_list_minimum_bandwidth_rule(self):
|
||||||
|
cmd = bw_rule.ListQoSMinimumBandwidthRules(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
policy_id = 'policy_id'
|
||||||
|
args = [policy_id]
|
||||||
|
contents = [{'name': 'rule1', 'min-kbps': 1000, 'direction': 'egress'}]
|
||||||
|
self._test_list_resources(self.cmd_ress, cmd, parent_id=policy_id,
|
||||||
|
base_args=args, response_contents=contents)
|
@@ -22,7 +22,9 @@ from neutronclient.tests.unit import test_cli20
|
|||||||
|
|
||||||
class CLITestV20QoSRuleJSON(test_cli20.CLITestV20Base):
|
class CLITestV20QoSRuleJSON(test_cli20.CLITestV20Base):
|
||||||
|
|
||||||
non_admin_status_resources = ['bandwidth_limit_rule', 'dscp_marking_rule']
|
non_admin_status_resources = ['bandwidth_limit_rule',
|
||||||
|
'dscp_marking_rule',
|
||||||
|
'minimum_bandwidth_rule']
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(CLITestV20QoSRuleJSON, self).setUp()
|
super(CLITestV20QoSRuleJSON, self).setUp()
|
||||||
@@ -32,7 +34,8 @@ class CLITestV20QoSRuleJSON(test_cli20.CLITestV20Base):
|
|||||||
resources = 'rule_types'
|
resources = 'rule_types'
|
||||||
cmd_resources = 'qos_rule_types'
|
cmd_resources = 'qos_rule_types'
|
||||||
response_contents = [{'type': 'bandwidth_limit',
|
response_contents = [{'type': 'bandwidth_limit',
|
||||||
'type': 'dscp_marking'}]
|
'type': 'dscp_marking',
|
||||||
|
'type': 'minimum_bandwidth'}]
|
||||||
|
|
||||||
cmd = qos_rule.ListQoSRuleTypes(test_cli20.MyApp(sys.stdout),
|
cmd = qos_rule.ListQoSRuleTypes(test_cli20.MyApp(sys.stdout),
|
||||||
None)
|
None)
|
||||||
|
@@ -595,6 +595,10 @@ class Client(ClientBase):
|
|||||||
qos_bandwidth_limit_rule_path = "/qos/policies/%s/bandwidth_limit_rules/%s"
|
qos_bandwidth_limit_rule_path = "/qos/policies/%s/bandwidth_limit_rules/%s"
|
||||||
qos_dscp_marking_rules_path = "/qos/policies/%s/dscp_marking_rules"
|
qos_dscp_marking_rules_path = "/qos/policies/%s/dscp_marking_rules"
|
||||||
qos_dscp_marking_rule_path = "/qos/policies/%s/dscp_marking_rules/%s"
|
qos_dscp_marking_rule_path = "/qos/policies/%s/dscp_marking_rules/%s"
|
||||||
|
qos_minimum_bandwidth_rules_path = \
|
||||||
|
"/qos/policies/%s/minimum_bandwidth_rules"
|
||||||
|
qos_minimum_bandwidth_rule_path = \
|
||||||
|
"/qos/policies/%s/minimum_bandwidth_rules/%s"
|
||||||
qos_rule_types_path = "/qos/rule-types"
|
qos_rule_types_path = "/qos/rule-types"
|
||||||
qos_rule_type_path = "/qos/rule-types/%s"
|
qos_rule_type_path = "/qos/rule-types/%s"
|
||||||
flavors_path = "/flavors"
|
flavors_path = "/flavors"
|
||||||
@@ -660,6 +664,7 @@ class Client(ClientBase):
|
|||||||
'qos_policies': 'qos_policy',
|
'qos_policies': 'qos_policy',
|
||||||
'policies': 'policy',
|
'policies': 'policy',
|
||||||
'bandwidth_limit_rules': 'bandwidth_limit_rule',
|
'bandwidth_limit_rules': 'bandwidth_limit_rule',
|
||||||
|
'minimum_bandwidth_rules': 'minimum_bandwidth_rule',
|
||||||
'rules': 'rule',
|
'rules': 'rule',
|
||||||
'dscp_marking_rules': 'dscp_marking_rule',
|
'dscp_marking_rules': 'dscp_marking_rule',
|
||||||
'rule_types': 'rule_type',
|
'rule_types': 'rule_type',
|
||||||
@@ -1740,6 +1745,35 @@ class Client(ClientBase):
|
|||||||
return self.delete(self.qos_dscp_marking_rule_path %
|
return self.delete(self.qos_dscp_marking_rule_path %
|
||||||
(policy, rule))
|
(policy, rule))
|
||||||
|
|
||||||
|
def list_minimum_bandwidth_rules(self, policy_id, retrieve_all=True,
|
||||||
|
**_params):
|
||||||
|
"""Fetches a list of all minimum bandwidth rules for the given policy.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.list('qos_minimum_bandwidth_rules',
|
||||||
|
self.qos_minimum_bandwidth_rules_path %
|
||||||
|
policy_id, retrieve_all, **_params)
|
||||||
|
|
||||||
|
def show_minimum_bandwidth_rule(self, rule, policy, body=None):
|
||||||
|
"""Fetches information of a certain minimum bandwidth rule."""
|
||||||
|
return self.get(self.qos_minimum_bandwidth_rule_path %
|
||||||
|
(policy, rule), body=body)
|
||||||
|
|
||||||
|
def create_minimum_bandwidth_rule(self, policy, body=None):
|
||||||
|
"""Creates a new minimum bandwidth rule."""
|
||||||
|
return self.post(self.qos_minimum_bandwidth_rules_path % policy,
|
||||||
|
body=body)
|
||||||
|
|
||||||
|
def update_minimum_bandwidth_rule(self, rule, policy, body=None):
|
||||||
|
"""Updates a minimum bandwidth rule."""
|
||||||
|
return self.put(self.qos_minimum_bandwidth_rule_path %
|
||||||
|
(policy, rule), body=body)
|
||||||
|
|
||||||
|
def delete_minimum_bandwidth_rule(self, rule, policy):
|
||||||
|
"""Deletes a minimum bandwidth rule."""
|
||||||
|
return self.delete(self.qos_minimum_bandwidth_rule_path %
|
||||||
|
(policy, rule))
|
||||||
|
|
||||||
def create_flavor(self, body=None):
|
def create_flavor(self, body=None):
|
||||||
"""Creates a new Neutron service flavor."""
|
"""Creates a new Neutron service flavor."""
|
||||||
return self.post(self.flavors_path, body=body)
|
return self.post(self.flavors_path, body=body)
|
||||||
|
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- New create, update, list, show, and delete commands are added for the QoS
|
||||||
|
minimum bandwidth rule.
|
Reference in New Issue
Block a user