Skip to content

Commit 5caac0e

Browse files
committed
Add meter rule to OSC
Implement network feature meter label rules into OpenStack Client. Allows for creation of rules to meter network traffic. Partially Implements: blueprint neutron-client-metering Change-Id: If18c078d7e80c122583417669f820f02c84d6237
1 parent 607f31d commit 5caac0e

7 files changed

Lines changed: 792 additions & 5 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
==================
2+
network meter rule
3+
==================
4+
5+
A **meter rule** sets the rule for
6+
a meter to measure traffic for a specific IP range.
7+
The following uses **meter** and requires the L3
8+
metering extension.
9+
10+
Network v2
11+
12+
network meter rule create
13+
-------------------------
14+
15+
Create meter rule
16+
17+
.. program:: network meter rule create
18+
.. code:: bash
19+
20+
openstack network meter rule create
21+
[--project <project> [--project-domain <project-domain>]]
22+
[--ingress | --egress]
23+
[--exclude | --include]
24+
--remote-ip-prefix <remote-ip-prefix>
25+
<meter>
26+
27+
.. option:: --project <project>
28+
29+
Owner's project (name or ID)
30+
31+
*Network version 2 only*
32+
33+
.. option:: --project-domain <project-domain>
34+
35+
Domain the project belongs to (name of ID).
36+
This can be used in case collisions between project names exist.
37+
38+
.. option:: --ingress
39+
40+
Rule is applied to incoming traffic (default)
41+
42+
.. option:: --egress
43+
44+
Rule is applied to outgoing traffic
45+
46+
.. option:: --exclude
47+
48+
Exclude remote_ip_prefix from count of the traffic of IP addresses
49+
50+
.. option:: --include
51+
52+
Include remote_ip_prefix into count of the traffic of IP addresses
53+
(default)
54+
55+
.. option:: --remote-ip-prefix <remote-ip-prefix>
56+
57+
The remote IP prefix to associate with this metering rule packet
58+
59+
.. _network_meter_rule_create:
60+
.. describe:: <meter>
61+
62+
Meter to associate with this meter rule (name or ID)
63+
64+
65+
network meter rule delete
66+
-------------------------
67+
68+
Delete meter rule(s)
69+
70+
.. program:: network meter rule delete
71+
.. code:: bash
72+
73+
openstack network meter rule delete <id> [<id> ...]
74+
75+
.. _network_meter_rule_delete:
76+
.. describe:: <meter-rule-id>
77+
78+
ID of meter rule(s) to delete
79+
80+
network meter rule list
81+
-----------------------
82+
83+
List meter rules
84+
85+
.. program:: network meter rule list
86+
.. code:: bash
87+
88+
openstack network meter rule list
89+
90+
network meter rule show
91+
-----------------------
92+
93+
Show meter rule
94+
95+
.. program:: network meter rule show
96+
.. code:: bash
97+
98+
openstack network meter rule show <meter-rule-id>
99+
100+
.. _network_meter_show:
101+
.. describe:: <meter-rule-id>
102+
103+
Meter rule to display (ID only)

