Implements support migration for volume transfer
Implements support for the volume transfer api added to cinder in https://review.openstack.org/#/c/29227 Change-Id: Idbcdfdd3ef76a8c516e08d1cf351d549254bc8c0
This commit is contained in:
@@ -114,6 +114,44 @@ def _stub_restore():
|
|||||||
return {'volume_id': '712f4980-5ac1-41e5-9383-390aa7c9f58b'}
|
return {'volume_id': '712f4980-5ac1-41e5-9383-390aa7c9f58b'}
|
||||||
|
|
||||||
|
|
||||||
|
def _stub_transfer_full(id, base_uri, tenant_id):
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'name': 'transfer',
|
||||||
|
'volume_id': '8c05f861-6052-4df6-b3e0-0aebfbe686cc',
|
||||||
|
'created_at': '2013-04-12T08:16:37.000000',
|
||||||
|
'auth_key': '123456',
|
||||||
|
'links': [
|
||||||
|
{
|
||||||
|
'href': _self_href(base_uri, tenant_id, id),
|
||||||
|
'rel': 'self'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'href': _bookmark_href(base_uri, tenant_id, id),
|
||||||
|
'rel': 'bookmark'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _stub_transfer(id, base_uri, tenant_id):
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'name': 'transfer',
|
||||||
|
'volume_id': '8c05f861-6052-4df6-b3e0-0aebfbe686cc',
|
||||||
|
'links': [
|
||||||
|
{
|
||||||
|
'href': _self_href(base_uri, tenant_id, id),
|
||||||
|
'rel': 'self'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'href': _bookmark_href(base_uri, tenant_id, id),
|
||||||
|
'rel': 'bookmark'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class FakeClient(fakes.FakeClient, client.Client):
|
class FakeClient(fakes.FakeClient, client.Client):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -405,3 +443,42 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
def post_backups_76a17945_3c6f_435c_975b_b5685db10b62_restore(self, **kw):
|
def post_backups_76a17945_3c6f_435c_975b_b5685db10b62_restore(self, **kw):
|
||||||
return (200, {},
|
return (200, {},
|
||||||
{'restore': _stub_restore()})
|
{'restore': _stub_restore()})
|
||||||
|
|
||||||
|
#
|
||||||
|
# VolumeTransfers
|
||||||
|
#
|
||||||
|
|
||||||
|
def get_os_volume_transfer_5678(self, **kw):
|
||||||
|
base_uri = 'http://localhost:8776'
|
||||||
|
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
|
||||||
|
transfer1 = '5678'
|
||||||
|
return (200, {},
|
||||||
|
{'transfer':
|
||||||
|
_stub_transfer_full(transfer1, base_uri, tenant_id)})
|
||||||
|
|
||||||
|
def get_os_volume_transfer_detail(self, **kw):
|
||||||
|
base_uri = 'http://localhost:8776'
|
||||||
|
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
|
||||||
|
transfer1 = '5678'
|
||||||
|
transfer2 = 'f625ec3e-13dd-4498-a22a-50afd534cc41'
|
||||||
|
return (200, {},
|
||||||
|
{'transfers': [
|
||||||
|
_stub_transfer_full(transfer1, base_uri, tenant_id),
|
||||||
|
_stub_transfer_full(transfer2, base_uri, tenant_id)]})
|
||||||
|
|
||||||
|
def delete_os_volume_transfer_5678(self, **kw):
|
||||||
|
return (202, {}, None)
|
||||||
|
|
||||||
|
def post_os_volume_transfer(self, **kw):
|
||||||
|
base_uri = 'http://localhost:8776'
|
||||||
|
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
|
||||||
|
transfer1 = '5678'
|
||||||
|
return (202, {},
|
||||||
|
{'transfer': _stub_transfer(transfer1, base_uri, tenant_id)})
|
||||||
|
|
||||||
|
def post_os_volume_transfer_5678_accept(self, **kw):
|
||||||
|
base_uri = 'http://localhost:8776'
|
||||||
|
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
|
||||||
|
transfer1 = '5678'
|
||||||
|
return (200, {},
|
||||||
|
{'transfer': _stub_transfer(transfer1, base_uri, tenant_id)})
|
||||||
|
51
cinderclient/tests/v1/test_volume_transfers.py
Normal file
51
cinderclient/tests/v1/test_volume_transfers.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from cinderclient.tests import utils
|
||||||
|
from cinderclient.tests.v1 import fakes
|
||||||
|
|
||||||
|
|
||||||
|
cs = fakes.FakeClient()
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeTRansfersTest(utils.TestCase):
|
||||||
|
|
||||||
|
def test_create(self):
|
||||||
|
cs.transfers.create('1234')
|
||||||
|
cs.assert_called('POST', '/os-volume-transfer')
|
||||||
|
|
||||||
|
def test_get(self):
|
||||||
|
transfer_id = '5678'
|
||||||
|
cs.transfers.get(transfer_id)
|
||||||
|
cs.assert_called('GET', '/os-volume-transfer/%s' % transfer_id)
|
||||||
|
|
||||||
|
def test_list(self):
|
||||||
|
cs.transfers.list()
|
||||||
|
cs.assert_called('GET', '/os-volume-transfer/detail')
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
b = cs.transfers.list()[0]
|
||||||
|
b.delete()
|
||||||
|
cs.assert_called('DELETE', '/os-volume-transfer/5678')
|
||||||
|
cs.transfers.delete('5678')
|
||||||
|
cs.assert_called('DELETE', '/os-volume-transfer/5678')
|
||||||
|
cs.transfers.delete(b)
|
||||||
|
cs.assert_called('DELETE', '/os-volume-transfer/5678')
|
||||||
|
|
||||||
|
def test_accept(self):
|
||||||
|
transfer_id = '5678'
|
||||||
|
auth_key = '12345'
|
||||||
|
cs.transfers.accept(transfer_id, auth_key)
|
||||||
|
cs.assert_called('POST', '/os-volume-transfer/%s/accept' % transfer_id)
|
@@ -121,6 +121,44 @@ def _stub_restore():
|
|||||||
return {'volume_id': '712f4980-5ac1-41e5-9383-390aa7c9f58b'}
|
return {'volume_id': '712f4980-5ac1-41e5-9383-390aa7c9f58b'}
|
||||||
|
|
||||||
|
|
||||||
|
def _stub_transfer_full(id, base_uri, tenant_id):
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'name': 'transfer',
|
||||||
|
'volume_id': '8c05f861-6052-4df6-b3e0-0aebfbe686cc',
|
||||||
|
'created_at': '2013-04-12T08:16:37.000000',
|
||||||
|
'auth_key': '123456',
|
||||||
|
'links': [
|
||||||
|
{
|
||||||
|
'href': _self_href(base_uri, tenant_id, id),
|
||||||
|
'rel': 'self'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'href': _bookmark_href(base_uri, tenant_id, id),
|
||||||
|
'rel': 'bookmark'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _stub_transfer(id, base_uri, tenant_id):
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'name': 'transfer',
|
||||||
|
'volume_id': '8c05f861-6052-4df6-b3e0-0aebfbe686cc',
|
||||||
|
'links': [
|
||||||
|
{
|
||||||
|
'href': _self_href(base_uri, tenant_id, id),
|
||||||
|
'rel': 'self'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'href': _bookmark_href(base_uri, tenant_id, id),
|
||||||
|
'rel': 'bookmark'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class FakeClient(fakes.FakeClient, client.Client):
|
class FakeClient(fakes.FakeClient, client.Client):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -412,3 +450,42 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
def post_backups_76a17945_3c6f_435c_975b_b5685db10b62_restore(self, **kw):
|
def post_backups_76a17945_3c6f_435c_975b_b5685db10b62_restore(self, **kw):
|
||||||
return (200, {},
|
return (200, {},
|
||||||
{'restore': _stub_restore()})
|
{'restore': _stub_restore()})
|
||||||
|
|
||||||
|
#
|
||||||
|
# VolumeTransfers
|
||||||
|
#
|
||||||
|
|
||||||
|
def get_os_volume_transfer_5678(self, **kw):
|
||||||
|
base_uri = 'http://localhost:8776'
|
||||||
|
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
|
||||||
|
transfer1 = '5678'
|
||||||
|
return (200, {},
|
||||||
|
{'transfer':
|
||||||
|
_stub_transfer_full(transfer1, base_uri, tenant_id)})
|
||||||
|
|
||||||
|
def get_os_volume_transfer_detail(self, **kw):
|
||||||
|
base_uri = 'http://localhost:8776'
|
||||||
|
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
|
||||||
|
transfer1 = '5678'
|
||||||
|
transfer2 = 'f625ec3e-13dd-4498-a22a-50afd534cc41'
|
||||||
|
return (200, {},
|
||||||
|
{'transfers': [
|
||||||
|
_stub_transfer_full(transfer1, base_uri, tenant_id),
|
||||||
|
_stub_transfer_full(transfer2, base_uri, tenant_id)]})
|
||||||
|
|
||||||
|
def delete_os_volume_transfer_5678(self, **kw):
|
||||||
|
return (202, {}, None)
|
||||||
|
|
||||||
|
def post_os_volume_transfer(self, **kw):
|
||||||
|
base_uri = 'http://localhost:8776'
|
||||||
|
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
|
||||||
|
transfer1 = '5678'
|
||||||
|
return (202, {},
|
||||||
|
{'transfer': _stub_transfer(transfer1, base_uri, tenant_id)})
|
||||||
|
|
||||||
|
def post_os_volume_transfer_5678_accept(self, **kw):
|
||||||
|
base_uri = 'http://localhost:8776'
|
||||||
|
tenant_id = '0fa851f6668144cf9cd8c8419c1646c1'
|
||||||
|
transfer1 = '5678'
|
||||||
|
return (200, {},
|
||||||
|
{'transfer': _stub_transfer(transfer1, base_uri, tenant_id)})
|
||||||
|
51
cinderclient/tests/v2/test_volume_transfers.py
Normal file
51
cinderclient/tests/v2/test_volume_transfers.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from cinderclient.tests import utils
|
||||||
|
from cinderclient.tests.v1 import fakes
|
||||||
|
|
||||||
|
|
||||||
|
cs = fakes.FakeClient()
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeTRansfersTest(utils.TestCase):
|
||||||
|
|
||||||
|
def test_create(self):
|
||||||
|
cs.transfers.create('1234')
|
||||||
|
cs.assert_called('POST', '/os-volume-transfer')
|
||||||
|
|
||||||
|
def test_get(self):
|
||||||
|
transfer_id = '5678'
|
||||||
|
cs.transfers.get(transfer_id)
|
||||||
|
cs.assert_called('GET', '/os-volume-transfer/%s' % transfer_id)
|
||||||
|
|
||||||
|
def test_list(self):
|
||||||
|
cs.transfers.list()
|
||||||
|
cs.assert_called('GET', '/os-volume-transfer/detail')
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
b = cs.transfers.list()[0]
|
||||||
|
b.delete()
|
||||||
|
cs.assert_called('DELETE', '/os-volume-transfer/5678')
|
||||||
|
cs.transfers.delete('5678')
|
||||||
|
cs.assert_called('DELETE', '/os-volume-transfer/5678')
|
||||||
|
cs.transfers.delete(b)
|
||||||
|
cs.assert_called('DELETE', '/os-volume-transfer/5678')
|
||||||
|
|
||||||
|
def test_accept(self):
|
||||||
|
transfer_id = '5678'
|
||||||
|
auth_key = '12345'
|
||||||
|
cs.transfers.accept(transfer_id, auth_key)
|
||||||
|
cs.assert_called('POST', '/os-volume-transfer/%s/accept' % transfer_id)
|
@@ -22,6 +22,7 @@ from cinderclient.v1 import volume_snapshots
|
|||||||
from cinderclient.v1 import volume_types
|
from cinderclient.v1 import volume_types
|
||||||
from cinderclient.v1 import volume_backups
|
from cinderclient.v1 import volume_backups
|
||||||
from cinderclient.v1 import volume_backups_restore
|
from cinderclient.v1 import volume_backups_restore
|
||||||
|
from cinderclient.v1 import volume_transfers
|
||||||
|
|
||||||
|
|
||||||
class Client(object):
|
class Client(object):
|
||||||
@@ -60,6 +61,7 @@ class Client(object):
|
|||||||
self.quotas = quotas.QuotaSetManager(self)
|
self.quotas = quotas.QuotaSetManager(self)
|
||||||
self.backups = volume_backups.VolumeBackupManager(self)
|
self.backups = volume_backups.VolumeBackupManager(self)
|
||||||
self.restores = volume_backups_restore.VolumeBackupRestoreManager(self)
|
self.restores = volume_backups_restore.VolumeBackupRestoreManager(self)
|
||||||
|
self.transfers = volume_transfers.VolumeTransferManager(self)
|
||||||
|
|
||||||
# Add in any extensions...
|
# Add in any extensions...
|
||||||
if extensions:
|
if extensions:
|
||||||
|
@@ -73,6 +73,11 @@ def _find_backup(cs, backup):
|
|||||||
return utils.find_resource(cs.backups, backup)
|
return utils.find_resource(cs.backups, backup)
|
||||||
|
|
||||||
|
|
||||||
|
def _find_transfer(cs, transfer):
|
||||||
|
"""Get a transfer by ID."""
|
||||||
|
return utils.find_resource(cs.transfers, transfer)
|
||||||
|
|
||||||
|
|
||||||
def _print_volume(volume):
|
def _print_volume(volume):
|
||||||
utils.print_dict(volume._info)
|
utils.print_dict(volume._info)
|
||||||
|
|
||||||
@@ -719,3 +724,71 @@ def do_backup_restore(cs, args):
|
|||||||
"""Restore a backup."""
|
"""Restore a backup."""
|
||||||
cs.restores.restore(args.backup,
|
cs.restores.restore(args.backup,
|
||||||
args.volume_id)
|
args.volume_id)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('volume', metavar='<volume>',
|
||||||
|
help='ID of the volume to transfer.')
|
||||||
|
@utils.arg('--display-name', metavar='<display-name>',
|
||||||
|
help='Optional transfer name. (Default=None)',
|
||||||
|
default=None)
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_create(cs, args):
|
||||||
|
"""Creates a volume transfer."""
|
||||||
|
transfer = cs.transfers.create(args.volume,
|
||||||
|
args.display_name)
|
||||||
|
info = dict()
|
||||||
|
info.update(transfer._info)
|
||||||
|
|
||||||
|
if 'links' in info:
|
||||||
|
info.pop('links')
|
||||||
|
|
||||||
|
utils.print_dict(info)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('transfer', metavar='<transfer>',
|
||||||
|
help='ID of the transfer to delete.')
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_delete(cs, args):
|
||||||
|
"""Undo a transfer."""
|
||||||
|
transfer = _find_transfer(cs, args.transfer)
|
||||||
|
transfer.delete()
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('transfer', metavar='<transfer>',
|
||||||
|
help='ID of the transfer to accept.')
|
||||||
|
@utils.arg('auth_key', metavar='<auth_key>',
|
||||||
|
help='Auth key of the transfer to accept.')
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_accept(cs, args):
|
||||||
|
"""Accepts a volume transfer."""
|
||||||
|
transfer = cs.transfers.accept(args.transfer, args.auth_key)
|
||||||
|
info = dict()
|
||||||
|
info.update(transfer._info)
|
||||||
|
|
||||||
|
if 'links' in info:
|
||||||
|
info.pop('links')
|
||||||
|
|
||||||
|
utils.print_dict(info)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_list(cs, args):
|
||||||
|
"""List all the transfers."""
|
||||||
|
transfers = cs.transfers.list()
|
||||||
|
columns = ['ID', 'Volume ID', 'Name']
|
||||||
|
utils.print_list(transfers, columns)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('transfer', metavar='<transfer>',
|
||||||
|
help='ID of the transfer to accept.')
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_show(cs, args):
|
||||||
|
"""Show details about a transfer."""
|
||||||
|
transfer = _find_transfer(cs, args.transfer)
|
||||||
|
info = dict()
|
||||||
|
info.update(transfer._info)
|
||||||
|
|
||||||
|
if 'links' in info:
|
||||||
|
info.pop('links')
|
||||||
|
|
||||||
|
utils.print_dict(info)
|
||||||
|
82
cinderclient/v1/volume_transfers.py
Normal file
82
cinderclient/v1/volume_transfers.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Volume transfer interface (1.1 extension).
|
||||||
|
"""
|
||||||
|
|
||||||
|
from cinderclient import base
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeTransfer(base.Resource):
|
||||||
|
"""Transfer a volume from one tenant to another"""
|
||||||
|
def __repr__(self):
|
||||||
|
return "<VolumeTransfer: %s>" % self.id
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
"""Delete this volume transfer."""
|
||||||
|
return self.manager.delete(self)
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeTransferManager(base.ManagerWithFind):
|
||||||
|
"""Manage :class:`VolumeTransfer` resources."""
|
||||||
|
resource_class = VolumeTransfer
|
||||||
|
|
||||||
|
def create(self, volume_id, name=None):
|
||||||
|
"""Create a volume transfer.
|
||||||
|
|
||||||
|
:param volume_id: The ID of the volume to transfer.
|
||||||
|
:param name: The name of the transfer.
|
||||||
|
:rtype: :class:`VolumeTransfer`
|
||||||
|
"""
|
||||||
|
body = {'transfer': {'volume_id': volume_id,
|
||||||
|
'name': name}}
|
||||||
|
return self._create('/os-volume-transfer', body, 'transfer')
|
||||||
|
|
||||||
|
def accept(self, transfer_id, auth_key):
|
||||||
|
"""Accept a volume transfer.
|
||||||
|
|
||||||
|
:param transfer_id: The ID of the trasnfer to accept.
|
||||||
|
:param auth_key: The auth_key of the transfer.
|
||||||
|
:rtype: :class:`VolumeTransfer`
|
||||||
|
"""
|
||||||
|
body = {'accept': {'auth_key': auth_key}}
|
||||||
|
return self._create('/os-volume-transfer/%s/accept' % transfer_id,
|
||||||
|
body, 'transfer')
|
||||||
|
|
||||||
|
def get(self, transfer_id):
|
||||||
|
"""Show details of a volume transfer.
|
||||||
|
|
||||||
|
:param transfer_id: The ID of the volume transfer to display.
|
||||||
|
:rtype: :class:`VolumeTransfer`
|
||||||
|
"""
|
||||||
|
return self._get("/os-volume-transfer/%s" % transfer_id, "transfer")
|
||||||
|
|
||||||
|
def list(self, detailed=True):
|
||||||
|
"""Get a list of all volume transfer.
|
||||||
|
|
||||||
|
:rtype: list of :class:`VolumeTransfer`
|
||||||
|
"""
|
||||||
|
if detailed is True:
|
||||||
|
return self._list("/os-volume-transfer/detail", "transfers")
|
||||||
|
else:
|
||||||
|
return self._list("/os-volume-transfer", "transfers")
|
||||||
|
|
||||||
|
def delete(self, transfer_id):
|
||||||
|
"""Delete a volume transfer.
|
||||||
|
|
||||||
|
:param transfer_id: The :class:`VolumeTransfer` to delete.
|
||||||
|
"""
|
||||||
|
self._delete("/os-volume-transfer/%s" % base.getid(transfer_id))
|
@@ -22,6 +22,7 @@ from cinderclient.v2 import volume_snapshots
|
|||||||
from cinderclient.v2 import volume_types
|
from cinderclient.v2 import volume_types
|
||||||
from cinderclient.v2 import volume_backups
|
from cinderclient.v2 import volume_backups
|
||||||
from cinderclient.v2 import volume_backups_restore
|
from cinderclient.v2 import volume_backups_restore
|
||||||
|
from cinderclient.v1 import volume_transfers
|
||||||
|
|
||||||
|
|
||||||
class Client(object):
|
class Client(object):
|
||||||
@@ -58,6 +59,7 @@ class Client(object):
|
|||||||
self.quotas = quotas.QuotaSetManager(self)
|
self.quotas = quotas.QuotaSetManager(self)
|
||||||
self.backups = volume_backups.VolumeBackupManager(self)
|
self.backups = volume_backups.VolumeBackupManager(self)
|
||||||
self.restores = volume_backups_restore.VolumeBackupRestoreManager(self)
|
self.restores = volume_backups_restore.VolumeBackupRestoreManager(self)
|
||||||
|
self.transfers = volume_transfers.VolumeTransferManager(self)
|
||||||
|
|
||||||
# Add in any extensions...
|
# Add in any extensions...
|
||||||
if extensions:
|
if extensions:
|
||||||
|
@@ -69,6 +69,11 @@ def _find_backup(cs, backup):
|
|||||||
return utils.find_resource(cs.backups, backup)
|
return utils.find_resource(cs.backups, backup)
|
||||||
|
|
||||||
|
|
||||||
|
def _find_transfer(cs, transfer):
|
||||||
|
"""Get a transfer by ID."""
|
||||||
|
return utils.find_resource(cs.transfers, transfer)
|
||||||
|
|
||||||
|
|
||||||
def _print_volume_snapshot(snapshot):
|
def _print_volume_snapshot(snapshot):
|
||||||
utils.print_dict(snapshot._info)
|
utils.print_dict(snapshot._info)
|
||||||
|
|
||||||
@@ -785,3 +790,77 @@ def do_backup_restore(cs, args):
|
|||||||
"""Restore a backup."""
|
"""Restore a backup."""
|
||||||
cs.restores.restore(args.backup,
|
cs.restores.restore(args.backup,
|
||||||
args.volume_id)
|
args.volume_id)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('volume', metavar='<volume>',
|
||||||
|
help='ID of the volume to transfer.')
|
||||||
|
@utils.arg('--name',
|
||||||
|
metavar='<name>',
|
||||||
|
default=None,
|
||||||
|
help='Optional transfer name. (Default=None)')
|
||||||
|
@utils.arg('--display-name',
|
||||||
|
help=argparse.SUPPRESS)
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_create(cs, args):
|
||||||
|
"""Creates a volume transfer."""
|
||||||
|
if args.display_name is not None:
|
||||||
|
args.name = args.display_name
|
||||||
|
|
||||||
|
transfer = cs.transfers.create(args.volume,
|
||||||
|
args.name)
|
||||||
|
info = dict()
|
||||||
|
info.update(transfer._info)
|
||||||
|
|
||||||
|
if 'links' in info:
|
||||||
|
info.pop('links')
|
||||||
|
|
||||||
|
utils.print_dict(info)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('transfer', metavar='<transfer>',
|
||||||
|
help='ID of the transfer to delete.')
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_delete(cs, args):
|
||||||
|
"""Undo a transfer."""
|
||||||
|
transfer = _find_transfer(cs, args.transfer)
|
||||||
|
transfer.delete()
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('transfer', metavar='<transfer>',
|
||||||
|
help='ID of the transfer to accept.')
|
||||||
|
@utils.arg('auth_key', metavar='<auth_key>',
|
||||||
|
help='Auth key of the transfer to accept.')
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_accept(cs, args):
|
||||||
|
"""Accepts a volume transfer."""
|
||||||
|
transfer = cs.transfers.accept(args.transfer, args.auth_key)
|
||||||
|
info = dict()
|
||||||
|
info.update(transfer._info)
|
||||||
|
|
||||||
|
if 'links' in info:
|
||||||
|
info.pop('links')
|
||||||
|
|
||||||
|
utils.print_dict(info)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_list(cs, args):
|
||||||
|
"""List all the transfers."""
|
||||||
|
transfers = cs.transfers.list()
|
||||||
|
columns = ['ID', 'Volume ID', 'Name']
|
||||||
|
utils.print_list(transfers, columns)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('transfer', metavar='<transfer>',
|
||||||
|
help='ID of the transfer to accept.')
|
||||||
|
@utils.service_type('volume')
|
||||||
|
def do_transfer_show(cs, args):
|
||||||
|
"""Show details about a transfer."""
|
||||||
|
transfer = _find_transfer(cs, args.transfer)
|
||||||
|
info = dict()
|
||||||
|
info.update(transfer._info)
|
||||||
|
|
||||||
|
if 'links' in info:
|
||||||
|
info.pop('links')
|
||||||
|
|
||||||
|
utils.print_dict(info)
|
||||||
|
82
cinderclient/v2/volume_transfers.py
Normal file
82
cinderclient/v2/volume_transfers.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Volume transfer interface (1.1 extension).
|
||||||
|
"""
|
||||||
|
|
||||||
|
from cinderclient import base
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeTransfer(base.Resource):
|
||||||
|
"""Transfer a volume from one tenant to another"""
|
||||||
|
def __repr__(self):
|
||||||
|
return "<VolumeTransfer: %s>" % self.id
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
"""Delete this volume transfer."""
|
||||||
|
return self.manager.delete(self)
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeTransferManager(base.ManagerWithFind):
|
||||||
|
"""Manage :class:`VolumeTransfer` resources."""
|
||||||
|
resource_class = VolumeTransfer
|
||||||
|
|
||||||
|
def create(self, volume_id, name=None):
|
||||||
|
"""Create a volume transfer.
|
||||||
|
|
||||||
|
:param volume_id: The ID of the volume to transfer.
|
||||||
|
:param name: The name of the transfer.
|
||||||
|
:rtype: :class:`VolumeTransfer`
|
||||||
|
"""
|
||||||
|
body = {'transfer': {'volume_id': volume_id,
|
||||||
|
'name': name}}
|
||||||
|
return self._create('/os-volume-transfer', body, 'transfer')
|
||||||
|
|
||||||
|
def accept(self, transfer_id, auth_key):
|
||||||
|
"""Accept a volume transfer.
|
||||||
|
|
||||||
|
:param transfer_id: The ID of the trasnfer to accept.
|
||||||
|
:param auth_key: The auth_key of the transfer.
|
||||||
|
:rtype: :class:`VolumeTransfer`
|
||||||
|
"""
|
||||||
|
body = {'accept': {'auth_key': auth_key}}
|
||||||
|
return self._create('/os-volume-transfer/%s/accept' % transfer_id,
|
||||||
|
body, 'transfer')
|
||||||
|
|
||||||
|
def get(self, transfer_id):
|
||||||
|
"""Show details of a volume transfer.
|
||||||
|
|
||||||
|
:param transfer_id: The ID of the volume transfer to display.
|
||||||
|
:rtype: :class:`VolumeTransfer`
|
||||||
|
"""
|
||||||
|
return self._get("/os-volume-transfer/%s" % transfer_id, "transfer")
|
||||||
|
|
||||||
|
def list(self, detailed=True):
|
||||||
|
"""Get a list of all volume transfer.
|
||||||
|
|
||||||
|
:rtype: list of :class:`VolumeTransfer`
|
||||||
|
"""
|
||||||
|
if detailed is True:
|
||||||
|
return self._list("/os-volume-transfer/detail", "transfers")
|
||||||
|
else:
|
||||||
|
return self._list("/os-volume-transfer", "transfers")
|
||||||
|
|
||||||
|
def delete(self, transfer_id):
|
||||||
|
"""Delete a volume transfer.
|
||||||
|
|
||||||
|
:param transfer_id: The :class:`VolumeTransfer` to delete.
|
||||||
|
"""
|
||||||
|
self._delete("/os-volume-transfer/%s" % base.getid(transfer_id))
|
Reference in New Issue
Block a user