Implement "volume transfer request show/accept" command

Add "volume transfer request show" and
"volume transfer accept" commands in
volume v1 and v2. Also add the unit tests,
docs, release note and functional tests

Implements: bp cinder-command-support
Co-Authored-By: Sheel Rana <ranasheel2000@gmail.com>

Change-Id: I5787fc486b3401307125caa316f517b9c96a95a5
This commit is contained in:
Huanxuan Ao 2016-08-29 19:55:28 +08:00
parent 69c4f605ec
commit 3ef7e29dd0
11 changed files with 411 additions and 7 deletions

View File

@ -4,6 +4,27 @@ volume transfer request
Block Storage v1, v2 Block Storage v1, v2
volume transfer request accept
------------------------------
Accept volume transfer request
.. program:: volume transfer request accept
.. code:: bash
os volume transfer request accept
<transfer-request>
<auth-key>
.. _volume_transfer_request_accept:
.. describe:: <transfer-request>
Volume transfer request to accept (name or ID)
.. describe:: <auth-key>
Authentication key of transfer request
volume transfer request create volume transfer request create
------------------------------ ------------------------------
@ -56,3 +77,19 @@ Lists all volume transfer requests.
Shows detail for all projects. Admin only. Shows detail for all projects. Admin only.
(defaults to False) (defaults to False)
volume transfer request show
----------------------------
Show volume transfer request details
.. program:: volume transfer request show
.. code:: bash
os volume transfer request show
<transfer-request>
.. _volume_transfer_request_show-transfer-request:
.. describe:: <transfer-request>
Volume transfer request to display (name or ID)

View File

@ -47,7 +47,45 @@ class TransferRequestTests(common.BaseVolumeTests):
cls.assertOutput('', raw_output_transfer) cls.assertOutput('', raw_output_transfer)
cls.assertOutput('', raw_output_volume) 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): def test_volume_transfer_request_list(self):
opts = self.get_opts(self.HEADERS) opts = self.get_opts(self.HEADERS)
raw_output = self.openstack('volume transfer request list' + opts) raw_output = self.openstack('volume transfer request list' + opts)
self.assertIn(self.NAME, raw_output) 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)

View File

@ -47,7 +47,45 @@ class TransferRequestTests(common.BaseVolumeTests):
cls.assertOutput('', raw_output_transfer) cls.assertOutput('', raw_output_transfer)
cls.assertOutput('', raw_output_volume) 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): def test_volume_transfer_request_list(self):
opts = self.get_opts(self.HEADERS) opts = self.get_opts(self.HEADERS)
raw_output = self.openstack('volume transfer request list' + opts) raw_output = self.openstack('volume transfer request list' + opts)
self.assertIn(self.NAME, raw_output) 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)

View File

