Skip to content

Commit d4b71ea

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Refactor security group show to use SDK"
2 parents 4bb48c0 + 564c8ff commit d4b71ea

9 files changed

Lines changed: 310 additions & 93 deletions

File tree

openstackclient/compute/v2/security_group.py

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,6 @@ def _xform_security_group_rule(sgroup):
5656
return info
5757

5858

59-
def _xform_and_trim_security_group_rule(sgroup):
60-
info = _xform_security_group_rule(sgroup)
61-
# Trim parent security group ID since caller has this information.
62-
info.pop('parent_group_id', None)
63-
# Trim keys with empty string values.
64-
keys_to_trim = [
65-
'ip_protocol',
66-
'ip_range',
67-
'port_range',
68-
'remote_security_group',
69-
]
70-
for key in keys_to_trim:
71-
if key in info and not info[key]:
72-
info.pop(key)
73-
return info
74-
75-
7659
class CreateSecurityGroup(command.ShowOne):
7760
"""Create a new security group"""
7861

@@ -215,40 +198,3 @@ def take_action(self, parsed_args):
215198
(utils.get_item_properties(
216199
s, columns,
217200
) for s in rules))
218-
219-
220-
class ShowSecurityGroup(command.ShowOne):
221-
"""Display security group details"""
222-
223-
def get_parser(self, prog_name):
224-
parser = super(ShowSecurityGroup, self).get_parser(prog_name)
225-
parser.add_argument(
226-
'group',
227-
metavar='<group>',
228-
help='Security group to display (name or ID)',
229-
)
230-
return parser
231-
232-
def take_action(self, parsed_args):
233-
234-
compute_client = self.app.client_manager.compute
235-
info = {}
236-
info.update(utils.find_resource(
237-
compute_client.security_groups,
238-
parsed_args.group,
239-
)._info)
240-
rules = []
241-
for r in info['rules']:
242-
formatted_rule = _xform_and_trim_security_group_rule(r)
243-
rules.append(utils.format_dict(formatted_rule))
244-
245-
# Format rules into a list of strings
246-
info.update(
247-
{'rules': utils.format_list(rules, separator='\n')}
248-
)
249-
# Map 'tenant_id' column to 'project_id'
250-
info.update(
251-
{'project_id': info.pop('tenant_id')}
252-
)
253-
254-
return zip(*sorted(six.iteritems(info)))

openstackclient/network/utils.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
15+
# Transform compute security group rule for display.
16+
def transform_compute_security_group_rule(sg_rule):
17+
info = {}
18+
info.update(sg_rule)
19+
from_port = info.pop('from_port')
20+
to_port = info.pop('to_port')
21+
if isinstance(from_port, int) and isinstance(to_port, int):
22+
port_range = {'port_range': "%u:%u" % (from_port, to_port)}
23+
elif from_port is None and to_port is None:
24+
port_range = {'port_range': ""}
25+
else:
26+
port_range = {'port_range': "%s:%s" % (from_port, to_port)}
27+
info.update(port_range)
28+
if 'cidr' in info['ip_range']:
29+
info['ip_range'] = info['ip_range']['cidr']
30+
else:
31+
info['ip_range'] = ''
32+
if info['ip_protocol'] is None:
33+
info['ip_protocol'] = ''
34+
elif info['ip_protocol'].lower() == 'icmp':
35+
info['port_range'] = ''
36+
group = info.pop('group')
37+
if 'name' in group:
38+
info['remote_security_group'] = group['name']
39+
else:
40+
info['remote_security_group'] = ''
41+
return info

openstackclient/network/v2/security_group.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,81 @@
1414
"""Security Group action implementations"""
1515

1616
import argparse
17+
import six
1718

