Skip to content

Commit 2249d00

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Switch server volume update to sdk"
2 parents fa90ad1 + 25b4714 commit 2249d00

File tree

3 files changed

+83
-69
lines changed

3 files changed

+83
-69
lines changed

openstackclient/compute/v2/server_volume.py

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
"""Compute v2 Server action implementations"""
1616

17-
from novaclient import api_versions
1817
from openstack import utils as sdk_utils
1918
from osc_lib.command import command
2019
from osc_lib import exceptions
@@ -83,14 +82,14 @@ class UpdateServerVolume(command.Command):
8382
"""Update a volume attachment on the server."""
8483

8584
def get_parser(self, prog_name):
86-
parser = super(UpdateServerVolume, self).get_parser(prog_name)
85+
parser = super().get_parser(prog_name)
8786
parser.add_argument(
8887
'server',
8988
help=_('Server to update volume for (name or ID)'),
9089
)
9190
parser.add_argument(
9291
'volume',
93-
help=_('Volume (ID)'),
92+
help=_('Volume to update attachment for (name or ID)'),
9493
)
9594
termination_group = parser.add_mutually_exclusive_group()
9695
termination_group.add_argument(
@@ -115,31 +114,29 @@ def get_parser(self, prog_name):
115114
return parser
116115

117116
def take_action(self, parsed_args):
118-
119-
compute_client = self.app.client_manager.compute
117+
compute_client = self.app.client_manager.sdk_connection.compute
118+
volume_client = self.app.client_manager.sdk_connection.volume
120119

121120
if parsed_args.delete_on_termination is not None:
122-
if compute_client.api_version < api_versions.APIVersion('2.85'):
121+
if not sdk_utils.supports_microversion(compute_client, '2.85'):
123122
msg = _(
124123
'--os-compute-api-version 2.85 or greater is required to '
125-
'support the --(no-)delete-on-termination option'
124+
'support the -delete-on-termination or '
125+
'--preserve-on-termination option'
126126
)
127127
raise exceptions.CommandError(msg)
128128

129-
server = utils.find_resource(
130-
compute_client.servers,
129+
server = compute_client.find_server(
131130
parsed_args.server,
131+
ignore_missing=False,
132132
)
133-
134-
# NOTE(stephenfin): This may look silly, and that's because it is.
135-
# This API was originally used only for the swapping volumes, which
136-
# is an internal operation that should only be done by
137-
# orchestration software rather than a human. We're not going to
138-
# expose that, but we are going to expose the ability to change the
139-
# delete on termination behavior.
140-
compute_client.volumes.update_server_volume(
141-
server.id,
142-
parsed_args.volume,
133+
volume = volume_client.find_volume(
143134
parsed_args.volume,
135+
ignore_missing=False,
136+
)
137+
138+
compute_client.update_volume_attachment(
139+
server,
140+
volume,
144141
delete_on_termination=parsed_args.delete_on_termination,
145142
)

openstackclient/tests/unit/compute/v2/test_server_volume.py

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,19 @@
1919

2020
from openstackclient.compute.v2 import server_volume
2121
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
22+
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
2223

2324

2425
class TestServerVolume(compute_fakes.TestComputev2):
2526

2627
def setUp(self):
2728
super().setUp()
2829

29-
# Get a shortcut to the compute client ServerManager Mock
30-
self.servers_mock = self.app.client_manager.compute.servers
31-
self.servers_mock.reset_mock()
32-
33-
# Get a shortcut to the compute client VolumeManager mock
34-
self.servers_volumes_mock = self.app.client_manager.compute.volumes
35-
self.servers_volumes_mock.reset_mock()
36-
3730
self.app.client_manager.sdk_connection = mock.Mock()
3831
self.app.client_manager.sdk_connection.compute = mock.Mock()
39-
self.sdk_client = self.app.client_manager.sdk_connection.compute
32+
self.app.client_manager.sdk_connection.volume = mock.Mock()
33+
self.compute_client = self.app.client_manager.sdk_connection.compute
34+
self.volume_client = self.app.client_manager.sdk_connection.volume
4035

4136

4237
class TestServerVolumeList(TestServerVolume):
@@ -47,8 +42,8 @@ def setUp(self):
4742
self.server = compute_fakes.FakeServer.create_one_sdk_server()
4843
self.volume_attachments = compute_fakes.create_volume_attachments()
4944

50-
self.sdk_client.find_server.return_value = self.server
51-
self.sdk_client.volume_attachments.return_value = (
45+
self.compute_client.find_server.return_value = self.server
46+
self.compute_client.volume_attachments.return_value = (
5247
self.volume_attachments)
5348

5449
# Get the command object to test
@@ -88,7 +83,9 @@ def test_server_volume_list(self, sm_mock):
8883
),
8984
tuple(data),
9085
)
91-
self.sdk_client.volume_attachments.assert_called_once_with(self.server)
86+
self.compute_client.volume_attachments.assert_called_once_with(
87+
self.server,
88+
)
9289

9390
@mock.patch.object(sdk_utils, 'supports_microversion')
9491
def test_server_volume_list_with_tags(self, sm_mock):
@@ -126,7 +123,9 @@ def test_server_volume_list_with_tags(self, sm_mock):
126123
),
127124
tuple(data),
128125
)
129-
self.sdk_client.volume_attachments.assert_called_once_with(self.server)
126+
self.compute_client.volume_attachments.assert_called_once_with(
127+
self.server,
128+
)
130129