@ -146,8 +146,6 @@ class FakeTransfer(object):
""" """
# Set default attribute # Set default attribute
transfer_info = { transfer_info = {
'auth_key': 'key-' + uuid.uuid4().hex,
'created_at': 'time-' + uuid.uuid4().hex,
'volume_id': 'volume-id-' + uuid.uuid4().hex, 'volume_id': 'volume-id-' + uuid.uuid4().hex,
'name': 'fake_transfer_name', 'name': 'fake_transfer_name',
'id': 'id-' + uuid.uuid4().hex, 'id': 'id-' + uuid.uuid4().hex,

View File

@ -36,6 +36,53 @@ class TestTransfer(transfer_fakes.TestVolumev1):
self.volumes_mock.reset_mock() 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): class TestTransferCreate(TestTransfer):
volume = transfer_fakes.FakeVolume.create_one_volume() volume = transfer_fakes.FakeVolume.create_one_volume()
@ -52,7 +99,10 @@ class TestTransferCreate(TestTransfer):
super(TestTransferCreate, self).setUp() super(TestTransferCreate, self).setUp()
self.volume_transfer = transfer_fakes.FakeTransfer.create_one_transfer( 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.data = (
self.volume_transfer.auth_key, self.volume_transfer.auth_key,
self.volume_transfer.created_at, self.volume_transfer.created_at,
@ -266,3 +316,49 @@ class TestTransferList(TestTransfer):
detailed=True, detailed=True,
search_opts={'all_tenants': 1} 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)

View File

@ -52,8 +52,6 @@ class FakeTransfer(object):
""" """
# Set default attribute # Set default attribute
transfer_info = { transfer_info = {
'auth_key': 'key-' + uuid.uuid4().hex,
'created_at': 'time-' + uuid.uuid4().hex,
'volume_id': 'volume-id-' + uuid.uuid4().hex, 'volume_id': 'volume-id-' + uuid.uuid4().hex,
'name': 'fake_transfer_name', 'name': 'fake_transfer_name',
'id': 'id-' + uuid.uuid4().hex, 'id': 'id-' + uuid.uuid4().hex,

View File

@ -36,6 +36,53 @@ class TestTransfer(transfer_fakes.TestVolume):
self.volumes_mock.reset_mock() 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): class TestTransferCreate(TestTransfer):
volume = transfer_fakes.FakeVolume.create_one_volume() volume = transfer_fakes.FakeVolume.create_one_volume()
@ -52,7 +99,10 @@ class TestTransferCreate(TestTransfer):
super(TestTransferCreate, self).setUp() super(TestTransferCreate, self).setUp()
self.volume_transfer = transfer_fakes.FakeTransfer.create_one_transfer( 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.data = (
self.volume_transfer.auth_key, self.volume_transfer.auth_key,
self.volume_transfer.created_at, self.volume_transfer.created_at,
@ -266,3 +316,49 @@ class TestTransferList(TestTransfer):
detailed=True, detailed=True,
search_opts={'all_tenants': 1} 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)

View File

@ -27,6 +27,34 @@ from openstackclient.i18n import _
LOG = logging.getLogger(__name__) 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="<transfer-request>",
help=_('Volume transfer request to accept (name or ID)'),
)
parser.add_argument(
'auth_key',
metavar="<auth-key>",
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): class CreateTransferRequest(command.ShowOne):
"""Create volume transfer request.""" """Create volume transfer request."""
@ -120,3 +148,24 @@ class ListTransferRequest(command.Lister):
return (column_headers, ( return (column_headers, (
utils.get_item_properties(s, columns) utils.get_item_properties(s, columns)
for s in volume_transfer_result)) 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="<transfer-request>",
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)))

View File

@ -27,6 +27,34 @@ from openstackclient.i18n import _
LOG = logging.getLogger(__name__) 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="<transfer-request>",
help=_('Volume transfer request to accept (name or ID)'),
)
parser.add_argument(
'auth_key',
metavar="<auth-key>",
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): class CreateTransferRequest(command.ShowOne):
"""Create volume transfer request.""" """Create volume transfer request."""
@ -120,3 +148,24 @@ class ListTransferRequest(command.Lister):
return (column_headers, ( return (column_headers, (
utils.get_item_properties(s, columns) utils.get_item_properties(s, columns)
for s in volume_transfer_result)) 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="<transfer-request>",
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)))

View File

@ -1,5 +1,6 @@
--- ---
features: 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. commands in volume v1 and v2.
[Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_] [Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]

View File

@ -483,9 +483,11 @@ openstack.volume.v1 =
volume_service_list = openstackclient.volume.v1.service:ListService volume_service_list = openstackclient.volume.v1.service:ListService
volume_service_set = openstackclient.volume.v1.service:SetService 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_create = openstackclient.volume.v1.volume_transfer_request:CreateTransferRequest
volume_transfer_request_delete = openstackclient.volume.v1.volume_transfer_request:DeleteTransferRequest 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_list = openstackclient.volume.v1.volume_transfer_request:ListTransferRequest
volume_transfer_request_show = openstackclient.volume.v1.volume_transfer_request:ShowTransferRequest
openstack.volume.v2 = openstack.volume.v2 =
backup_create = openstackclient.volume.v2.backup:CreateBackup backup_create = openstackclient.volume.v2.backup:CreateBackup
@ -533,9 +535,11 @@ openstack.volume.v2 =
volume_service_list = openstackclient.volume.v2.service:ListService volume_service_list = openstackclient.volume.v2.service:ListService
volume_service_set = openstackclient.volume.v2.service:SetService 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_create = openstackclient.volume.v2.volume_transfer_request:CreateTransferRequest
volume_transfer_request_delete = openstackclient.volume.v2.volume_transfer_request:DeleteTransferRequest 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_list = openstackclient.volume.v2.volume_transfer_request:ListTransferRequest
volume_transfer_request_show = openstackclient.volume.v2.volume_transfer_request:ShowTransferRequest
[build_sphinx] [build_sphinx]
source-dir = doc/source source-dir = doc/source