1819
from openstackclient.common import utils
1920
from openstackclient.network import common
21+
from openstackclient.network import utils as network_utils
22+
23+
24+
def _format_network_security_group_rules(sg_rules):
25+
# For readability and to align with formatting compute security group
26+
# rules, trim keys with caller known (e.g. security group and tenant ID)
27+
# or empty values.
28+
for sg_rule in sg_rules:
29+
empty_keys = [k for k, v in six.iteritems(sg_rule) if not v]
30+
for key in empty_keys:
31+
sg_rule.pop(key)
32+
sg_rule.pop('security_group_id', None)
33+
sg_rule.pop('tenant_id', None)
34+
return utils.format_list_of_dicts(sg_rules)
35+
36+
37+
def _format_compute_security_group_rule(sg_rule):
38+
info = network_utils.transform_compute_security_group_rule(sg_rule)
39+
# Trim parent security group ID since caller has this information.
40+
info.pop('parent_group_id', None)
41+
# Trim keys with empty string values.
42+
keys_to_trim = [
43+
'ip_protocol',
44+
'ip_range',
45+
'port_range',
46+
'remote_security_group',
47+
]
48+
for key in keys_to_trim:
49+
if key in info and not info[key]:
50+
info.pop(key)
51+
return utils.format_dict(info)
52+
53+
54+
def _format_compute_security_group_rules(sg_rules):
55+
rules = []
56+
for sg_rule in sg_rules:
57+
rules.append(_format_compute_security_group_rule(sg_rule))
58+
return utils.format_list(rules, separator='\n')
59+
60+
61+
_formatters_network = {
62+
'security_group_rules': _format_network_security_group_rules,
63+
}
64+
65+
66+
_formatters_compute = {
67+
'rules': _format_compute_security_group_rules,
68+
}
69+
70+
71+
def _get_columns(item):
72+
# Build the display columns and a list of the property columns
73+
# that need to be mapped (display column name, property name).
74+
columns = list(item.keys())
75+
property_column_mappings = []
76+
if 'security_group_rules' in columns:
77+
columns.append('rules')
78+
columns.remove('security_group_rules')
79+
property_column_mappings.append(('rules', 'security_group_rules'))
80+
if 'tenant_id' in columns:
81+
columns.append('project_id')
82+
columns.remove('tenant_id')
83+
property_column_mappings.append(('project_id', 'tenant_id'))
84+
display_columns = sorted(columns)
85+
86+
# Build the property columns and apply any column mappings.
87+
property_columns = sorted(columns)
88+
for property_column_mapping in property_column_mappings:
89+
property_index = property_columns.index(property_column_mapping[0])
90+
property_columns[property_index] = property_column_mapping[1]
91+
return tuple(display_columns), property_columns
2092

2193

2294
class DeleteSecurityGroup(common.NetworkAndComputeCommand):
@@ -143,3 +215,39 @@ def take_action_compute(self, client, parsed_args):
143215
data.name,
144216
data.description,
145217
)
218+
219+
220+
class ShowSecurityGroup(common.NetworkAndComputeShowOne):
221+
"""Display security group details"""
222+
223+
def update_parser_common(self, parser):
224+
parser.add_argument(
225+
'group',
226+
metavar='<group>',
227+
help='Security group to display (name or ID)',
228+
)
229+
return parser
230+
231+
def take_action_network(self, client, parsed_args):
232+
obj = client.find_security_group(parsed_args.group,
233+
ignore_missing=False)
234+
display_columns, property_columns = _get_columns(obj)
235+
data = utils.get_item_properties(
236+
obj,
237+
property_columns,
238+
formatters=_formatters_network
239+
)
240+
return (display_columns, data)
241+
242+
def take_action_compute(self, client, parsed_args):
243+
obj = utils.find_resource(
244+
client.security_groups,
245+
parsed_args.group,
246+
)
247+
display_columns, property_columns = _get_columns(obj._info)
248+
data = utils.get_dict_properties(
249+
obj._info,
250+
property_columns,
251+
formatters=_formatters_compute
252+
)
253+
return (display_columns, data)

openstackclient/network/v2/security_group_rule.py

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,11 @@
1818
from openstackclient.common import exceptions
1919
from openstackclient.common import utils
2020
from openstackclient.network import common
21-
22-
23-
def _xform_security_group_rule(sgroup):
24-
info = {}
25-
info.update(sgroup)
26-
from_port = info.pop('from_port')
27-
to_port = info.pop('to_port')
28-
if isinstance(from_port, int) and isinstance(to_port, int):
29-
port_range = {'port_range': "%u:%u" % (from_port, to_port)}
30-
elif from_port is None and to_port is None:
31-
port_range = {'port_range': ""}
32-
else:
33-
port_range = {'port_range': "%s:%s" % (from_port, to_port)}
34-
info.update(port_range)
35-
if 'cidr' in info['ip_range']:
36-
info['ip_range'] = info['ip_range']['cidr']
37-
else:
38-
info['ip_range'] = ''
39-
if info['ip_protocol'] is None:
40-
info['ip_protocol'] = ''
41-
elif info['ip_protocol'].lower() == 'icmp':
42-
info['port_range'] = ''
43-
group = info.pop('group')
44-
if 'name' in group:
45-
info['remote_security_group'] = group['name']
46-
else:
47-
info['remote_security_group'] = ''
48-
return info
21+
from openstackclient.network import utils as network_utils
4922

5023

5124
def _format_security_group_rule_show(obj):
52-
data = _xform_security_group_rule(obj)
25+
data = network_utils.transform_compute_security_group_rule(obj)
5326
return zip(*sorted(six.iteritems(data)))
5427

5528

openstackclient/tests/compute/v2/fakes.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,9 @@ def create_one_security_group(attrs=None, methods=None):
333333
security_group_attrs.update(attrs)
334334