131130
@mock.patch.object(sdk_utils, 'supports_microversion')
132131
def test_server_volume_list_with_delete_on_attachment(self, sm_mock):
@@ -169,7 +168,9 @@ def test_server_volume_list_with_delete_on_attachment(self, sm_mock):
169168
),
170169
tuple(data),
171170
)
172-
self.sdk_client.volume_attachments.assert_called_once_with(self.server)
171+
self.compute_client.volume_attachments.assert_called_once_with(
172+
self.server,
173+
)
173174

174175
@mock.patch.object(sdk_utils, 'supports_microversion')
175176
def test_server_volume_list_with_attachment_ids(self, sm_mock):
@@ -217,123 +218,139 @@ def test_server_volume_list_with_attachment_ids(self, sm_mock):
217218
),
218219
tuple(data),
219220
)
220-
self.sdk_client.volume_attachments.assert_called_once_with(self.server)
221+
self.compute_client.volume_attachments.assert_called_once_with(
222+
self.server,
223+
)
221224

222225

223226
class TestServerVolumeUpdate(TestServerVolume):
224227

225228
def setUp(self):
226229
super().setUp()
227230

228-
self.server = compute_fakes.FakeServer.create_one_server()
229-
self.servers_mock.get.return_value = self.server
231+
self.server = compute_fakes.FakeServer.create_one_sdk_server()
232+
self.compute_client.find_server.return_value = self.server
233+
234+
self.volume = volume_fakes.create_one_sdk_volume()
235+
self.volume_client.find_volume.return_value = self.volume
230236

231237
# Get the command object to test
232238
self.cmd = server_volume.UpdateServerVolume(self.app, None)
233239

234240
def test_server_volume_update(self):
235-
236241
arglist = [
237242
self.server.id,
238-
'foo',
243+
self.volume.id,
239244
]
240245
verifylist = [
241246
('server', self.server.id),
242-
('volume', 'foo'),
247+
('volume', self.volume.id),
243248
('delete_on_termination', None),
244249
]
245250
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
246251

247252
result = self.cmd.take_action(parsed_args)
248253

249254
# This is a no-op
250-
self.servers_volumes_mock.update_server_volume.assert_not_called()
255+
self.compute_client.update_volume_attachment.assert_not_called()
251256
self.assertIsNone(result)
252257

253-
def test_server_volume_update_with_delete_on_termination(self):
254-
self.app.client_manager.compute.api_version = \
255-
api_versions.APIVersion('2.85')
258+
@mock.patch.object(sdk_utils, 'supports_microversion')
259+
def test_server_volume_update_with_delete_on_termination(self, sm_mock):
260+
sm_mock.return_value = True
256261

