diff --git a/doc/source/command-objects/volume-transfer-request.rst b/doc/source/command-objects/volume-transfer-request.rst index 4729999574..b89289a81e 100644 --- a/doc/source/command-objects/volume-transfer-request.rst +++ b/doc/source/command-objects/volume-transfer-request.rst @@ -4,6 +4,27 @@ volume transfer request Block Storage v1, v2 +volume transfer request accept +------------------------------ + +Accept volume transfer request + +.. program:: volume transfer request accept +.. code:: bash + + os volume transfer request accept + + + +.. _volume_transfer_request_accept: +.. describe:: + + Volume transfer request to accept (name or ID) + +.. describe:: + + Authentication key of transfer request + volume transfer request create ------------------------------ @@ -56,3 +77,19 @@ Lists all volume transfer requests. Shows detail for all projects. Admin only. (defaults to False) + +volume transfer request show +---------------------------- + +Show volume transfer request details + +.. program:: volume transfer request show +.. code:: bash + + os volume transfer request show + + +.. _volume_transfer_request_show-transfer-request: +.. describe:: + + Volume transfer request to display (name or ID) diff --git a/openstackclient/tests/functional/volume/v1/test_transfer_request.py b/openstackclient/tests/functional/volume/v1/test_transfer_request.py index d8406b0295..e03cd717cd 100644 --- a/openstackclient/tests/functional/volume/v1/test_transfer_request.py +++ b/openstackclient/tests/functional/volume/v1/test_transfer_request.py @@ -47,7 +47,45 @@ class TransferRequestTests(common.BaseVolumeTests): cls.assertOutput('', raw_output_transfer) cls.assertOutput('', raw_output_volume) + def test_volume_transfer_request_accept(self): + volume_name = uuid.uuid4().hex + name = uuid.uuid4().hex + + # create a volume + opts = self.get_opts(['display_name']) + raw_output = self.openstack( + 'volume create --size 1 ' + volume_name + opts) + self.assertEqual(volume_name + '\n', raw_output) + + # create volume transfer request for the volume + # and get the auth_key of the new transfer request + opts = self.get_opts(['auth_key']) + auth_key = self.openstack( + 'volume transfer request create ' + + volume_name + + ' --name ' + name + opts) + self.assertNotEqual('', auth_key) + + # accept the volume transfer request + opts = self.get_opts(self.FIELDS) + raw_output = self.openstack( + 'volume transfer request accept ' + name + + ' ' + auth_key + opts) + self.assertEqual(name + '\n', raw_output) + + # the volume transfer will be removed by default after accepted + # so just need to delete the volume here + raw_output = self.openstack( + 'volume delete ' + volume_name) + self.assertEqual('', raw_output) + def test_volume_transfer_request_list(self): opts = self.get_opts(self.HEADERS) raw_output = self.openstack('volume transfer request list' + opts) self.assertIn(self.NAME, raw_output) + + def test_volume_transfer_request_show(self): + opts = self.get_opts(self.FIELDS) + raw_output = self.openstack( + 'volume transfer request show ' + self.NAME + opts) + self.assertEqual(self.NAME + '\n', raw_output) diff --git a/openstackclient/tests/functional/volume/v2/test_transfer_request.py b/openstackclient/tests/functional/volume/v2/test_transfer_request.py index 4f02238bc9..1791f8ac1f 100644 --- a/openstackclient/tests/functional/volume/v2/test_transfer_request.py +++ b/openstackclient/tests/functional/volume/v2/test_transfer_request.py @@ -47,7 +47,45 @@ class TransferRequestTests(common.BaseVolumeTests): cls.assertOutput('', raw_output_transfer) cls.assertOutput('', raw_output_volume) + def test_volume_transfer_request_accept(self): + volume_name = uuid.uuid4().hex + name = uuid.uuid4().hex + + # create a volume + opts = self.get_opts(self.FIELDS) + raw_output = self.openstack( + 'volume create --size 1 ' + volume_name + opts) + self.assertEqual(volume_name + '\n', raw_output) + + # create volume transfer request for the volume + # and get the auth_key of the new transfer request + opts = self.get_opts(['auth_key']) + auth_key = self.openstack( + 'volume transfer request create ' + + volume_name + + ' --name ' + name + opts) + self.assertNotEqual('', auth_key) + + # accept the volume transfer request + opts = self.get_opts(self.FIELDS) + raw_output = self.openstack( + 'volume transfer request accept ' + name + + ' ' + auth_key + opts) + self.assertEqual(name + '\n', raw_output) + + # the volume transfer will be removed by default after accepted + # so just need to delete the volume here + raw_output = self.openstack( + 'volume delete ' + volume_name) + self.assertEqual('', raw_output) + def test_volume_transfer_request_list(self): opts = self.get_opts(self.HEADERS) raw_output = self.openstack('volume transfer request list' + opts) self.assertIn(self.NAME, raw_output) + + def test_volume_transfer_request_show(self): + opts = self.get_opts(self.FIELDS) + raw_output = self.openstack( + 'volume transfer request show ' + self.NAME + opts) + self.assertEqual(self.NAME + '\n', raw_output) diff --git a/openstackclient/tests/unit/volume/v1/fakes.py b/openstackclient/tests/unit/volume/v1/fakes.py index 3337449937..ef52e4b008 100644 --- a/openstackclient/tests/unit/volume/v1/fakes.py +++ b/openstackclient/tests/unit/volume/v1/fakes.py @@ -146,8 +146,6 @@ class FakeTransfer(object): """ # Set default attribute transfer_info = { - 'auth_key': 'key-' + uuid.uuid4().hex, - 'created_at': 'time-' + uuid.uuid4().hex, 'volume_id': 'volume-id-' + uuid.uuid4().hex, 'name': 'fake_transfer_name', 'id': 'id-' + uuid.uuid4().hex, diff --git a/openstackclient/tests/unit/volume/v1/test_transfer_request.py b/openstackclient/tests/unit/volume/v1/test_transfer_request.py index e89c505647..b3788d6ec8 100644 --- a/openstackclient/tests/unit/volume/v1/test_transfer_request.py +++ b/openstackclient/tests/unit/volume/v1/test_transfer_request.py @@ -36,6 +36,53 @@ class TestTransfer(transfer_fakes.TestVolumev1): self.volumes_mock.reset_mock() +class TestTransferAccept(TestTransfer): + + columns = ( + 'id', + 'name', + 'volume_id', + ) + + def setUp(self): + super(TestTransferAccept, self).setUp() + + self.volume_transfer = ( + transfer_fakes.FakeTransfer.create_one_transfer()) + self.data = ( + self.volume_transfer.id, + self.volume_transfer.name, + self.volume_transfer.volume_id, + ) + + self.transfer_mock.get.return_value = self.volume_transfer + self.transfer_mock.accept.return_value = self.volume_transfer + + # Get the command object to test + self.cmd = volume_transfer_request.AcceptTransferRequest( + self.app, None) + + def test_transfer_accept(self): + arglist = [ + self.volume_transfer.id, + 'auth_key', + ] + verifylist = [ + ('transfer_request', self.volume_transfer.id), + ('auth_key', 'auth_key'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.transfer_mock.get.assert_called_once_with( + self.volume_transfer.id) + self.transfer_mock.accept.assert_called_once_with( + self.volume_transfer.id, 'auth_key') + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + class TestTransferCreate(TestTransfer): volume = transfer_fakes.FakeVolume.create_one_volume() @@ -52,7 +99,10 @@ class TestTransferCreate(TestTransfer): super(TestTransferCreate, self).setUp() self.volume_transfer = transfer_fakes.FakeTransfer.create_one_transfer( - attrs={'volume_id': self.volume.id}) + attrs={'volume_id': self.volume.id, + 'auth_key': 'key', + 'created_at': 'time'} + ) self.data = ( self.volume_transfer.auth_key, self.volume_transfer.created_at, @@ -266,3 +316,49 @@ class TestTransferList(TestTransfer): detailed=True, search_opts={'all_tenants': 1} ) + + +class TestTransferShow(TestTransfer): + + columns = ( + 'created_at', + 'id', + 'name', + 'volume_id', + ) + + def setUp(self): + super(TestTransferShow, self).setUp() + + self.volume_transfer = ( + transfer_fakes.FakeTransfer.create_one_transfer( + attrs={'created_at': 'time'}) + ) + self.data = ( + self.volume_transfer.created_at, + self.volume_transfer.id, + self.volume_transfer.name, + self.volume_transfer.volume_id, + ) + + self.transfer_mock.get.return_value = self.volume_transfer + + # Get the command object to test + self.cmd = volume_transfer_request.ShowTransferRequest( + self.app, None) + + def test_transfer_show(self): + arglist = [ + self.volume_transfer.id, + ] + verifylist = [ + ('transfer_request', self.volume_transfer.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.transfer_mock.get.assert_called_once_with( + self.volume_transfer.id) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py index 8d7ac83139..2aeea60ab5 100644 --- a/openstackclient/tests/unit/volume/v2/fakes.py +++ b/openstackclient/tests/unit/volume/v2/fakes.py @@ -52,8 +52,6 @@ class FakeTransfer(object): """ # Set default attribute transfer_info = { - 'auth_key': 'key-' + uuid.uuid4().hex, - 'created_at': 'time-' + uuid.uuid4().hex, 'volume_id': 'volume-id-' + uuid.uuid4().hex, 'name': 'fake_transfer_name', 'id': 'id-' + uuid.uuid4().hex, diff --git a/openstackclient/tests/unit/volume/v2/test_transfer_request.py b/openstackclient/tests/unit/volume/v2/test_transfer_request.py index b4f890896c..8cd6534ba7 100644 --- a/openstackclient/tests/unit/volume/v2/test_transfer_request.py +++ b/openstackclient/tests/unit/volume/v2/test_transfer_request.py @@ -36,6 +36,53 @@ class TestTransfer(transfer_fakes.TestVolume): self.volumes_mock.reset_mock() +class TestTransferAccept(TestTransfer): + + columns = ( + 'id', + 'name', + 'volume_id', + ) + + def setUp(self): + super(TestTransferAccept, self).setUp() + + self.volume_transfer = ( + transfer_fakes.FakeTransfer.create_one_transfer()) + self.data = ( + self.volume_transfer.id, + self.volume_transfer.name, + self.volume_transfer.volume_id, + ) + + self.transfer_mock.get.return_value = self.volume_transfer + self.transfer_mock.accept.return_value = self.volume_transfer + + # Get the command object to test + self.cmd = volume_transfer_request.AcceptTransferRequest( + self.app, None) + + def test_transfer_accept(self): + arglist = [ + self.volume_transfer.id, + 'auth_key', + ] + verifylist = [ + ('transfer_request', self.volume_transfer.id), + ('auth_key', 'auth_key'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.transfer_mock.get.assert_called_once_with( + self.volume_transfer.id) + self.transfer_mock.accept.assert_called_once_with( + self.volume_transfer.id, 'auth_key') + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + class TestTransferCreate(TestTransfer): volume = transfer_fakes.FakeVolume.create_one_volume() @@ -52,7 +99,10 @@ class TestTransferCreate(TestTransfer): super(TestTransferCreate, self).setUp() self.volume_transfer = transfer_fakes.FakeTransfer.create_one_transfer( - attrs={'volume_id': self.volume.id}) + attrs={'volume_id': self.volume.id, + 'auth_key': 'key', + 'created_at': 'time'} + ) self.data = ( self.volume_transfer.auth_key, self.volume_transfer.created_at, @@ -266,3 +316,49 @@ class TestTransferList(TestTransfer): detailed=True, search_opts={'all_tenants': 1} ) + + +class TestTransferShow(TestTransfer): + + columns = ( + 'created_at', + 'id', + 'name', + 'volume_id', + ) + + def setUp(self): + super(TestTransferShow, self).setUp() + + self.volume_transfer = ( + transfer_fakes.FakeTransfer.create_one_transfer( + attrs={'created_at': 'time'}) + ) + self.data = ( + self.volume_transfer.created_at, + self.volume_transfer.id, + self.volume_transfer.name, + self.volume_transfer.volume_id, + ) + + self.transfer_mock.get.return_value = self.volume_transfer + + # Get the command object to test + self.cmd = volume_transfer_request.ShowTransferRequest( + self.app, None) + + def test_transfer_show(self): + arglist = [ + self.volume_transfer.id, + ] + verifylist = [ + ('transfer_request', self.volume_transfer.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.transfer_mock.get.assert_called_once_with( + self.volume_transfer.id) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) diff --git a/openstackclient/volume/v1/volume_transfer_request.py b/openstackclient/volume/v1/volume_transfer_request.py index a985f8e598..4d6f216132 100644 --- a/openstackclient/volume/v1/volume_transfer_request.py +++ b/openstackclient/volume/v1/volume_transfer_request.py @@ -27,6 +27,34 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) +class AcceptTransferRequest(command.ShowOne): + """Accept volume transfer request.""" + + def get_parser(self, prog_name): + parser = super(AcceptTransferRequest, self).get_parser(prog_name) + parser.add_argument( + 'transfer_request', + metavar="", + help=_('Volume transfer request to accept (name or ID)'), + ) + parser.add_argument( + 'auth_key', + metavar="", + help=_('Authentication key of transfer request'), + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + transfer_request_id = utils.find_resource( + volume_client.transfers, parsed_args.transfer_request).id + transfer_accept = volume_client.transfers.accept( + transfer_request_id, parsed_args.auth_key) + transfer_accept._info.pop("links", None) + + return zip(*sorted(six.iteritems(transfer_accept._info))) + + class CreateTransferRequest(command.ShowOne): """Create volume transfer request.""" @@ -120,3 +148,24 @@ class ListTransferRequest(command.Lister): return (column_headers, ( utils.get_item_properties(s, columns) for s in volume_transfer_result)) + + +class ShowTransferRequest(command.ShowOne): + """Show volume transfer request details.""" + + def get_parser(self, prog_name): + parser = super(ShowTransferRequest, self).get_parser(prog_name) + parser.add_argument( + 'transfer_request', + metavar="", + help=_('Volume transfer request to display (name or ID)'), + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + volume_transfer_request = utils.find_resource( + volume_client.transfers, parsed_args.transfer_request) + volume_transfer_request._info.pop("links", None) + + return zip(*sorted(six.iteritems(volume_transfer_request._info))) diff --git a/openstackclient/volume/v2/volume_transfer_request.py b/openstackclient/volume/v2/volume_transfer_request.py index 8e79807cab..9008fe3c24 100644 --- a/openstackclient/volume/v2/volume_transfer_request.py +++ b/openstackclient/volume/v2/volume_transfer_request.py @@ -27,6 +27,34 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) +class AcceptTransferRequest(command.ShowOne): + """Accept volume transfer request.""" + + def get_parser(self, prog_name): + parser = super(AcceptTransferRequest, self).get_parser(prog_name) + parser.add_argument( + 'transfer_request', + metavar="", + help=_('Volume transfer request to accept (name or ID)'), + ) + parser.add_argument( + 'auth_key', + metavar="", + help=_('Authentication key of transfer request'), + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + transfer_request_id = utils.find_resource( + volume_client.transfers, parsed_args.transfer_request).id + transfer_accept = volume_client.transfers.accept( + transfer_request_id, parsed_args.auth_key) + transfer_accept._info.pop("links", None) + + return zip(*sorted(six.iteritems(transfer_accept._info))) + + class CreateTransferRequest(command.ShowOne): """Create volume transfer request.""" @@ -120,3 +148,24 @@ class ListTransferRequest(command.Lister): return (column_headers, ( utils.get_item_properties(s, columns) for s in volume_transfer_result)) + + +class ShowTransferRequest(command.ShowOne): + """Show volume transfer request details.""" + + def get_parser(self, prog_name): + parser = super(ShowTransferRequest, self).get_parser(prog_name) + parser.add_argument( + 'transfer_request', + metavar="", + help=_('Volume transfer request to display (name or ID)'), + ) + return parser + + def take_action(self, parsed_args): + volume_client = self.app.client_manager.volume + volume_transfer_request = utils.find_resource( + volume_client.transfers, parsed_args.transfer_request) + volume_transfer_request._info.pop("links", None) + + return zip(*sorted(six.iteritems(volume_transfer_request._info))) diff --git a/releasenotes/notes/bp-cinder-command-support-cc8708c4395ce467.yaml b/releasenotes/notes/bp-cinder-command-support-cc8708c4395ce467.yaml index 5f94fd6709..4c858a94c8 100644 --- a/releasenotes/notes/bp-cinder-command-support-cc8708c4395ce467.yaml +++ b/releasenotes/notes/bp-cinder-command-support-cc8708c4395ce467.yaml @@ -1,5 +1,6 @@ --- features: - - Add ``volume transfer request create`` and ``volume transfer request delete`` + - Add ``volume transfer request create``, ``volume transfer request delete``, + ``volume transfer request show`` and ``volume transfer request accept`` commands in volume v1 and v2. [Blueprint `cinder-command-support `_] diff --git a/setup.cfg b/setup.cfg index 3e6486a23d..1635b5597b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -483,9 +483,11 @@ openstack.volume.v1 = volume_service_list = openstackclient.volume.v1.service:ListService volume_service_set = openstackclient.volume.v1.service:SetService + volume_transfer_request_accept = openstackclient.volume.v1.volume_transfer_request:AcceptTransferRequest volume_transfer_request_create = openstackclient.volume.v1.volume_transfer_request:CreateTransferRequest volume_transfer_request_delete = openstackclient.volume.v1.volume_transfer_request:DeleteTransferRequest volume_transfer_request_list = openstackclient.volume.v1.volume_transfer_request:ListTransferRequest + volume_transfer_request_show = openstackclient.volume.v1.volume_transfer_request:ShowTransferRequest openstack.volume.v2 = backup_create = openstackclient.volume.v2.backup:CreateBackup @@ -533,9 +535,11 @@ openstack.volume.v2 = volume_service_list = openstackclient.volume.v2.service:ListService volume_service_set = openstackclient.volume.v2.service:SetService + volume_transfer_request_accept = openstackclient.volume.v2.volume_transfer_request:AcceptTransferRequest volume_transfer_request_create = openstackclient.volume.v2.volume_transfer_request:CreateTransferRequest volume_transfer_request_delete = openstackclient.volume.v2.volume_transfer_request:DeleteTransferRequest volume_transfer_request_list = openstackclient.volume.v2.volume_transfer_request:ListTransferRequest + volume_transfer_request_show = openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest [build_sphinx] source-dir = doc/source