335335
# Set default methods.
336-
security_group_methods = {}
336+
security_group_methods = {
337+
'keys': ['id', 'name', 'description', 'tenant_id', 'rules'],
338+
}
337339

338340
# Overwrite default methods.
339341
security_group_methods.update(methods)
@@ -369,7 +371,7 @@ class FakeSecurityGroupRule(object):
369371
"""Fake one or more security group rules."""
370372

371373
@staticmethod
372-
def create_one_security_group_rule(attrs={}, methods={}):
374+
def create_one_security_group_rule(attrs=None, methods=None):
373375
"""Create a fake security group rule.
374376
375377
:param Dictionary attrs:
@@ -379,6 +381,11 @@ def create_one_security_group_rule(attrs={}, methods={}):
379381
:return:
380382
A FakeResource object, with id, etc.
381383
"""
384+
if attrs is None:
385+
attrs = {}
386+
if methods is None:
387+
methods = {}
388+
382389
# Set default attributes.
383390
security_group_rule_attrs = {
384391
'from_port': -1,
@@ -406,7 +413,7 @@ def create_one_security_group_rule(attrs={}, methods={}):
406413
return security_group_rule
407414

408415
@staticmethod
409-
def create_security_group_rules(attrs={}, methods={}, count=2):
416+
def create_security_group_rules(attrs=None, methods=None, count=2):
410417
"""Create multiple fake security group rules.
411418
412419
:param Dictionary attrs:

openstackclient/tests/network/v2/fakes.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ class FakeSecurityGroup(object):
419419
"""Fake one or more security groups."""
420420

421421
@staticmethod
422-
def create_one_security_group(attrs={}, methods={}):
422+
def create_one_security_group(attrs=None, methods=None):
423423
"""Create a fake security group.
424424
425425
:param Dictionary attrs:
@@ -429,6 +429,11 @@ def create_one_security_group(attrs={}, methods={}):
429429
:return:
430430
A FakeResource object, with id, name, etc.
431431
"""
432+
if attrs is None:
433+
attrs = {}
434+
if methods is None:
435+
methods = {}
436+
432437
# Set default attributes.
433438
security_group_attrs = {
434439
'id': 'security-group-id-' + uuid.uuid4().hex,
@@ -442,7 +447,10 @@ def create_one_security_group(attrs={}, methods={}):
442447
security_group_attrs.update(attrs)
443448

444449
# Set default methods.
445-
security_group_methods = {}
450+
security_group_methods = {
451+
'keys': ['id', 'name', 'description', 'tenant_id',
452+
'security_group_rules'],
453+
}
446454

447455
# Overwrite default methods.
448456
security_group_methods.update(methods)
@@ -451,10 +459,14 @@ def create_one_security_group(attrs={}, methods={}):
451459
info=copy.deepcopy(security_group_attrs),
452460
methods=copy.deepcopy(security_group_methods),
453461
loaded=True)
462+
463+
# Set attributes with special mapping in OpenStack SDK.
464+
security_group.project_id = security_group_attrs['tenant_id']
465+
454466
return security_group
455467

456468
@staticmethod
457-
def create_security_groups(attrs={}, methods={}, count=2):
469+
def create_security_groups(attrs=None, methods=None, count=2):
458470
"""Create multiple fake security groups.
459471
460472
:param Dictionary attrs:
@@ -478,7 +490,7 @@ class FakeSecurityGroupRule(object):
478490
"""Fake one or more security group rules."""
479491

480492
@staticmethod
481-
def create_one_security_group_rule(attrs={}, methods={}):
493+
def create_one_security_group_rule(attrs=None, methods=None):
482494
"""Create a fake security group rule.
483495
484496
:param Dictionary attrs:
@@ -488,6 +500,11 @@ def create_one_security_group_rule(attrs={}, methods={}):
488500
:return:
489501
A FakeResource object, with id, etc.
490502
"""
503+
if attrs is None:
504+
attrs = {}
505+
if methods is None:
506+
methods = {}
507+
491508
# Set default attributes.
492509
security_group_rule_attrs = {
493510
'direction': 'ingress',
@@ -520,13 +537,13 @@ def create_one_security_group_rule(attrs={}, methods={}):
520537
methods=copy.deepcopy(security_group_rule_methods),
521538
loaded=True)
522539

523-
# Set attributes with special mappings.
540+
# Set attributes with special mapping in OpenStack SDK.
524541
security_group_rule.project_id = security_group_rule_attrs['tenant_id']
525542

526543
return security_group_rule
527544

528545
@staticmethod
529-
def create_security_group_rules(attrs={}, methods={}, count=2):
546+
def create_security_group_rules(attrs=None, methods=None, count=2):
530547
"""Create multiple fake security group rules.
531548
532549
:param Dictionary attrs:

0 commit comments

Comments
 (0)