Skip to content

Commit 35833c9

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Add set feature to volume type v2"
2 parents 8affa0d + 429ceef commit 35833c9

4 files changed

Lines changed: 240 additions & 4 deletions

File tree

doc/source/command-objects/volume-type.rst

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,29 @@ List volume types
7777
volume type set
7878
---------------
7979

80-
*Only supported for Volume API v1*
81-
8280
Set volume type properties
8381

8482
.. program:: volume type set
8583
.. code:: bash
8684
8785
os volume type set
86+
[--name <name>]
87+
[--description <description>]
8888
[--property <key=value> [...] ]
8989
<volume-type>
9090
91+
.. option:: --name <name>
92+
93+
Set volume type name
94+
95+
.. versionadded:: 2
96+
97+
.. option:: --description <description>
98+
99+
Set volume type description
100+
101+
.. versionadded:: 2
102+
91103
.. option:: --property <key=value>
92104

93105
Property to add or modify for this volume type (repeat option to set multiple properties)
@@ -99,8 +111,6 @@ Set volume type properties
99111
volume type unset
100112
-----------------
101113

102-
*Only supported for Volume API v1*
103-
104114
Unset volume type properties
105115

106116
.. program:: volume type unset

openstackclient/tests/volume/v2/test_type.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@
1919
from openstackclient.volume.v2 import volume_type
2020

2121

22+
class FakeTypeResource(fakes.FakeResource):
23+
24+
_keys = {'property': 'value'}
25+
26+
def set_keys(self, args):
27+
self._keys.update(args)
28+
29+
def unset_keys(self, key):
30+
self._keys.pop(key, None)
31+
32+
def get_keys(self):
33+
return self._keys
34+
35+
2236
class TestType(volume_fakes.TestVolume):
2337

2438
def setUp(self):
@@ -184,6 +198,122 @@ def test_type_show(self):
184198
self.assertEqual(volume_fakes.TYPE_FORMATTED_data, data)
185199

186200

201+
class TestTypeSet(TestType):
202+
203+
def setUp(self):
204+
super(TestTypeSet, self).setUp()
205+
206+
self.types_mock.get.return_value = FakeTypeResource(
207+
None,
208+
copy.deepcopy(volume_fakes.TYPE),
209+
loaded=True,
210+
)
211+
212+
# Get the command object to test
213+
self.cmd = volume_type.SetVolumeType(self.app, None)
214+
215+
def test_type_set_name(self):
216+
new_name = 'new_name'
217+
arglist = [
218+
'--name', new_name,
219+
volume_fakes.type_id,
220+
]
221+
verifylist = [
222+
('name', new_name),
223+
('description', None),
224+
('property', None),
225+
('volume_type', volume_fakes.type_id),
226+
]
227+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
228+
229+
self.cmd.take_action(parsed_args)
230+
231+
# Set expected values
232+
kwargs = {
233+
'name': new_name,
234+
}
235+
self.types_mock.update.assert_called_with(
236+
volume_fakes.type_id,
237+
**kwargs
238+
)
239+
240+
def test_type_set_description(self):
241+
new_desc = 'new_desc'
242+
arglist = [
243+
'--description', new_desc,
244+
volume_fakes.type_id,
245+
]
246+
verifylist = [
247+
('name', None),
248+
('description', new_desc),
249+
('property', None),
250+
('volume_type', volume_fakes.type_id),
251+
]
252+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
253+
254+
self.cmd.take_action(parsed_args)
255+
256+
# Set expected values
257+
kwargs = {
258+
'description': new_desc,
259+
}
260+
self.types_mock.update.assert_called_with(
261+
volume_fakes.type_id,
262+
**kwargs
263+
)
264+
265+
def test_type_set_property(self):
266+
arglist = [
267+
'--property', 'myprop=myvalue',
268+
volume_fakes.type_id,
269+
]
270+
verifylist = [
271+
('name', None),
272+
('description', None),
273+
('property', {'myprop': 'myvalue'}),
274+
('volume_type', volume_fakes.type_id),
275+
]
276+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
277+
278+
self.cmd.take_action(parsed_args)
279+
280+
result = self.types_mock.get.return_value._keys
281+
self.assertIn('myprop', result)
282+
self.assertEqual('myvalue', result['myprop'])
283+
284+
285+
class TestTypeUnset(TestType):
286+
287+
def setUp(self):
288+
super(TestTypeUnset, self).setUp()
289+
290+
self.types_mock.get.return_value = FakeTypeResource(
291+
None,
292+
copy.deepcopy(volume_fakes.TYPE),
293+
loaded=True,
294+
)
295+
296+
self.cmd = volume_type.UnsetVolumeType(self.app, None)
297+
298+
def test_type_unset(self):
299+
arglist = [
300+
'--property', 'property',
301+
volume_fakes.type_id,
302+
]
303+
verifylist = [
304+
('property', 'property'),
305+
('volume_type', volume_fakes.type_id),
306+
]
307+
308+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
309+
310+
self.cmd.take_action(parsed_args)
311+
312+
result = self.types_mock.get.return_value._keys
313+
314+
self.assertNotIn('property', result)
315+
316+
187317
class TestTypeDelete(TestType):
188318
def setUp(self):
189319
super(TestTypeDelete, self).setUp()

