Remove deprecated volume(snapshot) commands/bindings

23f13437dd deprecated the
purely volume or volume-snapshot related CLIs and python
API bindings during Kilo. python-cinderclient should be
used for the python API bindings now, and python-openstackclient
should be used for the CLI for those operations.

The alternate_service_type context manager is also removed
since it was only used for proxying through to the volume API
endpoint.

Since the proxy for creating volumes is removed, we have to
add python-cinderclient for testing the volume attachment
CLIs/APIs that are left intact.

Change-Id: I09a6501603667350f49b1b1fa130353a6d5272a2
This commit is contained in:
Matt Riedemann 2016-04-01 14:44:09 -04:00
parent 8c204ac1a2
commit a425702689
18 changed files with 21 additions and 834 deletions

View File

@ -259,18 +259,6 @@ class Manager(HookableMixin):
for res in data if res]
return ListWithMeta(items, resp)
@contextlib.contextmanager
def alternate_service_type(self, default, allowed_types=()):
original_service_type = self.api.client.service_type
if original_service_type in allowed_types:
yield
else:
self.api.client.service_type = default
try:
yield
finally:
self.api.client.service_type = original_service_type
@contextlib.contextmanager
def completion_cache(self, cache_type, obj_class, mode):
"""The completion cache for bash autocompletion.

View File

@ -14,6 +14,7 @@ import os
import time
import uuid
from cinderclient.v2 import client as cinderclient
import fixtures
from keystoneclient.v2_0 import client as keystoneclient
import os_client_config
@ -206,6 +207,7 @@ class ClientTestBase(testtools.TestCase):
password=passwd,
tenant_name=tenant,
auth_url=auth_url)
self.cinder = cinderclient.Client(user, passwd, tenant, auth_url)
def nova(self, action, flags='', params='', fail_ok=False,
endpoint_type='publicURL', merge_stderr=False):
@ -218,14 +220,14 @@ class ClientTestBase(testtools.TestCase):
poll_interval=1):
"""Wait until volume reaches given status.
:param volume_id: uuid4 id of given volume
:param volume: volume resource
:param status: expected status of volume
:param timeout: timeout in seconds
:param poll_interval: poll interval in seconds
"""
start_time = time.time()
while time.time() - start_time < timeout:
volume = self.client.volumes.get(volume.id)
volume = self.cinder.volumes.get(volume.id)
if volume.status == status:
break
time.sleep(poll_interval)

View File

@ -22,8 +22,8 @@ class TestExtAttrNovaClient(base.ClientTestBase):
def _create_server_and_attach_volume(self):
server = self._create_server()
volume = self.client.volumes.create(1)
self.addCleanup(self.nova, 'volume-delete', params=volume.id)
volume = self.cinder.volumes.create(1)
self.addCleanup(volume.delete)
self.wait_for_volume_status(volume, 'available')
self.nova('volume-attach', params="%s %s" % (server.name, volume.id))
self.addCleanup(self._release_volume, server, volume)

View File

@ -52,10 +52,9 @@ class TestInstanceCLI(base.ClientTestBase):
server = servers[0]
self.addCleanup(server.delete)
# create a volume for attachment. We use the CLI because it
# magic routes to cinder, however the low level API does not.
volume = self.client.volumes.create(1)
self.addCleanup(self.nova, 'volume-delete', params=volume.id)
# create a volume for attachment
volume = self.cinder.volumes.create(1)
self.addCleanup(volume.delete)
# allow volume to become available
self.wait_for_volume_status(volume, 'available')
@ -69,4 +68,3 @@ class TestInstanceCLI(base.ClientTestBase):
# clean up on success
self.nova('volume-detach', params="%s %s" % (name, volume.id))
self.wait_for_volume_status(volume, 'available')
self.nova('volume-delete', params=volume.id)

View File

@ -131,17 +131,6 @@ class SimpleReadOnlyNovaClientTest(base.ClientTestBase):
def test_admin_usage_list(self):
self.nova('usage-list')
def test_admin_volume_list(self):
self.nova('volume-list')
def test_admin_volume_snapshot_list(self):
out = self.nova('volume-snapshot-list', merge_stderr=True)
self.assertIn('Command volume-snapshot-list is deprecated', out)
def test_admin_volume_type_list(self):
out = self.nova('volume-type-list', merge_stderr=True)
self.assertIn('Command volume-type-list is deprecated', out)
def test_admin_help(self):
self.nova('help')

View File

@ -24,8 +24,8 @@ class TestServersBootNovaClient(base.ClientTestBase):
def _boot_server_with_legacy_bdm(self, bdm_params=()):
volume_size = 1
volume_name = str(uuid.uuid4())
volume = self.client.volumes.create(size=volume_size,
display_name=volume_name,
volume = self.cinder.volumes.create(size=volume_size,
name=volume_name,
imageRef=self.image.id)
self.wait_for_volume_status(volume, "available")

View File

@ -1,92 +0,0 @@
# 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.
import time
import six.moves
from novaclient import exceptions
from novaclient.tests.functional import base
def wait_for_delete(test, name, thing, get_func):
thing.delete()
for x in six.moves.range(60):
try:
thing = get_func(thing.id)
except exceptions.NotFound:
break
time.sleep(1)
else:
test.fail('%s %s still not deleted after 60s' % (name, thing.id))
class TestVolumesAPI(base.ClientTestBase):
COMPUTE_API_VERSION = "2.1"
def test_volumes_snapshots_types_create_get_list_delete(self):
# Create a volume
volume = self.client.volumes.create(1)
# Make sure we can still list servers after using the volume endpoint
self.client.servers.list()
# This cleanup tests volume delete
self.addCleanup(volume.delete)
# Wait for the volume to become available
self.wait_for_volume_status(volume, 'available')
# List all volumes
self.client.volumes.list()
# Create a volume snapshot
snapshot = self.client.volume_snapshots.create(volume.id)
# This cleanup tests volume snapshot delete. The volume
# can't be deleted until the dependent snapshot is gone
self.addCleanup(wait_for_delete, self, 'Snapshot', snapshot,
self.client.volume_snapshots.get)
# Wait for the snapshot to become available
for x in six.moves.range(60):
snapshot = self.client.volume_snapshots.get(snapshot.id)
if snapshot.status == 'available':
break
elif snapshot.status == 'error':
self.fail('Snapshot %s is in error state' % snapshot.id)
time.sleep(1)
else:
self.fail('Snapshot %s not available after 60s' % snapshot.id)
# List snapshots
self.client.volume_snapshots.list()
# List servers again to make sure things are still good
self.client.servers.list()
# Create a volume type
name = self.name_generate('VolumeType')
volume_type = self.client.volume_types.create(name)
# This cleanup tests volume type delete
self.addCleanup(self.client.volume_types.delete, volume_type.id)
# Get the volume type
volume_type = self.client.volume_types.get(volume_type.id)
# List all volume types
self.client.volume_types.list()
# One more servers list
self.client.servers.list()

View File

@ -1,18 +0,0 @@
# 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 novaclient.tests.functional.v2.legacy import test_volumes_api
class TestVolumesAPI(test_volumes_api.TestVolumesAPI):
COMPUTE_API_VERSION = "2.latest"

View File

@ -58,16 +58,3 @@ class ServiceCatalogTest(utils.TestCase):
# Matching south (and catalog has South).
self.assertRaises(exceptions.AmbiguousEndpoints, sc.url_for,
'region', 'south', service_type='volume')
def test_alternate_service_type(self):
sc = service_catalog.ServiceCatalog(SERVICE_CATALOG)
self.assertRaises(exceptions.AmbiguousEndpoints, sc.url_for,
service_type='volume')
self.assertEqual("https://volume1.host/v1/1",
sc.url_for('tenantId', '1', service_type='volume'))
self.assertEqual("https://volume1.host/v1.1/2",
sc.url_for('tenantId', '2', service_type='volume'))
self.assertRaises(exceptions.EndpointNotFound, sc.url_for,
"region", "North", service_type='volume')

View File

@ -2488,53 +2488,10 @@ class ShellTest(utils.TestCase):
self.run_command('interface-detach 1234 port_id')
self.assert_called('DELETE', '/servers/1234/os-interface/port_id')
def test_volume_list(self):
_, err = self.run_command('volume-list')
self.assertIn('Command volume-list is deprecated', err)
self.assert_called('GET', '/volumes/detail')
def test_volume_show(self):
_, err = self.run_command('volume-show Work')
self.assertIn('Command volume-show is deprecated', err)
self.assert_called('GET', '/volumes?display_name=Work', pos=-2)
self.assert_called(
'GET',
'/volumes/15e59938-07d5-11e1-90e3-e3dffe0c5983',
pos=-1
)
def test_volume_attachments(self):
self.run_command('volume-attachments 1234')
self.assert_called('GET', '/servers/1234/os-volume_attachments')
def test_volume_create(self):
_, err = self.run_command('volume-create 2 --display-name Work')
self.assertIn('Command volume-create is deprecated', err)
self.assert_called('POST', '/volumes',
{'volume':
{'display_name': 'Work',
'imageRef': None,
'availability_zone': None,
'volume_type': None,
'display_description': None,
'snapshot_id': None,
'size': 2}})
def test_volume_delete(self):
_, err = self.run_command('volume-delete Work')
self.assertIn('Command volume-delete is deprecated', err)
self.assert_called('DELETE',
'/volumes/15e59938-07d5-11e1-90e3-e3dffe0c5983')
def test_volume_delete_multiple(self):
self.run_command('volume-delete Work Work2')
self.assert_called('DELETE',
'/volumes/15e59938-07d5-11e1-90e3-e3dffe0c5983',
pos=-4)
self.assert_called('DELETE',
'/volumes/15e59938-07d5-11e1-90e3-ee32ba30feaa',
pos=-1)
def test_volume_attach(self):
self.run_command('volume-attach sample-server Work /dev/vdb')
self.assert_called('POST', '/servers/1234/os-volume_attachments',

View File

@ -13,10 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import warnings
import mock
from novaclient.tests.unit import utils
from novaclient.tests.unit.v2 import fakes
from novaclient.v2 import volumes
@ -27,61 +23,6 @@ cs = fakes.FakeClient()
class VolumesTest(utils.TestCase):
@mock.patch.object(warnings, 'warn')
def test_list_volumes(self, mock_warn):
vl = cs.volumes.list()
self.assert_request_id(vl, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('GET', '/volumes/detail')
for v in vl:
self.assertIsInstance(v, volumes.Volume)
self.assertEqual(1, mock_warn.call_count)
@mock.patch.object(warnings, 'warn')
def test_list_volumes_undetailed(self, mock_warn):
vl = cs.volumes.list(detailed=False)
self.assert_request_id(vl, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('GET', '/volumes')
for v in vl:
self.assertIsInstance(v, volumes.Volume)
self.assertEqual(1, mock_warn.call_count)
@mock.patch.object(warnings, 'warn')
def test_get_volume_details(self, mock_warn):
vol_id = '15e59938-07d5-11e1-90e3-e3dffe0c5983'
v = cs.volumes.get(vol_id)
self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('GET', '/volumes/%s' % vol_id)
self.assertIsInstance(v, volumes.Volume)
self.assertEqual(v.id, vol_id)
self.assertEqual(1, mock_warn.call_count)
@mock.patch.object(warnings, 'warn')
def test_create_volume(self, mock_warn):
v = cs.volumes.create(
size=2,
display_name="My volume",
display_description="My volume desc",
)
self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('POST', '/volumes')
self.assertIsInstance(v, volumes.Volume)
self.assertEqual(1, mock_warn.call_count)
@mock.patch.object(warnings, 'warn')
def test_delete_volume(self, mock_warn):
vol_id = '15e59938-07d5-11e1-90e3-e3dffe0c5983'
v = cs.volumes.get(vol_id)
ret = v.delete()
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('DELETE', '/volumes/%s' % vol_id)
ret = cs.volumes.delete(vol_id)
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('DELETE', '/volumes/%s' % vol_id)
ret = cs.volumes.delete(v)
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
cs.assert_called('DELETE', '/volumes/%s' % vol_id)
self.assertEqual(4, mock_warn.call_count)
def test_create_server_volume(self):
v = cs.volumes.create_server_volume(
server_id=1234,

View File

@ -47,8 +47,6 @@ from novaclient.v2 import services
from novaclient.v2 import usage
from novaclient.v2 import versions
from novaclient.v2 import virtual_interfaces
from novaclient.v2 import volume_snapshots
from novaclient.v2 import volume_types
from novaclient.v2 import volumes
@ -143,8 +141,6 @@ class Client(object):
self.floating_ip_pools = floating_ip_pools.FloatingIPPoolManager(self)
self.fping = fping.FpingManager(self)
self.volumes = volumes.VolumeManager(self)
self.volume_snapshots = volume_snapshots.SnapshotManager(self)
self.volume_types = volume_types.VolumeTypeManager(self)
self.keypairs = keypairs.KeypairManager(self)
self.networks = networks.NetworkManager(self)
self.quota_classes = quota_classes.QuotaClassSetManager(self)

View File

@ -66,14 +66,6 @@ CLIENT_BDM2_KEYS = {
}
# NOTE(mriedem): Remove this along with the deprecated commands in the first
# python-novaclient release AFTER the nova server 13.0.0 'M' release.
def emit_volume_deprecation_warning(command_name):
print('WARNING: Command %s is deprecated and will be removed after Nova '
'13.0.0 is released. Use python-cinderclient or openstackclient '
'instead.' % command_name, file=sys.stderr)
def _key_value_pairing(text):
try:
(k, v) = text.split('=', 1)
@ -2249,137 +2241,6 @@ def _translate_volume_attachments_keys(collection):
('volumeId', 'volume_id')])
@utils.arg(
'--all-tenants',
dest='all_tenants',
metavar='<0|1>',
nargs='?',
type=int,
const=1,
default=int(strutils.bool_from_string(
os.environ.get("ALL_TENANTS", 'false'), True)),
help=_('Display information from all tenants (Admin only).'))
@utils.arg(
'--all_tenants',
nargs='?',
type=int,
const=1,
action=shell.DeprecatedAction,
use=_('use "%s"; this option will be removed in '
'novaclient 3.3.0.') % '--all-tenants',
help=argparse.SUPPRESS)
def do_volume_list(cs, args):
"""DEPRECATED: List all the volumes."""
emit_volume_deprecation_warning('volume-list')
search_opts = {'all_tenants': args.all_tenants}
volumes = cs.volumes.list(search_opts=search_opts)
_translate_volume_keys(volumes)
# Create a list of servers to which the volume is attached
for vol in volumes:
servers = [s.get('server_id') for s in vol.attachments]
setattr(vol, 'attached_to', ','.join(map(str, servers)))
utils.print_list(volumes, ['ID', 'Status', 'Display Name',
'Size', 'Volume Type', 'Attached to'])
@utils.arg(
'volume',
metavar='<volume>',
help=_('Name or ID of the volume.'))
def do_volume_show(cs, args):
"""DEPRECATED: Show details about a volume."""
emit_volume_deprecation_warning('volume-show')
volume = _find_volume(cs, args.volume)
_print_volume(volume)
@utils.arg(
'size',
metavar='<size>',
type=int,
help=_('Size of volume in GB'))
@utils.arg(
'--snapshot-id',
metavar='<snapshot-id>',
default=None,
help=_('Optional snapshot ID to create the volume from. (Default=None)'))
@utils.arg(
'--snapshot_id',
action=shell.DeprecatedAction,
use=_('use "%s"; this option will be removed in '
'novaclient 3.3.0.') % '--snapshot-id',
help=argparse.SUPPRESS)
@utils.arg(
'--image-id',
metavar='<image-id>',
help=_('Optional image ID to create the volume from. (Default=None)'),
default=None)
@utils.arg(
'--display-name',
metavar='<display-name>',
default=None,
help=_('Optional volume name. (Default=None)'))
@utils.arg(
'--display_name',
action=shell.DeprecatedAction,
use=_('use "%s"; this option will be removed in '
'novaclient 3.3.0.') % '--display-name',
help=argparse.SUPPRESS)
@utils.arg(
'--display-description',
metavar='<display-description>',
default=None,
help=_('Optional volume description. (Default=None)'))
@utils.arg(
'--display_description',
action=shell.DeprecatedAction,
use=_('use "%s"; this option will be removed in '
'novaclient 3.3.0.') % '--display-description',
help=argparse.SUPPRESS)
@utils.arg(
'--volume-type',
metavar='<volume-type>',
default=None,
help=_('Optional volume type. (Default=None)'))
@utils.arg(
'--volume_type',
action=shell.DeprecatedAction,
use=_('use "%s"; this option will be removed in '
'novaclient 3.3.0.') % '--volume-type',
help=argparse.SUPPRESS)
@utils.arg(
'--availability-zone', metavar='<availability-zone>',
help=_('Optional Availability Zone for volume. (Default=None)'),
default=None)
def do_volume_create(cs, args):
"""DEPRECATED: Add a new volume."""
emit_volume_deprecation_warning('volume-create')
volume = cs.volumes.create(args.size,
args.snapshot_id,
args.display_name,
args.display_description,
args.volume_type,
args.availability_zone,
imageRef=args.image_id)
_print_volume(volume)
@utils.arg(
'volume',
metavar='<volume>', nargs='+',
help=_('Name or ID of the volume(s) to delete.'))
def do_volume_delete(cs, args):
"""DEPRECATED: Remove volume(s)."""
emit_volume_deprecation_warning('volume-delete')
for volume in args.volume:
try:
_find_volume(cs, volume).delete()
except Exception as e:
print(_("Delete for volume %(volume)s failed: %(e)s") %
{'volume': volume, 'e': e})
@utils.arg(
'server',
metavar='<server>',
@ -2448,111 +2309,6 @@ def do_volume_attachments(cs, args):
utils.print_list(volumes, ['ID', 'DEVICE', 'SERVER ID', 'VOLUME ID'])
def do_volume_snapshot_list(cs, _args):
"""DEPRECATED: List all the snapshots."""
emit_volume_deprecation_warning('volume-snapshot-list')
snapshots = cs.volume_snapshots.list()
_translate_volume_snapshot_keys(snapshots)
utils.print_list(snapshots, ['ID', 'Volume ID', 'Status', 'Display Name',
'Size'])
@utils.arg(
'snapshot',
metavar='<snapshot>',
help=_('Name or ID of the snapshot.'))
def do_volume_snapshot_show(cs, args):
"""DEPRECATED: Show details about a snapshot."""
emit_volume_deprecation_warning('volume-snapshot-show')
snapshot = _find_volume_snapshot(cs, args.snapshot)
_print_volume_snapshot(snapshot)
@utils.arg(
'volume_id',
metavar='<volume-id>',
help=_('ID of the volume to snapshot'))
@utils.arg(
'--force',
metavar='<True|False>',
help=_('Optional flag to indicate whether to snapshot a volume even if '
'its attached to a server. (Default=False)'),
default=False)
@utils.arg(
'--display-name',
metavar='<display-name>',
default=None,
help=_('Optional snapshot name. (Default=None)'))
@utils.arg(
'--display_name',
action=shell.DeprecatedAction,
use=_('use "%s"; this option will be removed in '
'novaclient 3.3.0.') % '--display-name',
help=argparse.SUPPRESS)
@utils.arg(
'--display-description',
metavar='<display-description>',
default=None,
help=_('Optional snapshot description. (Default=None)'))
@utils.arg(
'--display_description',
action=shell.DeprecatedAction,
use=_('use "%s"; this option will be removed in '
'novaclient 3.3.0.') % '--display-description',
help=argparse.SUPPRESS)
def do_volume_snapshot_create(cs, args):
"""DEPRECATED: Add a new snapshot."""
emit_volume_deprecation_warning('volume-snapshot-create')
snapshot = cs.volume_snapshots.create(args.volume_id,
args.force,
args.display_name,
args.display_description)
_print_volume_snapshot(snapshot)
@utils.arg(
'snapshot',
metavar='<snapshot>',
help=_('Name or ID of the snapshot to delete.'))
def do_volume_snapshot_delete(cs, args):
"""DEPRECATED: Remove a snapshot."""
emit_volume_deprecation_warning('volume-snapshot-delete')
snapshot = _find_volume_snapshot(cs, args.snapshot)
snapshot.delete()
def _print_volume_type_list(vtypes):
utils.print_list(vtypes, ['ID', 'Name'])
def do_volume_type_list(cs, args):
"""DEPRECATED: Print a list of available 'volume types'."""
emit_volume_deprecation_warning('volume-type-list')
vtypes = cs.volume_types.list()
_print_volume_type_list(vtypes)
@utils.arg(
'name',
metavar='<name>',
help=_("Name of the new volume type"))
def do_volume_type_create(cs, args):
"""DEPRECATED: Create a new volume type."""
emit_volume_deprecation_warning('volume-type-create')
vtype = cs.volume_types.create(args.name)
_print_volume_type_list([vtype])
@utils.arg(
'id',
metavar='<id>',
help=_("Unique ID of the volume type to delete."))
def do_volume_type_delete(cs, args):
"""DEPRECATED: Delete a specific volume type."""
emit_volume_deprecation_warning('volume-type-delete')
cs.volume_types.delete(args.id)
@api_versions.wraps('2.0', '2.5')
def console_dict_accessor(cs, data):
return data['console']

View File

@ -1,120 +0,0 @@
# Copyright 2011 Denali Systems, Inc.
# 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.
"""
DEPRECATED: Volume snapshot interface (1.1 extension).
"""
import warnings
from novaclient import base
class Snapshot(base.Resource):
"""
DEPRECATED: A Snapshot is a point-in-time snapshot of an openstack volume.
"""
NAME_ATTR = 'display_name'
def __repr__(self):
return "<Snapshot: %s>" % self.id
def delete(self):
"""
DEPRECATED: Delete this snapshot.
:returns: An instance of novaclient.base.TupleWithMeta
"""
return self.manager.delete(self)
class SnapshotManager(base.ManagerWithFind):
"""
DEPRECATED: Manage :class:`Snapshot` resources.
"""
resource_class = Snapshot
def create(self, volume_id, force=False, display_name=None,
display_description=None):
"""
DEPRECATED: Create a snapshot of the given volume.
:param volume_id: The ID of the volume to snapshot.
:param force: If force is True, create a snapshot even if the volume is
attached to an instance. Default is False.
:param display_name: Name of the snapshot
:param display_description: Description of the snapshot
:rtype: :class:`Snapshot`
"""
warnings.warn('The novaclient.v2.volume_snapshots module is '
'deprecated and will be removed after Nova 13.0.0 is '
'released. Use python-cinderclient or '
'python-openstacksdk instead.', DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
body = {'snapshot': {'volume_id': volume_id,
'force': force,
'display_name': display_name,
'display_description': display_description}}
return self._create('/snapshots', body, 'snapshot')
def get(self, snapshot_id):
"""
DEPRECATED: Get a snapshot.
:param snapshot_id: The ID of the snapshot to get.
:rtype: :class:`Snapshot`
"""
warnings.warn('The novaclient.v2.volume_snapshots module is '
'deprecated and will be removed after Nova 13.0.0 is '
'released. Use python-cinderclient or '
'python-openstacksdk instead.', DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
return self._get("/snapshots/%s" % snapshot_id, "snapshot")
def list(self, detailed=True):
"""
DEPRECATED: Get a list of all snapshots.
:rtype: list of :class:`Snapshot`
"""
warnings.warn('The novaclient.v2.volume_snapshots module is '
'deprecated and will be removed after Nova 13.0.0 is '
'released. Use python-cinderclient or '
'python-openstacksdk instead.', DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
if detailed is True:
return self._list("/snapshots/detail", "snapshots")
else:
return self._list("/snapshots", "snapshots")
def delete(self, snapshot):
"""
DEPRECATED: Delete a snapshot.
:param snapshot: The :class:`Snapshot` to delete.
:returns: An instance of novaclient.base.TupleWithMeta
"""
warnings.warn('The novaclient.v2.volume_snapshots module is '
'deprecated and will be removed after Nova 13.0.0 is '
'released. Use python-cinderclient or '
'python-openstacksdk instead.', DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
return self._delete("/snapshots/%s" % base.getid(snapshot))

View File

@ -1,103 +0,0 @@
# Copyright (c) 2011 Rackspace US, Inc.
#
# 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.
"""
DEPRECATED: Volume Type interface.
"""
import warnings
from novaclient import base
class VolumeType(base.Resource):
"""
DEPRECATED: A Volume Type is the type of volume to be created
"""
def __repr__(self):
return "<Volume Type: %s>" % self.name
class VolumeTypeManager(base.ManagerWithFind):
"""
DEPRECATED: Manage :class:`VolumeType` resources.
"""
resource_class = VolumeType
def list(self):
"""
DEPRECATED: Get a list of all volume types.
:rtype: list of :class:`VolumeType`.
"""
warnings.warn('The novaclient.v2.volume_types module is deprecated '
'and will be removed after Nova 13.0.0 is released. Use '
'python-cinderclient or python-openstacksdk instead.',
DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
return self._list("/types", "volume_types")
def get(self, volume_type):
"""
DEPRECATED: Get a specific volume type.
:param volume_type: The ID of the :class:`VolumeType` to get.
:rtype: :class:`VolumeType`
"""
warnings.warn('The novaclient.v2.volume_types module is deprecated '
'and will be removed after Nova 13.0.0 is released. Use '
'python-cinderclient or python-openstacksdk instead.',
DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
return self._get("/types/%s" % base.getid(volume_type),
"volume_type")
def delete(self, volume_type):
"""
DEPRECATED: Delete a specific volume_type.
:param volume_type: The ID of the :class:`VolumeType` to get.
:returns: An instance of novaclient.base.TupleWithMeta
"""
warnings.warn('The novaclient.v2.volume_types module is deprecated '
'and will be removed after Nova 13.0.0 is released. Use '
'python-cinderclient or python-openstacksdk instead.',
DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
return self._delete("/types/%s" % base.getid(volume_type))
def create(self, name):
"""
DEPRECATED: Create a volume type.
:param name: Descriptive name of the volume type
:rtype: :class:`VolumeType`
"""
warnings.warn('The novaclient.v2.volume_types module is deprecated '
'and will be removed after Nova 13.0.0 is released. Use '
'python-cinderclient or python-openstacksdk instead.',
DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
body = {
"volume_type": {
"name": name,
}
}
return self._create("/types", body, "volume_type")

View File

@ -17,17 +17,12 @@
Volume interface (1.1 extension).
"""
import warnings
import six
from six.moves.urllib import parse
from novaclient import base
class Volume(base.Resource):
"""
DEPRECATED: A volume is an extra block level storage to the OpenStack
A volume is an extra block level storage to the OpenStack
instances.
"""
NAME_ATTR = 'display_name'
@ -35,109 +30,13 @@ class Volume(base.Resource):
def __repr__(self):
return "<Volume: %s>" % self.id
def delete(self):
"""
DEPRECATED: Delete this volume.
:returns: An instance of novaclient.base.TupleWithMeta
"""
return self.manager.delete(self)
class VolumeManager(base.ManagerWithFind):
class VolumeManager(base.Manager):
"""
DEPRECATED: Manage :class:`Volume` resources.
Manage :class:`Volume` resources. This is really about volume attachments.
"""
resource_class = Volume
def create(self, size, snapshot_id=None, display_name=None,
display_description=None, volume_type=None,
availability_zone=None, imageRef=None):
"""
DEPRECATED: Create a volume.
:param size: Size of volume in GB
:param snapshot_id: ID of the snapshot
:param display_name: Name of the volume
:param display_description: Description of the volume
:param volume_type: Type of volume
:param availability_zone: Availability Zone for volume
:rtype: :class:`Volume`
:param imageRef: reference to an image stored in glance
"""
warnings.warn('The novaclient.v2.volumes.VolumeManager.create() '
'method is deprecated and will be removed after Nova '
'13.0.0 is released. Use python-cinderclient or '
'python-openstacksdk instead.', DeprecationWarning)
# NOTE(melwitt): Ensure we use the volume endpoint for this call
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
body = {'volume': {'size': size,
'snapshot_id': snapshot_id,
'display_name': display_name,
'display_description': display_description,
'volume_type': volume_type,
'availability_zone': availability_zone,
'imageRef': imageRef}}
return self._create('/volumes', body, 'volume')
def get(self, volume_id):
"""
DEPRECATED: Get a volume.
:param volume_id: The ID of the volume to get.
:rtype: :class:`Volume`
"""
warnings.warn('The novaclient.v2.volumes.VolumeManager.get() '
'method is deprecated and will be removed after Nova '
'13.0.0 is released. Use python-cinderclient or '
'python-openstacksdk instead.', DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
return self._get("/volumes/%s" % volume_id, "volume")
def list(self, detailed=True, search_opts=None):
"""
DEPRECATED: Get a list of all volumes.
:rtype: list of :class:`Volume`
"""
warnings.warn('The novaclient.v2.volumes.VolumeManager.list() '
'method is deprecated and will be removed after Nova '
'13.0.0 is released. Use python-cinderclient or '
'python-openstacksdk instead.', DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
search_opts = search_opts or {}
if 'name' in search_opts.keys():
search_opts['display_name'] = search_opts.pop('name')
qparams = dict((k, v) for (k, v) in
six.iteritems(search_opts) if v)
query_str = '?%s' % parse.urlencode(qparams) if qparams else ''
if detailed is True:
return self._list("/volumes/detail%s" % query_str, "volumes")
else:
return self._list("/volumes%s" % query_str, "volumes")
def delete(self, volume):
"""
DEPRECATED: Delete a volume.
:param volume: The :class:`Volume` to delete.
:returns: An instance of novaclient.base.TupleWithMeta
"""
warnings.warn('The novaclient.v2.volumes.VolumeManager.delete() '
'method is deprecated and will be removed after Nova '
'13.0.0 is released. Use python-cinderclient or '
'python-openstacksdk instead.', DeprecationWarning)
with self.alternate_service_type(
'volumev2', allowed_types=('volume', 'volumev2')):
return self._delete("/volumes/%s" % base.getid(volume))
def create_server_volume(self, server_id, volume_id, device=None):
"""
Attach a volume identified by the volume ID to the given server ID

View File

@ -0,0 +1,6 @@
---
upgrade:
- Volume, volume-type and volume-snapshot create/update/delete/list CLIs
and python API bindings are removed. Use python-cinderclient or
python-openstackclient for CLIs instead. Use python-cinderclient or
python-openstacksdk for python API bindings instead.

View File

@ -10,6 +10,7 @@ fixtures>=1.3.1 # Apache-2.0/BSD
keyring>=5.5.1 # MIT/PSF
mock>=1.2 # BSD
python-keystoneclient!=1.8.0,!=2.1.0,>=1.6.0 # Apache-2.0
python-cinderclient>=1.3.1 # Apache-2.0
requests-mock>=0.7.0 # Apache-2.0
sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
os-client-config>=1.13.1 # Apache-2.0