Skip to content

Commit 6ccbcdd

Browse files
pszczerbikosfrickler
authored andcommitted
Add support for CRUD operations for QoS minimum packet rate rule
Closes-Bug: #1922237 Depends-On: https://review.opendev.org/c/openstack/openstacksdk/+/810364 See-Also: https://review.opendev.org/785236 Change-Id: Ie7e1eb0575fd37121d5097ecbc318d0769ab3db0
1 parent 9eea28b commit 6ccbcdd

File tree

5 files changed

+436
-12
lines changed

5 files changed

+436
-12
lines changed

openstackclient/network/v2/network_qos_rule.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@
2525
RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth-limit'
2626
RULE_TYPE_DSCP_MARKING = 'dscp-marking'
2727
RULE_TYPE_MINIMUM_BANDWIDTH = 'minimum-bandwidth'
28+
RULE_TYPE_MINIMUM_PACKET_RATE = 'minimum-packet-rate'
2829
MANDATORY_PARAMETERS = {
2930
RULE_TYPE_MINIMUM_BANDWIDTH: {'min_kbps', 'direction'},
31+
RULE_TYPE_MINIMUM_PACKET_RATE: {'min_kpps', 'direction'},
3032
RULE_TYPE_DSCP_MARKING: {'dscp_mark'},
3133
RULE_TYPE_BANDWIDTH_LIMIT: {'max_kbps'}}
3234
OPTIONAL_PARAMETERS = {
3335
RULE_TYPE_MINIMUM_BANDWIDTH: set(),
36+
RULE_TYPE_MINIMUM_PACKET_RATE: set(),
3437
RULE_TYPE_DSCP_MARKING: set(),
3538
RULE_TYPE_BANDWIDTH_LIMIT: {'direction', 'max_burst_kbps'}}
3639
DIRECTION_EGRESS = 'egress'
3740
DIRECTION_INGRESS = 'ingress'
41+
DIRECTION_ANY = 'any'
3842
DSCP_VALID_MARKS = [0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
3943
34, 36, 38, 40, 46, 48, 56]
4044

@@ -98,10 +102,20 @@ def _get_attrs(network_client, parsed_args, is_create=False):
98102
attrs['dscp_mark'] = parsed_args.dscp_mark
99103
if parsed_args.min_kbps is not None:
100104
attrs['min_kbps'] = parsed_args.min_kbps
105+
if parsed_args.min_kpps is not None:
106+
attrs['min_kpps'] = parsed_args.min_kpps
101107
if parsed_args.ingress:
102-
attrs['direction'] = 'ingress'
108+
attrs['direction'] = DIRECTION_INGRESS
103109
if parsed_args.egress:
104-
attrs['direction'] = 'egress'
110+
attrs['direction'] = DIRECTION_EGRESS
111+
if parsed_args.any:
112+
if rule_type == RULE_TYPE_MINIMUM_PACKET_RATE:
113+
attrs['direction'] = DIRECTION_ANY
114+
else:
115+
msg = (_('Direction "any" can only be used with '
116+
'%(rule_type_min_pps)s rule type') %
117+
{'rule_type_min_pps': RULE_TYPE_MINIMUM_PACKET_RATE})
118+
raise exceptions.CommandError(msg)
105119
_check_type_parameters(attrs, rule_type, is_create)
106120
return attrs
107121

@@ -160,6 +174,13 @@ def _add_rule_arguments(parser):
160174
type=int,
161175
help=_('Minimum guaranteed bandwidth in kbps')
162176
)
177+
parser.add_argument(
178+
'--min-kpps',
179+
dest='min_kpps',
180+
metavar='<min-kpps>',
181+
type=int,
182+
help=_('Minimum guaranteed packet rate in kpps')
183+
)
163184
direction_group = parser.add_mutually_exclusive_group()
164185
direction_group.add_argument(
165186
'--ingress',
@@ -171,6 +192,12 @@ def _add_rule_arguments(parser):
171192
action='store_true',
172193
help=_("Egress traffic direction from the project point of view")
173194
)
195+
direction_group.add_argument(
196+
'--any',
197+
action='store_true',
198+
help=_("Any traffic direction from the project point of view. Can be "
199+
"used only with minimum packet rate rule.")
200+
)
174201

175202

176203
class CreateNetworkQosRule(command.ShowOne,
@@ -190,6 +217,7 @@ def get_parser(self, prog_name):
190217
metavar='<type>',
191218
required=True,
192219
choices=[RULE_TYPE_MINIMUM_BANDWIDTH,
220+
RULE_TYPE_MINIMUM_PACKET_RATE,
193221
RULE_TYPE_DSCP_MARKING,
194222
RULE_TYPE_BANDWIDTH_LIMIT],
195223
help=(_('QoS rule type (%s)') %
@@ -200,10 +228,10 @@ def get_parser(self, prog_name):
200228

201229
def take_action(self, parsed_args):
202230
network_client = self.app.client_manager.network
203-
attrs = _get_attrs(network_client, parsed_args, is_create=True)
204-
attrs.update(
205-
self._parse_extra_properties(parsed_args.extra_properties))
206231
try:
232+
attrs = _get_attrs(network_client, parsed_args, is_create=True)
233+
attrs.update(
234+
self._parse_extra_properties(parsed_args.extra_properties))
207235
obj = _rule_action_call(
208236
network_client, ACTION_CREATE, parsed_args.type)(
209237
attrs.pop('qos_policy_id'), **attrs)
@@ -270,6 +298,7 @@ def take_action(self, parsed_args):
270298
'max_kbps',
271299
'max_burst_kbps',
272300
'min_kbps',
301+
'min_kpps',
273302
'dscp_mark',
274303
'direction',
275304
)
@@ -280,6 +309,7 @@ def take_action(self, parsed_args):
280309
'Max Kbps',
281310
'Max Burst Kbits',
282311
'Min Kbps',
312+
'Min Kpps',
283313
'DSCP mark',
284314
'Direction',
285315
)

