Skip to content
This repository was archived by the owner on Nov 19, 2018. It is now read-only.

Commit 2ecbb73

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Refactor security group list to use SDK"
2 parents 0dfc50e + 842882f commit 2ecbb73

8 files changed

Lines changed: 267 additions & 126 deletions

File tree

doc/source/command-objects/security-group.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ List security groups
5454

5555
Display information from all projects (admin only)
5656

57+
*Network version 2 ignores this option and will always display information*
58+
*for all projects.*
59+
5760
security group set
5861
------------------
5962

openstackclient/compute/v2/security_group.py

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
import six
2020

21-
from keystoneauth1 import exceptions as ks_exc
22-
2321
try:
2422
from novaclient.v2 import security_group_rules
2523
except ImportError:
@@ -169,58 +167,6 @@ def take_action(self, parsed_args):
169167
return zip(*sorted(six.iteritems(info)))
170168

171169

172-
class ListSecurityGroup(command.Lister):
173-
"""List security groups"""
174-
175-
def get_parser(self, prog_name):
176-
parser = super(ListSecurityGroup, self).get_parser(prog_name)
177-
parser.add_argument(
178-
'--all-projects',
179-
action='store_true',
180-
default=False,
181-
help='Display information from all projects (admin only)',
182-
)
183-
return parser
184-
185-
def take_action(self, parsed_args):
186-
187-
def _get_project(project_id):
188-
try:
189-
return getattr(project_hash[project_id], 'name', project_id)
190-
except KeyError:
191-
return project_id
192-
193-
compute_client = self.app.client_manager.compute
194-
columns = (
195-
"ID",
196-
"Name",
197-
"Description",
198-
)
199-
column_headers = columns
200-
if parsed_args.all_projects:
201-
# TODO(dtroyer): Translate Project_ID to Project (name)
202-
columns = columns + ('Tenant ID',)
203-
column_headers = column_headers + ('Project',)
204-
search = {'all_tenants': parsed_args.all_projects}
205-
data = compute_client.security_groups.list(search_opts=search)
206-
207-
project_hash = {}
208-
try:
209-
projects = self.app.client_manager.identity.projects.list()
210-
except ks_exc.ClientException:
211-
# This fails when the user is not an admin, just move along
212-
pass
213-
else:
214-
for project in projects:
215-
project_hash[project.id] = project
216-
217-
return (column_headers,
218-
(utils.get_item_properties(
219-
s, columns,
220-
formatters={'Tenant ID': _get_project},
221-
) for s in data))
222-
223-
224170
class ListSecurityGroupRule(command.Lister):
225171
"""List security group rules"""
226172

openstackclient/network/v2/security_group.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
"""Security Group action implementations"""
1515

16+
import argparse
17+
1618
from openstackclient.common import utils
1719
from openstackclient.network import common
1820

@@ -38,3 +40,51 @@ def take_action_compute(self, client, parsed_args):
3840
parsed_args.group,
3941
)
4042
client.security_groups.delete(data.id)
43+
44+
45+
class ListSecurityGroup(common.NetworkAndComputeLister):
46+
"""List security groups"""
47+
48+
def update_parser_network(self, parser):
49+
# Maintain and hide the argument for backwards compatibility.
50+
# Network will always return all projects for an admin.
51+
parser.add_argument(
52+
'--all-projects',
53+
action='store_true',
54+
default=False,
55+
help=argparse.SUPPRESS,
56+
)
57+
return parser
58+
59+
def update_parser_compute(self, parser):
60+
parser.add_argument(
61+
'--all-projects',
62+
action='store_true',
63+
default=False,
64+
help='Display information from all projects (admin only)',
65+
)
66+
return parser
67+
68+
def _get_return_data(self, data, include_project=True):
69+
columns = (
70+
"ID",
71+
"Name",
72+
"Description",
73+
)
74+
column_headers = columns
75+
if include_project:
76+
columns = columns + ('Tenant ID',)
77+
column_headers = column_headers + ('Project',)
78+
return (column_headers,
79+
(utils.get_item_properties(
80+
s, columns,
81+
) for s in data))
82+
83+
def take_action_network(self, client, parsed_args):
84+
return self._get_return_data(client.security_groups())
85+
86+
def take_action_compute(self, client, parsed_args):
87+
search = {'all_tenants': parsed_args.all_projects}
88+
data = client.security_groups.list(search_opts=search)
89+
return self._get_return_data(data,
90+
include_project=parsed_args.all_projects)

