Remove support for the Cinder v1 API

The Cinder v1 API is deprecated and Nova has been emitting
a warning when using it since Juno, so it's time to drop the
support as we start looking to support the new Cinder v3 API.

Change-Id: I8eb9ca88be81cc04c4feb3bafda2d8aa79a12dc4
This commit is contained in:
Matt Riedemann 2016-12-12 12:49:11 -05:00
parent 14bbfc497b
commit 84f5c6165b
5 changed files with 42 additions and 94 deletions

View File

@ -33,6 +33,9 @@ Possible values:
* Format is separated values of the form:
<service_type>:<service_name>:<endpoint_type>
Note: Nova does not support the Cinder v1 API since the Nova 15.0.0 Ocata
release.
Related options:
* endpoint_template - Setting this option will override catalog_info
@ -45,7 +48,10 @@ this template for cinder endpoint
Possible values:
* URL for cinder endpoint API
e.g. http://localhost:8776/v1/%(project_id)s
e.g. http://localhost:8776/v2/%(project_id)s
Note: Nova does not support the Cinder v1 API since the Nova 15.0.0 Ocata
release.
Related options:

View File

@ -141,6 +141,10 @@ class CinderConnectionFailed(NovaException):
msg_fmt = _("Connection to cinder host failed: %(reason)s")
class UnsupportedCinderAPIVersion(NovaException):
msg_fmt = _('Nova does not support Cinder API version %(version)s')
class Forbidden(NovaException):
msg_fmt = _("Forbidden")
code = 403

View File

@ -14,10 +14,9 @@
import collections
from cinderclient.v1 import client as cinder_client_v1
from cinderclient.v2 import client as cinder_client_v2
import mock
from requests_mock.contrib import fixture
from testtools import matchers
import nova.conf
from nova import context
@ -115,63 +114,25 @@ class BaseCinderTestCase(object):
self.assertEqual(cacert, self.create_client().client.session.verify)
class CinderTestCase(BaseCinderTestCase, test.NoDBTestCase):
"""Test case for cinder volume v1 api."""
# NOTE(mriedem): This does not extend BaseCinderTestCase because Cinder v1 is
# no longer supported, this is just to test that trying to use v1 fails.
class CinderV1TestCase(test.NoDBTestCase):
URL = "http://localhost:8776/v1/project_id"
CATALOG = [{
"type": "volumev2",
"name": "cinderv2",
"endpoints": [{"publicURL": URL}]
}]
def create_client(self):
c = super(CinderTestCase, self).create_client()
self.assertIsInstance(c, cinder_client_v1.Client)
return c
def stub_volume(self, **kwargs):
volume = {
'display_name': None,
'display_description': None,
"attachments": [],
"availability_zone": "cinder",
"created_at": "2012-09-10T00:00:00.000000",
"id": _volume_id,
"metadata": {},
"size": 1,
"snapshot_id": None,
"status": "available",
"volume_type": "None",
"bootable": "true",
"multiattach": "true"
}
volume.update(kwargs)
return volume
def test_cinder_endpoint_template(self):
endpoint = 'http://other_host:8776/v1/%(project_id)s'
self.flags(endpoint_template=endpoint, group='cinder')
self.assertEqual('http://other_host:8776/v1/project_id',
self.create_client().client.endpoint_override)
def test_get_non_existing_volume(self):
self.requests.get(self.URL + '/volumes/nonexisting',
status_code=404)
self.assertRaises(exception.VolumeNotFound, self.api.get, self.context,
'nonexisting')
def test_volume_with_image_metadata(self):
v = self.stub_volume(id='1234', volume_image_metadata=_image_metadata)
m = self.requests.get(self.URL + '/volumes/5678', json={'volume': v})
volume = self.api.get(self.context, '5678')
self.assertThat(m.last_request.path,
matchers.EndsWith('/volumes/5678'))
self.assertIn('volume_image_metadata', volume)
self.assertEqual(_image_metadata, volume['volume_image_metadata'])
@mock.patch.object(cinder.ks_loading, 'load_session_from_conf_options')
@mock.patch.object(cinder.cinder_client, 'get_volume_api_from_url',
return_value='1')
def test_cinderclient_unsupported_v1(self, get_api_version, load_session):
"""Tests that we fail if trying to use Cinder v1."""
self.flags(catalog_info='volume:cinder:publicURL', group='cinder')
# setup mocks
get_endpoint = mock.Mock(
return_value='http://localhost:8776/v1/%(project_id)s')
fake_session = mock.Mock(get_endpoint=get_endpoint)
load_session.return_value = fake_session
ctxt = context.get_admin_context()
self.assertRaises(exception.UnsupportedCinderAPIVersion,
cinder.cinderclient, ctxt)
get_api_version.assert_called_once_with(get_endpoint.return_value)
class CinderV2TestCase(BaseCinderTestCase, test.NoDBTestCase):

