Skip to content

Commit 774201b

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Implementation for project unset cmd for python-openstackclient."
2 parents 1b916da + a2a63f1 commit 774201b

5 files changed

Lines changed: 133 additions & 4 deletions

File tree

doc/source/command-objects/project.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ Set project properties
156156
Set a property on :ref:`\<project\> <project_set-project>`
157157
(repeat option to set multiple properties)
158158

159+
*Identity version 2 only*
160+
159161
.. _project_set-project:
160162
.. describe:: <project>
161163

@@ -195,3 +197,25 @@ Display project details
195197
.. describe:: <project>
196198

197199
Project to display (name or ID)
200+
201+
project unset
202+
-------------
203+
204+
Unset project properties
205+
206+
*Identity version 2 only*
207+
208+
.. program:: project unset
209+
.. code:: bash
210+
211+
os project unset
212+
--property <key> [--property <key> ...]
213+
<project>
214+
215+
.. option:: --property <key>
216+
217+
Property key to remove from project (repeat option to remove multiple properties)
218+
219+
.. describe:: <project>
220+
221+
Project to modify (name or ID)

functional/tests/identity/v2/test_project.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,19 @@ def test_project_set(self):
6868
)
6969
items = self.parse_show(raw_output)
7070
fields = list(self.PROJECT_FIELDS)
71-
fields.extend(['k0'])
71+
fields.extend(['properties'])
7272
self.assert_show_fields(items, fields)
7373
project = self.parse_show_as_object(raw_output)
7474
self.assertEqual(new_project_name, project['name'])
7575
self.assertEqual('False', project['enabled'])
76-
self.assertEqual('v0', project['k0'])
76+
self.assertEqual("k0='v0'", project['properties'])
7777

7878
def test_project_show(self):
7979
project_name = self._create_dummy_project()
8080
raw_output = self.openstack(
8181
'project show %s' % project_name
8282
)
8383
items = self.parse_show(raw_output)
84-
self.assert_show_fields(items, self.PROJECT_FIELDS)
84+
fields = list(self.PROJECT_FIELDS)
85+
fields.extend(['properties'])
86+
self.assert_show_fields(items, fields)

openstackclient/identity/v2_0/project.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,4 +282,60 @@ def take_action(self, parsed_args):
282282

283283
# TODO(stevemar): Remove the line below when we support multitenancy
284284
info.pop('parent_id', None)
285+
286+
# NOTE(stevemar): Property handling isn't really supported in Keystone
287+
# and needs a lot of extra handling. Let's reserve the properties that
288+
# the API has and handle the extra top level properties.
289+
reserved = ('name', 'id', 'enabled', 'description')
290+
properties = {}
291+
for k, v in info.items():
292+
if k not in reserved:
293+
# If a key is not in `reserved` it's a property, pop it
294+
info.pop(k)
295+
# If a property has been "unset" it's `None`, so don't show it
296+
if v is not None:
297+
properties[k] = v
298+
299+
info['properties'] = utils.format_dict(properties)
285300
return zip(*sorted(six.iteritems(info)))
301+
302+
303+
class UnsetProject(command.Command):
304+
"""Unset project properties"""
305+
306+
log = logging.getLogger(__name__ + '.UnsetProject')
307+
308+
def get_parser(self, prog_name):
309+
parser = super(UnsetProject, self).get_parser(prog_name)
310+
parser.add_argument(
311+
'project',
312+
metavar='<project>',
313+
help=_('Project to modify (name or ID)'),
314+
)
315+
parser.add_argument(
316+
'--property',
317+
metavar='<key>',
318+
action='append',
319+
default=[],
320+
help=_('Unset a project property '
321+
'(repeat option to unset multiple properties)'),
322+
required=True,
323+
)
324+
return parser
325+
326+
@utils.log_method(log)
327+
def take_action(self, parsed_args):
328+
identity_client = self.app.client_manager.identity
329+
project = utils.find_resource(
330+
identity_client.tenants,
331+
parsed_args.project,
332+
)
333+
if not parsed_args.property:
334+
self.app.log.error("No changes requested\n")
335+
else:
336+
kwargs = project._info
337+
for key in parsed_args.property:
338+
if key in kwargs:
339+
kwargs[key] = None
340+
identity_client.tenants.update(project.id, **kwargs)
341+
return

openstackclient/tests/identity/v2_0/test_project.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,12 +592,58 @@ def test_project_show(self):
592592
identity_fakes.project_id,
593593
)
594594

595-
collist = ('description', 'enabled', 'id', 'name')
595+
collist = ('description', 'enabled', 'id', 'name', 'properties')
596596
self.assertEqual(collist, columns)
597597
datalist = (
598598
identity_fakes.project_description,
599599
True,
600600
identity_fakes.project_id,
601601
identity_fakes.project_name,
602+
'',
602603
)
603604
self.assertEqual(datalist, data)
605+
606+
607+
class TestProjectUnset(TestProject):
608+
609+
def setUp(self):
610+
super(TestProjectUnset, self).setUp()
611+
612+
project_dict = {'fee': 'fi', 'fo': 'fum'}
613+
project_dict.update(identity_fakes.PROJECT)
614+
self.projects_mock.get.return_value = fakes.FakeResource(
615+
None,
616+
copy.deepcopy(project_dict),
617+
loaded=True,
618+
)
619+
620+
# Get the command object to test
621+
self.cmd = project.UnsetProject(self.app, None)
622+
623+
def test_project_unset_key(self):
624+
arglist = [
625+
'--property', 'fee',
626+
'--property', 'fo',
627+
identity_fakes.project_name,
628+
]
629+
verifylist = [
630+
('property', ['fee', 'fo']),
631+
]
632+
633+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
634+
635+
self.cmd.run(parsed_args)
636+
# Set expected values
637+
kwargs = {
638+
'description': identity_fakes.project_description,
639+
'enabled': True,
640+
'fee': None,
641+
'fo': None,
642+
'id': identity_fakes.project_id,
643+
'name': identity_fakes.project_name,
644+
}
645+
646+
self.projects_mock.update.assert_called_with(
647+
identity_fakes.project_id,
648+
**kwargs
649+
)

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ openstack.identity.v2 =
163163
project_list = openstackclient.identity.v2_0.project:ListProject
164164
project_set = openstackclient.identity.v2_0.project:SetProject
165165
project_show = openstackclient.identity.v2_0.project:ShowProject
166+
project_unset = openstackclient.identity.v2_0.project:UnsetProject
166167

167168
role_add = openstackclient.identity.v2_0.role:AddRole
168169
role_create = openstackclient.identity.v2_0.role:CreateRole

0 commit comments

Comments
 (0)