volume: Migrate 'volume attachment *' to SDK
This patch migrates the volume attachment create, get, list, delete, update and complete commands to SDK. Change-Id: Ib237d25cc1c3fc72946b9d088ff3447433162130
This commit is contained in:
parent
402327f2e4
commit
9f30ee9af2
@ -24,6 +24,7 @@ from openstack.block_storage.v3 import backup as _backup
|
|||||||
from openstack.block_storage.v3 import extension as _extension
|
from openstack.block_storage.v3 import extension as _extension
|
||||||
from openstack.block_storage.v3 import resource_filter as _filters
|
from openstack.block_storage.v3 import resource_filter as _filters
|
||||||
from openstack.block_storage.v3 import volume as _volume
|
from openstack.block_storage.v3 import volume as _volume
|
||||||
|
from openstack.compute.v2 import _proxy as _compute_proxy
|
||||||
from openstack.image.v2 import _proxy as _image_proxy
|
from openstack.image.v2 import _proxy as _image_proxy
|
||||||
|
|
||||||
from openstackclient.tests.unit import fakes
|
from openstackclient.tests.unit import fakes
|
||||||
@ -129,16 +130,16 @@ class TestVolume(
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
# avoid circular imports
|
# avoid circular imports by defining this manually rather than using
|
||||||
from openstackclient.tests.unit.compute.v2 import (
|
# openstackclient.tests.unit.compute.v2.fakes.FakeClientMixin
|
||||||
fakes as compute_fakes,
|
# TODO(stephenfin): Rename to 'compute_client' once all commands are
|
||||||
|
# migrated to SDK
|
||||||
|
self.app.client_manager.sdk_connection.compute = mock.Mock(
|
||||||
|
_compute_proxy.Proxy
|
||||||
)
|
)
|
||||||
|
self.compute_sdk_client = (
|
||||||
self.app.client_manager.compute = compute_fakes.FakeComputev2Client(
|
self.app.client_manager.sdk_connection.compute
|
||||||
endpoint=fakes.AUTH_URL,
|
|
||||||
token=fakes.AUTH_TOKEN,
|
|
||||||
)
|
)
|
||||||
self.compute_client = self.app.client_manager.compute
|
|
||||||
|
|
||||||
# avoid circular imports by defining this manually rather than using
|
# avoid circular imports by defining this manually rather than using
|
||||||
# openstackclient.tests.unit.image.v2.fakes.FakeClientMixin
|
# openstackclient.tests.unit.image.v2.fakes.FakeClientMixin
|
||||||
|
@ -23,22 +23,12 @@ class TestVolumeAttachment(volume_fakes.TestVolume):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.volumes_mock = self.volume_client.volumes
|
self.projects_mock = self.app.client_manager.identity.projects
|
||||||
self.volumes_mock.reset_mock()
|
|
||||||
|
|
||||||
self.volume_attachments_mock = self.volume_client.attachments
|
|
||||||
self.volume_attachments_mock.reset_mock()
|
|
||||||
|
|
||||||
self.projects_mock = self.identity_client.projects
|
|
||||||
self.projects_mock.reset_mock()
|
|
||||||
|
|
||||||
self.servers_mock = self.compute_client.servers
|
|
||||||
self.servers_mock.reset_mock()
|
|
||||||
|
|
||||||
|
|
||||||
class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
||||||
volume = volume_fakes.create_one_volume()
|
volume = volume_fakes.create_one_volume()
|
||||||
server = compute_fakes.create_one_server()
|
server = compute_fakes.create_one_sdk_server()
|
||||||
volume_attachment = volume_fakes.create_one_volume_attachment(
|
volume_attachment = volume_fakes.create_one_volume_attachment(
|
||||||
attrs={'instance': server.id, 'volume_id': volume.id},
|
attrs={'instance': server.id, 'volume_id': volume.id},
|
||||||
)
|
)
|
||||||
@ -67,12 +57,11 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.volumes_mock.get.return_value = self.volume
|
self.volume_sdk_client.find_volume.return_value = self.volume
|
||||||
self.servers_mock.get.return_value = self.server
|
self.volume_sdk_client.create_attachment.return_value = (
|
||||||
# VolumeAttachmentManager.create returns a dict
|
|
||||||
self.volume_attachments_mock.create.return_value = (
|
|
||||||
self.volume_attachment.to_dict()
|
self.volume_attachment.to_dict()
|
||||||
)
|
)
|
||||||
|
self.compute_sdk_client.find_server.return_value = self.server
|
||||||
|
|
||||||
self.cmd = volume_attachment.CreateVolumeAttachment(self.app, None)
|
self.cmd = volume_attachment.CreateVolumeAttachment(self.app, None)
|
||||||
|
|
||||||
@ -100,13 +89,17 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
|||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.volumes_mock.get.assert_called_once_with(self.volume.id)
|
self.volume_sdk_client.find_volume.assert_called_once_with(
|
||||||
self.servers_mock.get.assert_called_once_with(self.server.id)
|
self.volume.id, ignore_missing=False
|
||||||
self.volume_attachments_mock.create.assert_called_once_with(
|
)
|
||||||
|
self.compute_sdk_client.find_server.assert_called_once_with(
|
||||||
|
self.server.id, ignore_missing=False
|
||||||
|
)
|
||||||
|
self.volume_sdk_client.create_attachment.assert_called_once_with(
|
||||||
self.volume.id,
|
self.volume.id,
|
||||||
{},
|
connector={},
|
||||||
self.server.id,
|
instance=self.server.id,
|
||||||
None,
|
mode=None,
|
||||||
)
|
)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertCountEqual(self.data, data)
|
self.assertCountEqual(self.data, data)
|
||||||
@ -163,13 +156,17 @@ class TestVolumeAttachmentCreate(TestVolumeAttachment):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
self.volumes_mock.get.assert_called_once_with(self.volume.id)
|
self.volume_sdk_client.find_volume.assert_called_once_with(
|
||||||
self.servers_mock.get.assert_called_once_with(self.server.id)
|
self.volume.id, ignore_missing=False
|
||||||
self.volume_attachments_mock.create.assert_called_once_with(
|
)
|
||||||
|
self.compute_sdk_client.find_server.assert_called_once_with(
|
||||||
|
self.server.id, ignore_missing=False
|
||||||
|
)
|
||||||
|
self.volume_sdk_client.create_attachment.assert_called_once_with(
|
||||||
self.volume.id,
|
self.volume.id,
|
||||||
connect_info,
|
connector=connect_info,
|
||||||
self.server.id,
|
instance=self.server.id,
|
||||||
'null',
|
mode='null',
|
||||||
)
|
)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertCountEqual(self.data, data)
|
self.assertCountEqual(self.data, data)
|
||||||
@ -248,7 +245,7 @@ class TestVolumeAttachmentDelete(TestVolumeAttachment):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.volume_attachments_mock.delete.return_value = None
|
self.volume_sdk_client.delete_attachment.return_value = None
|
||||||
|
|
||||||
self.cmd = volume_attachment.DeleteVolumeAttachment(self.app, None)
|
self.cmd = volume_attachment.DeleteVolumeAttachment(self.app, None)
|
||||||
|
|
||||||
@ -265,7 +262,7 @@ class TestVolumeAttachmentDelete(TestVolumeAttachment):
|
|||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.volume_attachments_mock.delete.assert_called_once_with(
|
self.volume_sdk_client.delete_attachment.assert_called_once_with(
|
||||||
self.volume_attachment.id,
|
self.volume_attachment.id,
|
||||||
)
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
@ -316,7 +313,7 @@ class TestVolumeAttachmentSet(TestVolumeAttachment):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.volume_attachments_mock.update.return_value = (
|
self.volume_sdk_client.update_attachment.return_value = (
|
||||||
self.volume_attachment
|
self.volume_attachment
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -367,9 +364,9 @@ class TestVolumeAttachmentSet(TestVolumeAttachment):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
self.volume_attachments_mock.update.assert_called_once_with(
|
self.volume_sdk_client.update_attachment.assert_called_once_with(
|
||||||
self.volume_attachment.id,
|
self.volume_attachment.id,
|
||||||
connect_info,
|
connector=connect_info,
|
||||||
)
|
)
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertCountEqual(self.data, data)
|
self.assertCountEqual(self.data, data)
|
||||||
@ -402,7 +399,7 @@ class TestVolumeAttachmentComplete(TestVolumeAttachment):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.volume_attachments_mock.complete.return_value = None
|
self.volume_sdk_client.complete_attachment.return_value = None
|
||||||
|
|
||||||
self.cmd = volume_attachment.CompleteVolumeAttachment(self.app, None)
|
self.cmd = volume_attachment.CompleteVolumeAttachment(self.app, None)
|
||||||
|
|
||||||
@ -419,7 +416,7 @@ class TestVolumeAttachmentComplete(TestVolumeAttachment):
|
|||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.volume_attachments_mock.complete.assert_called_once_with(
|
self.volume_sdk_client.complete_attachment.assert_called_once_with(
|
||||||
self.volume_attachment.id,
|
self.volume_attachment.id,
|
||||||
)
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
@ -467,7 +464,7 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
|
|||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.projects_mock.get.return_value = self.project
|
self.projects_mock.get.return_value = self.project
|
||||||
self.volume_attachments_mock.list.return_value = (
|
self.volume_sdk_client.attachments.return_value = (
|
||||||
self.volume_attachments
|
self.volume_attachments
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -489,7 +486,7 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
|
|||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.volume_attachments_mock.list.assert_called_once_with(
|
self.volume_sdk_client.attachments.assert_called_once_with(
|
||||||
search_opts={
|
search_opts={
|
||||||
'all_tenants': False,
|
'all_tenants': False,
|
||||||
'project_id': None,
|
'project_id': None,
|
||||||
@ -529,7 +526,7 @@ class TestVolumeAttachmentList(TestVolumeAttachment):
|
|||||||
|
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.volume_attachments_mock.list.assert_called_once_with(
|
self.volume_sdk_client.attachments.assert_called_once_with(
|
||||||
search_opts={
|
search_opts={
|
||||||
'all_tenants': True,
|
'all_tenants': True,
|
||||||
'project_id': self.project.id,
|
'project_id': self.project.id,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from cinderclient import api_versions
|
from openstack import utils as sdk_utils
|
||||||
from osc_lib.cli import format_columns
|
from osc_lib.cli import format_columns
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
from osc_lib import exceptions
|
from osc_lib import exceptions
|
||||||
@ -170,10 +170,10 @@ class CreateVolumeAttachment(command.ShowOne):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
volume_client = self.app.client_manager.volume
|
volume_client = self.app.client_manager.sdk_connection.volume
|
||||||
compute_client = self.app.client_manager.compute
|
compute_client = self.app.client_manager.sdk_connection.compute
|
||||||
|
|
||||||
if volume_client.api_version < api_versions.APIVersion('3.27'):
|
if not sdk_utils.supports_microversion(volume_client, '3.27'):
|
||||||
msg = _(
|
msg = _(
|
||||||
"--os-volume-api-version 3.27 or greater is required to "
|
"--os-volume-api-version 3.27 or greater is required to "
|
||||||
"support the 'volume attachment create' command"
|
"support the 'volume attachment create' command"
|
||||||
@ -181,7 +181,7 @@ class CreateVolumeAttachment(command.ShowOne):
|
|||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
if parsed_args.mode:
|
if parsed_args.mode:
|
||||||
if volume_client.api_version < api_versions.APIVersion('3.54'):
|
if not sdk_utils.supports_microversion(volume_client, '3.54'):
|
||||||
msg = _(
|
msg = _(
|
||||||
"--os-volume-api-version 3.54 or greater is required to "
|
"--os-volume-api-version 3.54 or greater is required to "
|
||||||
"support the '--mode' option"
|
"support the '--mode' option"
|
||||||
@ -218,17 +218,18 @@ class CreateVolumeAttachment(command.ShowOne):
|
|||||||
)
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
volume = utils.find_resource(
|
volume = volume_client.find_volume(
|
||||||
volume_client.volumes,
|
parsed_args.volume, ignore_missing=False
|
||||||
parsed_args.volume,
|
|
||||||
)
|
)
|
||||||
server = utils.find_resource(
|
server = compute_client.find_server(
|
||||||
compute_client.servers,
|
parsed_args.server, ignore_missing=False
|
||||||
parsed_args.server,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
attachment = volume_client.attachments.create(
|
attachment = volume_client.create_attachment(
|
||||||
volume.id, connector, server.id, parsed_args.mode
|
volume.id,
|
||||||
|
connector=connector,
|
||||||
|
instance=server.id,
|
||||||
|
mode=parsed_args.mode,
|
||||||
)
|
)
|
||||||
|
|
||||||
return _format_attachment(attachment)
|
return _format_attachment(attachment)
|
||||||
@ -256,16 +257,16 @@ class DeleteVolumeAttachment(command.Command):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
volume_client = self.app.client_manager.volume
|
volume_client = self.app.client_manager.sdk_connection.volume
|
||||||
|
|
||||||
if volume_client.api_version < api_versions.APIVersion('3.27'):
|
if not sdk_utils.supports_microversion(volume_client, '3.27'):
|
||||||
msg = _(
|
msg = _(
|
||||||
"--os-volume-api-version 3.27 or greater is required to "
|
"--os-volume-api-version 3.27 or greater is required to "
|
||||||
"support the 'volume attachment delete' command"
|
"support the 'volume attachment delete' command"
|
||||||
)
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
volume_client.attachments.delete(parsed_args.attachment)
|
volume_client.delete_attachment(parsed_args.attachment)
|
||||||
|
|
||||||
|
|
||||||
class SetVolumeAttachment(command.ShowOne):
|
class SetVolumeAttachment(command.ShowOne):
|
||||||
@ -330,9 +331,9 @@ class SetVolumeAttachment(command.ShowOne):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
volume_client = self.app.client_manager.volume
|
volume_client = self.app.client_manager.sdk_connection.volume
|
||||||
|
|
||||||
if volume_client.api_version < api_versions.APIVersion('3.27'):
|
if not sdk_utils.supports_microversion(volume_client, '3.27'):
|
||||||
msg = _(
|
msg = _(
|
||||||
"--os-volume-api-version 3.27 or greater is required to "
|
"--os-volume-api-version 3.27 or greater is required to "
|
||||||
"support the 'volume attachment set' command"
|
"support the 'volume attachment set' command"
|
||||||
@ -349,8 +350,9 @@ class SetVolumeAttachment(command.ShowOne):
|
|||||||
'mountpoint': parsed_args.mountpoint,
|
'mountpoint': parsed_args.mountpoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
attachment = volume_client.attachments.update(
|
attachment = volume_client.update_attachment(
|
||||||
parsed_args.attachment, connector
|
parsed_args.attachment,
|
||||||
|
connector=connector,
|
||||||
)
|
)
|
||||||
|
|
||||||
return _format_attachment(attachment)
|
return _format_attachment(attachment)
|
||||||
@ -369,16 +371,16 @@ class CompleteVolumeAttachment(command.Command):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
volume_client = self.app.client_manager.volume
|
volume_client = self.app.client_manager.sdk_connection.volume
|
||||||
|
|
||||||
if volume_client.api_version < api_versions.APIVersion('3.44'):
|
if not sdk_utils.supports_microversion(volume_client, '3.44'):
|
||||||
msg = _(
|
msg = _(
|
||||||
"--os-volume-api-version 3.44 or greater is required to "
|
"--os-volume-api-version 3.44 or greater is required to "
|
||||||
"support the 'volume attachment complete' command"
|
"support the 'volume attachment complete' command"
|
||||||
)
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
volume_client.attachments.complete(parsed_args.attachment)
|
volume_client.complete_attachment(parsed_args.attachment)
|
||||||
|
|
||||||
|
|
||||||
class ListVolumeAttachment(command.Lister):
|
class ListVolumeAttachment(command.Lister):
|
||||||
@ -429,10 +431,10 @@ class ListVolumeAttachment(command.Lister):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
volume_client = self.app.client_manager.volume
|
volume_client = self.app.client_manager.sdk_connection.volume
|
||||||
identity_client = self.app.client_manager.identity
|
identity_client = self.app.client_manager.identity
|
||||||
|
|
||||||
if volume_client.api_version < api_versions.APIVersion('3.27'):
|
if not sdk_utils.supports_microversion(volume_client, '3.27'):
|
||||||
msg = _(
|
msg = _(
|
||||||
"--os-volume-api-version 3.27 or greater is required to "
|
"--os-volume-api-version 3.27 or greater is required to "
|
||||||
"support the 'volume attachment list' command"
|
"support the 'volume attachment list' command"
|
||||||
@ -458,7 +460,7 @@ class ListVolumeAttachment(command.Lister):
|
|||||||
# search_opts.update(shell_utils.extract_filters(AppendFilters.filters))
|
# search_opts.update(shell_utils.extract_filters(AppendFilters.filters))
|
||||||
|
|
||||||
# TODO(stephenfin): Implement sorting
|
# TODO(stephenfin): Implement sorting
|
||||||
attachments = volume_client.attachments.list(
|
attachments = volume_client.attachments(
|
||||||
search_opts=search_opts,
|
search_opts=search_opts,
|
||||||
marker=parsed_args.marker,
|
marker=parsed_args.marker,
|
||||||
limit=parsed_args.limit,
|
limit=parsed_args.limit,
|
||||||
@ -496,15 +498,15 @@ class ShowVolumeAttachment(command.ShowOne):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
volume_client = self.app.client_manager.volume
|
volume_client = self.app.client_manager.sdk_connection.volume
|
||||||
|
|
||||||
if volume_client.api_version < api_versions.APIVersion('3.27'):
|
if not sdk_utils.supports_microversion(volume_client, '3.27'):
|
||||||
msg = _(
|
msg = _(
|
||||||
"--os-volume-api-version 3.27 or greater is required to "
|
"--os-volume-api-version 3.27 or greater is required to "
|
||||||
"support the 'volume attachment show' command"
|
"support the 'volume attachment show' command"
|
||||||
)
|
)
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
attachment = volume_client.attachments.show(parsed_args.attachment)
|
attachment = volume_client.get_attachment(parsed_args.attachment)
|
||||||
|
|
||||||
return _format_attachment(attachment)
|
return _format_attachment(attachment)
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Migrated volume attachment commands to SDK.
|
Loading…
Reference in New Issue
Block a user