View File

@ -25,7 +25,6 @@ import sys
from cinderclient import client as cinder_client
from cinderclient import exceptions as cinder_exception
from cinderclient.v1 import client as v1_client
from keystoneauth1 import exceptions as keystone_exception
from keystoneauth1 import loading as ks_loading
from oslo_log import log as logging
@ -47,7 +46,6 @@ CONF = nova.conf.CONF
LOG = logging.getLogger(__name__)
_SESSION = None
_V1_ERROR_RAISED = False
def reset_globals():
@ -59,7 +57,6 @@ def reset_globals():
def cinderclient(context):
global _SESSION
global _V1_ERROR_RAISED
if not _SESSION:
_SESSION = ks_loading.load_session_from_conf_options(
@ -87,13 +84,8 @@ def cinderclient(context):
# values.
version = cinder_client.get_volume_api_from_url(url)
if version == '1' and not _V1_ERROR_RAISED:
msg = _LW('Cinder V1 API is deprecated as of the Juno '
'release, and Nova is still configured to use it. '
'Enable the V2 API in Cinder and set '
'cinder.catalog_info in nova.conf to use it.')
LOG.warning(msg)
_V1_ERROR_RAISED = True
if version == '1':
raise exception.UnsupportedCinderAPIVersion(version=version)
return cinder_client.Client(version,
session=_SESSION,
@ -132,14 +124,8 @@ def _untranslate_volume_summary_view(context, vol):
d['attach_status'] = 'attached'
else:
d['attach_status'] = 'detached'
# NOTE(dzyu) volume(cinder) v2 API uses 'name' instead of 'display_name',
# and use 'description' instead of 'display_description' for volume.
if hasattr(vol, 'display_name'):
d['display_name'] = vol.display_name
d['display_description'] = vol.display_description
else:
d['display_name'] = vol.name
d['display_description'] = vol.description
d['display_name'] = vol.name
d['display_description'] = vol.description
# TODO(jdg): Information may be lost in this translation
d['volume_type_id'] = vol.volume_type
d['snapshot_id'] = vol.snapshot_id
@ -163,15 +149,8 @@ def _untranslate_snapshot_summary_view(context, snapshot):
d['progress'] = snapshot.progress
d['size'] = snapshot.size
d['created_at'] = snapshot.created_at
# NOTE(dzyu) volume(cinder) v2 API uses 'name' instead of 'display_name',
# 'description' instead of 'display_description' for snapshot.
if hasattr(snapshot, 'display_name'):
d['display_name'] = snapshot.display_name
d['display_description'] = snapshot.display_description
else:
d['display_name'] = snapshot.name
d['display_description'] = snapshot.description
d['display_name'] = snapshot.name
d['display_description'] = snapshot.description
d['volume_id'] = snapshot.volume_id
d['project_id'] = snapshot.project_id
@ -438,14 +417,9 @@ class API(object):
project_id=context.project_id,
availability_zone=availability_zone,
metadata=metadata,
imageRef=image_id)
if isinstance(client, v1_client.Client):
kwargs['display_name'] = name
kwargs['display_description'] = description
else:
kwargs['name'] = name
kwargs['description'] = description
imageRef=image_id,
name=name,
description=description)
item = client.volumes.create(size, **kwargs)
return _untranslate_volume_summary_view(context, item)

View File

@ -0,0 +1,3 @@
---
upgrade:
- Nova no longer supports the deprecated Cinder v1 API.