openstackclient/tests/compute/v2/fakes.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,70 @@ def create_hypervisors_stats(attrs={}, count=2):
298298
return hypervisors
299299

300300

301+
class FakeSecurityGroup(object):
302+
"""Fake one or more security groups."""
303+
304+
@staticmethod
305+
def create_one_security_group(attrs=None, methods=None):
306+
"""Create a fake security group.
307+
308+
:param Dictionary attrs:
309+
A dictionary with all attributes
310+
:param Dictionary methods:
311+
A dictionary with all methods
312+
:return:
313+
A FakeResource object, with id, name, etc.
314+
"""
315+
if attrs is None:
316+
attrs = {}
317+
if methods is None:
318+
methods = {}
319+
320+
# Set default attributes.
321+
security_group_attrs = {
322+
'id': 'security-group-id-' + uuid.uuid4().hex,
323+
'name': 'security-group-name-' + uuid.uuid4().hex,
324+
'description': 'security-group-description-' + uuid.uuid4().hex,
325+
'tenant_id': 'project-id-' + uuid.uuid4().hex,
326+
'rules': [],
327+
}
328+
329+
# Overwrite default attributes.
330+
security_group_attrs.update(attrs)
331+
332+
# Set default methods.
333+
security_group_methods = {}
334+
335+
# Overwrite default methods.
336+
security_group_methods.update(methods)
337+
338+
security_group = fakes.FakeResource(
339+
info=copy.deepcopy(security_group_attrs),
340+
methods=copy.deepcopy(security_group_methods),
341+
loaded=True)
342+
return security_group
343+
344+
@staticmethod
345+
def create_security_groups(attrs=None, methods=None, count=2):
346+
"""Create multiple fake security groups.
347+
348+
:param Dictionary attrs:
349+
A dictionary with all attributes
350+
:param Dictionary methods:
351+
A dictionary with all methods
352+
:param int count:
353+
The number of security groups to fake
354+
:return:
355+
A list of FakeResource objects faking the security groups
356+
"""
357+
security_groups = []
358+
for i in range(0, count):
359+
security_groups.append(
360+
FakeSecurityGroup.create_one_security_group(attrs, methods))
361+
362+
return security_groups
363+
364+
301365
class FakeSecurityGroupRule(object):
302366
"""Fake one or more security group rules."""
303367

openstackclient/tests/compute/v2/test_security_group.py

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -125,65 +125,3 @@ def test_security_group_create_description(self):
125125

126126
self.assertEqual(self.columns, columns)
127127
self.assertEqual(self.data, data)
128-
129-
130-
class TestSecurityGroupList(TestSecurityGroup):
131-
132-
def setUp(self):
133-
super(TestSecurityGroupList, self).setUp()
134-
135-
self.secgroups_mock.list.return_value = [
136-
FakeSecurityGroupResource(
137-
None,
138-
copy.deepcopy(SECURITY_GROUP),
139-
loaded=True,
140-
),
141-
]
142-
143-
# Get the command object to test
144-
self.cmd = security_group.ListSecurityGroup(self.app, None)
145-
146-
def test_security_group_list_no_options(self):
147-
self.projects_mock.list.return_value = [
148-
fakes.FakeResource(
149-
None,
150-
copy.deepcopy(identity_fakes.PROJECT),
151-
loaded=True,
152-
),
153-
]
154-
155-
arglist = []
156-
verifylist = [
157-
('all_projects', False),
158-
]
159-
160-
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
161-
162-
# In base command class Lister in cliff, abstract method take_action()
163-
# returns a tuple containing the column names and an iterable
164-
# containing the data to be listed.
165-
columns, data = self.cmd.take_action(parsed_args)
166-
167-
# Set expected values
168-
kwargs = {
169-
'search_opts': {
170-
'all_tenants': False,
171-
},
172-
}
173-
174-
self.secgroups_mock.list.assert_called_with(
175-
**kwargs
176-
)
177-
178-
collist = (
179-
'ID',
180-
'Name',
181-
'Description',
182-
)
183-
self.assertEqual(collist, columns)
184-
datalist = ((
185-
security_group_id,
186-
security_group_name,
187-
security_group_description,
188-
), )
189-
self.assertEqual(datalist, tuple(data))

0 commit comments

Comments
 (0)