openstackclient/volume/v2/volume_type.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,67 @@ def take_action(self, parsed_args):
143143
) for s in data))
144144

145145

146+
class SetVolumeType(command.Command):
147+
"""Set volume type properties"""
148+
149+
log = logging.getLogger(__name__ + '.SetVolumeType')
150+
151+
def get_parser(self, prog_name):
152+
parser = super(SetVolumeType, self).get_parser(prog_name)
153+
parser.add_argument(
154+
'volume_type',
155+
metavar='<volume-type>',
156+
help='Volume type to modify (name or ID)',
157+
)
158+
parser.add_argument(
159+
'--name',
160+
metavar='<name>',
161+
help='Set volume type name',
162+
)
163+
parser.add_argument(
164+
'--description',
165+
metavar='<name>',
166+
help='Set volume type description',
167+
)
168+
parser.add_argument(
169+
'--property',
170+
metavar='<key=value>',
171+
action=parseractions.KeyValueAction,
172+
help='Property to add or modify for this volume type '
173+
'(repeat option to set multiple properties)',
174+
)
175+
return parser
176+
177+
def take_action(self, parsed_args):
178+
self.log.debug('take_action(%s)', parsed_args)
179+
volume_client = self.app.client_manager.volume
180+
volume_type = utils.find_resource(
181+
volume_client.volume_types, parsed_args.volume_type)
182+
183+
if (not parsed_args.name
184+
and not parsed_args.description
185+
and not parsed_args.property):
186+
self.app.log.error("No changes requested\n")
187+
return
188+
189+
kwargs = {}
190+
if parsed_args.name:
191+
kwargs['name'] = parsed_args.name
192+
if parsed_args.description:
193+
kwargs['description'] = parsed_args.description
194+
195+
if kwargs:
196+
volume_client.volume_types.update(
197+
volume_type.id,
198+
**kwargs
199+
)
200+
201+
if parsed_args.property:
202+
volume_type.set_keys(parsed_args.property)
203+
204+
return
205+
206+
146207
class ShowVolumeType(show.ShowOne):
147208
"""Display volume type details"""
148209

@@ -165,3 +226,36 @@ def take_action(self, parsed_args):
165226
properties = utils.format_dict(volume_type._info.pop('extra_specs'))
166227
volume_type._info.update({'properties': properties})
167228
return zip(*sorted(six.iteritems(volume_type._info)))
229+
230+
231+
class UnsetVolumeType(command.Command):
232+
"""Unset volume type properties"""
233+
234+
log = logging.getLogger(__name__ + '.UnsetVolumeType')
235+
236+
def get_parser(self, prog_name):
237+
parser = super(UnsetVolumeType, self).get_parser(prog_name)
238+
parser.add_argument(
239+
'volume_type',
240+
metavar='<volume-type>',
241+
help='Volume type to modify (name or ID)',
242+
)
243+
parser.add_argument(
244+
'--property',
245+
metavar='<key>',
246+
default=[],
247+
required=True,
248+
help='Property to remove from volume type '
249+
'(repeat option to remove multiple properties)',
250+
)
251+
return parser
252+
253+
def take_action(self, parsed_args):
254+
self.log.debug('take_action(%s)', parsed_args)
255+
volume_client = self.app.client_manager.volume
256+
volume_type = utils.find_resource(
257+
volume_client.volume_types,
258+
parsed_args.volume_type,
259+
)
260+
volume_type.unset_keys(parsed_args.property)
261+
return

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,9 @@ openstack.volume.v2 =
403403
volume_type_create = openstackclient.volume.v2.volume_type:CreateVolumeType
404404
volume_type_delete = openstackclient.volume.v2.volume_type:DeleteVolumeType
405405
volume_type_list = openstackclient.volume.v2.volume_type:ListVolumeType
406+
volume_type_set = openstackclient.volume.v2.volume_type:SetVolumeType
406407
volume_type_show = openstackclient.volume.v2.volume_type:ShowVolumeType
408+
volume_type_unset = openstackclient.volume.v2.volume_type:UnsetVolumeType
407409

408410
volume_qos_associate = openstackclient.volume.v2.qos_specs:AssociateQos
409411
volume_qos_create = openstackclient.volume.v2.qos_specs:CreateQos

0 commit comments

Comments
 (0)