Skip to content

Commit c5b58a4

Browse files
committed
Refactor security group rule list to use SDK
Refactored the 'os security group rule list' command to use the SDK when neutron is enabled, but continue to use the nova client when nova network is enabled. In addition, a release note was added to document the features and fixes resulting from this refactor. Change-Id: I24d04b720102ed1c60776e1ca67d4ca20e31b663 Partial-Bug: #1519512 Implements: blueprint neutron-client
1 parent 5f55e99 commit c5b58a4

6 files changed

Lines changed: 314 additions & 334 deletions

File tree

openstackclient/compute/v2/security_group.py

Lines changed: 0 additions & 103 deletions
This file was deleted.

openstackclient/network/v2/security_group_rule.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515

1616
import six
1717

18+
try:
19+
from novaclient.v2 import security_group_rules as compute_secgroup_rules
20+
except ImportError:
21+
from novaclient.v1_1 import security_group_rules as compute_secgroup_rules
22+
1823
from openstackclient.common import exceptions
1924
from openstackclient.common import parseractions
2025
from openstackclient.common import utils
@@ -27,6 +32,20 @@ def _format_security_group_rule_show(obj):
2732
return zip(*sorted(six.iteritems(data)))
2833

2934

35+
def _format_network_port_range(rule):
36+
port_range = ''
37+
if (rule.protocol != 'icmp' and
38+
(rule.port_range_min or rule.port_range_max)):
39+
port_range_min = str(rule.port_range_min)
40+
port_range_max = str(rule.port_range_max)
41+
if rule.port_range_min is None:
42+
port_range_min = port_range_max
43+
if rule.port_range_max is None:
44+
port_range_max = port_range_min
45+
port_range = port_range_min + ':' + port_range_max
46+
return port_range
47+
48+
3049
def _get_columns(item):
3150
columns = list(item.keys())
3251
if 'tenant_id' in columns:
@@ -161,6 +180,102 @@ def take_action_compute(self, client, parsed_args):
161180
client.security_group_rules.delete(parsed_args.rule)
162181

163182

183+
class ListSecurityGroupRule(common.NetworkAndComputeLister):
184+
"""List security group rules"""
185+
186+
def update_parser_common(self, parser):
187+
parser.add_argument(
188+
'group',
189+
metavar='<group>',
190+
nargs='?',
191+
help='List all rules in this security group (name or ID)',
192+
)
193+
return parser
194+
195+
def _get_column_headers(self, parsed_args):
196+
column_headers = (
197+
'ID',
198+
'IP Protocol',
199+
'IP Range',
200+
'Port Range',
201+
'Remote Security Group',
202+
)
203+
if parsed_args.group is None:
204+
column_headers = column_headers + ('Security Group',)
205+
return column_headers
206+
207+
def take_action_network(self, client, parsed_args):
208+
column_headers = self._get_column_headers(parsed_args)
209+
columns = (
210+
'id',
211+
'protocol',
212+
'remote_ip_prefix',
213+
'port_range_min',
214+
'remote_group_id',
215+
)
216+
217+
# Get the security group rules using the requested query.
218+
query = {}
219+
if parsed_args.group is not None:
220+
# NOTE(rtheis): Unfortunately, the security group resource
221+
# does not contain security group rules resources. So use
222+
# the security group ID in a query to get the resources.
223+
security_group_id = client.find_security_group(
224+
parsed_args.group,
225+
ignore_missing=False
226+
).id
227+
query = {'security_group_id': security_group_id}
228+
else:
229+
columns = columns + ('security_group_id',)
230+
rules = list(client.security_group_rules(**query))
231+
232+
# Reformat the rules to display a port range instead
233+
# of just the port range minimum. This maintains
234+
# output compatibility with compute.
235+
for rule in rules:
236+
rule.port_range_min = _format_network_port_range(rule)
237+
238+
return (column_headers,
239+
(utils.get_item_properties(
240+
s, columns,
241+
) for s in rules))
242+
243+
def take_action_compute(self, client, parsed_args):
244+
column_headers = self._get_column_headers(parsed_args)
245+
columns = (
246+
"ID",
247+
"IP Protocol",
248+
"IP Range",
249+
"Port Range",
250+
"Remote Security Group",
251+
)
252+
253+
rules_to_list = []
254+
if parsed_args.group is not None:
255+
group = utils.find_resource(
256+
client.security_groups,
257+
parsed_args.group,
258+
)
259+
rules_to_list = group.rules
260+
else:
261+
columns = columns + ('parent_group_id',)
262+
for group in client.security_groups.list():
263+
rules_to_list.extend(group.rules)
264+
265+
# NOTE(rtheis): Turn the raw rules into resources.
266+
rules = []
267+
for rule in rules_to_list:
268+
rules.append(compute_secgroup_rules.SecurityGroupRule(
269+
client.security_group_rules,
270+
network_utils.transform_compute_security_group_rule(rule),
271+
))
272+
273+
return (column_headers,
274+
(utils.get_item_properties(
275+
s, columns,
276+
) for s in rules))
277+
278+
164279
class ShowSecurityGroupRule(common.NetworkAndComputeShowOne):
165280
"""Display security group rule details"""
166281

0 commit comments

Comments
 (0)