257262
arglist = [
258263
self.server.id,
259-
'foo',
264+
self.volume.id,
260265
'--delete-on-termination',
261266
]
262267
verifylist = [
263268
('server', self.server.id),
264-
('volume', 'foo'),
269+
('volume', self.volume.id),
265270
('delete_on_termination', True),
266271
]
267272
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
268273

269274
result = self.cmd.take_action(parsed_args)
270275

271-
self.servers_volumes_mock.update_server_volume.assert_called_once_with(
272-
self.server.id, 'foo', 'foo',
273-
delete_on_termination=True)
276+
self.compute_client.update_volume_attachment.assert_called_once_with(
277+
self.server,
278+
self.volume,
279+
delete_on_termination=True,
280+
)
274281
self.assertIsNone(result)
275282

276-
def test_server_volume_update_with_preserve_on_termination(self):
277-
self.app.client_manager.compute.api_version = \
278-
api_versions.APIVersion('2.85')
283+
@mock.patch.object(sdk_utils, 'supports_microversion')
284+
def test_server_volume_update_with_preserve_on_termination(self, sm_mock):
285+
sm_mock.return_value = True
279286

280287
arglist = [
281288
self.server.id,
282-
'foo',
289+
self.volume.id,
283290
'--preserve-on-termination',
284291
]
285292
verifylist = [
286293
('server', self.server.id),
287-
('volume', 'foo'),
294+
('volume', self.volume.id),
288295
('delete_on_termination', False),
289296
]
290297
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
291298

292299
result = self.cmd.take_action(parsed_args)
293300

294-
self.servers_volumes_mock.update_server_volume.assert_called_once_with(
295-
self.server.id, 'foo', 'foo',
296-
delete_on_termination=False)
301+
self.compute_client.update_volume_attachment.assert_called_once_with(
302+
self.server,
303+
self.volume,
304+
delete_on_termination=False
305+
)
297306
self.assertIsNone(result)
298307

299-
def test_server_volume_update_with_delete_on_termination_pre_v285(self):
300-
self.app.client_manager.compute.api_version = \
301-
api_versions.APIVersion('2.84')
308+
@mock.patch.object(sdk_utils, 'supports_microversion')
309+
def test_server_volume_update_with_delete_on_termination_pre_v285(
310+
self, sm_mock,
311+
):
312+
sm_mock.return_value = False
302313

303314
arglist = [
304315
self.server.id,
305-
'foo',
316+
self.volume.id,
306317
'--delete-on-termination',
307318
]
308319
verifylist = [
309320
('server', self.server.id),
310-
('volume', 'foo'),
321+
('volume', self.volume.id),
311322
('delete_on_termination', True),
312323
]
313324
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
314325

315326
self.assertRaises(
316327
exceptions.CommandError,
317328
self.cmd.take_action,
318-
parsed_args)
329+
parsed_args,
330+
)
331+
self.compute_client.update_volume_attachment.assert_not_called()
319332

320-
def test_server_volume_update_with_preserve_on_termination_pre_v285(self):
321-
self.app.client_manager.compute.api_version = \
322-
api_versions.APIVersion('2.84')
333+
@mock.patch.object(sdk_utils, 'supports_microversion')
334+
def test_server_volume_update_with_preserve_on_termination_pre_v285(
335+
self, sm_mock,
336+
):
337+
sm_mock.return_value = False
323338

324339
arglist = [
325340
self.server.id,
326-
'foo',
341+
self.volume.id,
327342
'--preserve-on-termination',
328343
]
329344
verifylist = [
330345
('server', self.server.id),
331-
('volume', 'foo'),
346+
('volume', self.volume.id),
332347
('delete_on_termination', False),
333348
]
334349
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
335350

336351
self.assertRaises(
337352
exceptions.CommandError,
338353
self.cmd.take_action,
339-
parsed_args)
354+
parsed_args,
355+
)
356+
self.compute_client.update_volume_attachment.assert_not_called()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
features:
22
- |
3-
Switch the server volume list command from novaclient to SDK.
3+
Switch the server volume list and server volume update command from novaclient to SDK.

0 commit comments

Comments
 (0)