openstackclient/tests/functional/network/v2/test_network_qos_rule.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,73 @@ def test_qos_rule_set(self):
8585
self.assertEqual(7500, cmd_output['min_kbps'])
8686

8787

88+
class NetworkQosRuleTestsMinimumPacketRate(common.NetworkTests):
89+
"""Functional tests for QoS minimum packet rate rule"""
90+
91+
def setUp(self):
92+
super(NetworkQosRuleTestsMinimumPacketRate, self).setUp()
93+
# Nothing in this class works with Nova Network
94+
if not self.haz_network:
95+
self.skipTest("No Network service present")
96+
97+
self.QOS_POLICY_NAME = 'qos_policy_%s' % uuid.uuid4().hex
98+
99+
self.openstack(
100+
'network qos policy create %s' % self.QOS_POLICY_NAME
101+
)
102+
self.addCleanup(self.openstack,
103+
'network qos policy delete %s' % self.QOS_POLICY_NAME)
104+
cmd_output = json.loads(self.openstack(
105+
'network qos rule create -f json '
106+
'--type minimum-packet-rate '
107+
'--min-kpps 2800 '
108+
'--egress %s' %
109+
self.QOS_POLICY_NAME
110+
))
111+
self.RULE_ID = cmd_output['id']
112+
self.addCleanup(self.openstack,
113+
'network qos rule delete %s %s' %
114+
(self.QOS_POLICY_NAME, self.RULE_ID))
115+
self.assertTrue(self.RULE_ID)
116+
117+
def test_qos_rule_create_delete(self):
118+
# This is to check the output of qos rule delete
119+
policy_name = uuid.uuid4().hex
120+
self.openstack('network qos policy create -f json %s' % policy_name)
121+
self.addCleanup(self.openstack,
122+
'network qos policy delete %s' % policy_name)
123+
rule = json.loads(self.openstack(
124+
'network qos rule create -f json '
125+
'--type minimum-packet-rate '
126+
'--min-kpps 2800 '
127+
'--egress %s' % policy_name
128+
))
129+
raw_output = self.openstack(
130+
'network qos rule delete %s %s' %
131+
(policy_name, rule['id']))
132+
self.assertEqual('', raw_output)
133+
134+
def test_qos_rule_list(self):
135+
cmd_output = json.loads(self.openstack(
136+
'network qos rule list -f json %s' % self.QOS_POLICY_NAME))
137+
self.assertIn(self.RULE_ID, [rule['ID'] for rule in cmd_output])
138+
139+
def test_qos_rule_show(self):
140+
cmd_output = json.loads(self.openstack(
141+
'network qos rule show -f json %s %s' %
142+
(self.QOS_POLICY_NAME, self.RULE_ID)))
143+
self.assertEqual(self.RULE_ID, cmd_output['id'])
144+
145+
def test_qos_rule_set(self):
146+
self.openstack('network qos rule set --min-kpps 7500 --any %s %s' %
147+
(self.QOS_POLICY_NAME, self.RULE_ID))
148+
cmd_output = json.loads(self.openstack(
149+
'network qos rule show -f json %s %s' %
150+
(self.QOS_POLICY_NAME, self.RULE_ID)))
151+
self.assertEqual(7500, cmd_output['min_kpps'])
152+
self.assertEqual('any', cmd_output['direction'])
153+
154+
88155
class NetworkQosRuleTestsDSCPMarking(common.NetworkTests):
89156
"""Functional tests for QoS DSCP marking rule"""
90157

openstackclient/tests/unit/network/v2/fakes.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@
5858
RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth-limit'
5959
RULE_TYPE_DSCP_MARKING = 'dscp-marking'
6060
RULE_TYPE_MINIMUM_BANDWIDTH = 'minimum-bandwidth'
61+
RULE_TYPE_MINIMUM_PACKET_RATE = 'minimum-packet-rate'
6162
VALID_QOS_RULES = [RULE_TYPE_BANDWIDTH_LIMIT,
6263
RULE_TYPE_DSCP_MARKING,
63-
RULE_TYPE_MINIMUM_BANDWIDTH]
64+
RULE_TYPE_MINIMUM_BANDWIDTH,
65+
RULE_TYPE_MINIMUM_PACKET_RATE]
6466
VALID_DSCP_MARKS = [0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
6567
34, 36, 38, 40, 46, 48, 56]
6668

@@ -274,6 +276,9 @@ def create_one_qos_rule(attrs=None):
274276
elif type == RULE_TYPE_MINIMUM_BANDWIDTH:
275277
qos_rule_attrs['min_kbps'] = randint(1, 10000)
276278
qos_rule_attrs['direction'] = 'egress'
279+
elif type == RULE_TYPE_MINIMUM_PACKET_RATE:
280+
qos_rule_attrs['min_kpps'] = randint(1, 10000)
281+
qos_rule_attrs['direction'] = 'egress'
277282

278283
# Overwrite default attributes.
279284
qos_rule_attrs.update(attrs)

0 commit comments

Comments
 (0)