doc/source/commands.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ referring to both Compute and Volume quotas.
112112
* ``network``: (**Compute**, **Network**) - a virtual network for connecting servers and other resources
113113
* ``network agent``: (**Network**) - A network agent is an agent that handles various tasks used to implement virtual networks
114114
* ``network meter``: (**Network**) - allow traffic metering in a network
115+
* ``network meter rule``: (**Network**) - rules for network traffic metering
115116
* ``network rbac``: (**Network**) - an RBAC policy for network resources
116117
* ``network qos rule``: (**Network**) - a QoS rule for network resources
117118
* ``network qos policy``: (**Network**) - a QoS policy for network resources
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
14+
"""Meter Rule Implementations"""
15+
16+
import logging
17+
18+
from osc_lib.command import command
19+
from osc_lib import exceptions
20+
from osc_lib import utils
21+
22+
from openstackclient.i18n import _
23+
from openstackclient.identity import common as identity_common
24+
from openstackclient.network import sdk_utils
25+
26+
LOG = logging.getLogger(__name__)
27+
28+
29+
def _get_columns(item):
30+
column_map = {
31+
'tenant_id': 'project_id',
32+
}
33+
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
34+
35+
36+
def _get_attrs(client_manager, parsed_args):
37+
attrs = {}
38+
39+
if parsed_args.exclude:
40+
attrs['excluded'] = True
41+
if parsed_args.include:
42+
attrs['excluded'] = False
43+
if parsed_args.ingress or not parsed_args.egress:
44+
attrs['direction'] = 'ingress'
45+
if parsed_args.egress:
46+
attrs['direction'] = 'egress'
47+
if parsed_args.remote_ip_prefix is not None:
48+
attrs['remote_ip_prefix'] = parsed_args.remote_ip_prefix
49+
if parsed_args.meter is not None:
50+
attrs['metering_label_id'] = parsed_args.meter
51+
if parsed_args.project is not None:
52+
identity_client = client_manager.identity
53+
project_id = identity_common.find_project(
54+
identity_client,
55+
parsed_args.project,
56+
parsed_args.project_domain,
57+
).id
58+
attrs['tenant_id'] = project_id
59+
60+
return attrs
61+
62+
63+
class CreateMeterRule(command.ShowOne):
64+
_description = _("Create a new meter rule")
65+
66+
def get_parser(self, prog_name):
67+
parser = super(CreateMeterRule, self).get_parser(prog_name)
68+
69+
parser.add_argument(
70+
'--project',
71+
metavar='<project>',
72+
help=_("Owner's project (name or ID)")
73+
)
74+
identity_common.add_project_domain_option_to_parser(parser)
75+
exclude_group = parser.add_mutually_exclusive_group()
76+
exclude_group.add_argument(
77+
'--exclude',
78+
action='store_true',
79+
help=_("Exclude remote IP prefix from traffic count")
80+
)
81+
exclude_group.add_argument(
82+
'--include',
83+
action='store_true',
84+
help=_("Include remote IP prefix from traffic count (default)")
85+
)
86+
direction_group = parser.add_mutually_exclusive_group()
87+
direction_group.add_argument(
88+
'--ingress',
89+
action='store_true',
90+
help=_("Apply rule to incoming network traffic (default)")
91+
)
92+
direction_group.add_argument(
93+
'--egress',
94+
action='store_true',
95+
help=_('Apply rule to outgoing network traffic')
96+
)
97+
parser.add_argument(
98+
'--remote-ip-prefix',
99+
metavar='<remote-ip-prefix>',
100+
required=True,
101+
help=_('The remote IP prefix to associate with this rule'),
102+
)
103+
parser.add_argument(
104+
'meter',
105+
metavar='<meter>',
106+
help=_('Label to associate with this metering rule (name or ID)'),
107+
)
108+
109+
return parser
110+
111+
def take_action(self, parsed_args):
112+
client = self.app.client_manager.network
113+
_meter = client.find_metering_label(parsed_args.meter,
114+
ignore_missing=False)
115+
parsed_args.meter = _meter.id
116+
attrs = _get_attrs(self.app.client_manager, parsed_args)
117+
obj = client.create_metering_label_rule(**attrs)
118+
display_columns, columns = _get_columns(obj)
119+
data = utils.get_item_properties(obj, columns, formatters={})
120+
121+
return (display_columns, data)
122+
123+
124+
class DeleteMeterRule(command.Command):
125+
_description = _("Delete meter rule(s)")
126+
127+
def get_parser(self, prog_name):
128+
parser = super(DeleteMeterRule, self).get_parser(prog_name)
129+
130+
parser.add_argument(
131+
'meter_rule_id',
132+
metavar='<meter-rule-id>',
133+
nargs='+',
134+
help=_('Meter rule to delete (ID only)')
135+
)
136+
137+
return parser
138+
139+
def take_action(self, parsed_args):
140+
client = self.app.client_manager.network
141+
result = 0
142+
143+
for id in parsed_args.meter_rule_id:
144+
try:
145+
obj = client.find_metering_label_rule(id, ignore_missing=False)
146+
client.delete_metering_label_rule(obj)
147+
except Exception as e:
148+
result += 1
149+
LOG.error(_("Failed to delete meter rule with "
150+
"ID '%(id)s': %(e)s"),
151+
{"id": id, "e": e})
152+
153+
if result > 0:
154+
total = len(parsed_args.meter_rule_id)
155+
msg = (_("%(result)s of %(total)s meter rules failed "
156+
"to delete.") % {"result": result, "total": total})
157+
raise exceptions.CommandError(msg)
158+
159+
160+
class ListMeterRule(command.Lister):
161+
_description = _("List meter rules")
162+
163+
def take_action(self, parsed_args):
164+
client = self.app.client_manager.network
165+
166+
columns = (
167+
'id',
168+
'excluded',
169+
'direction',
170+
'remote_ip_prefix',
171+
)
172+
column_headers = (
173+
'ID',
174+
'Excluded',
175+
'Direction',
176+
'Remote IP Prefix',
177+
)
178+
data = client.metering_label_rules()
179+
return (column_headers,
180+
(utils.get_item_properties(
181+
s, columns,
182+
) for s in data))
183+
184+
185+
class ShowMeterRule(command.ShowOne):
186+
_description = _("Display meter rules details")
187+
188+
def get_parser(self, prog_name):
189+
parser = super(ShowMeterRule, self).get_parser(prog_name)
190+
parser.add_argument(
191+
'meter_rule_id',
192+
metavar='<meter-rule-id>',
193+
help=_('Meter rule (ID only)')
194+
)
195+
return parser
196+
197+
def take_action(self, parsed_args):
198+
client = self.app.client_manager.network
199+
obj = client.find_metering_label_rule(parsed_args.meter_rule_id,
200+
ignore_missing=False)
201+
display_columns, columns = _get_columns(obj)
202+
data = utils.get_item_properties(obj, columns)
203+
return display_columns, data

0 commit comments

Comments
 (0)