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:
parent
14bbfc497b
commit
84f5c6165b
@ -33,6 +33,9 @@ Possible values:
|
|||||||
* Format is separated values of the form:
|
* Format is separated values of the form:
|
||||||
<service_type>:<service_name>:<endpoint_type>
|
<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:
|
Related options:
|
||||||
|
|
||||||
* endpoint_template - Setting this option will override catalog_info
|
* endpoint_template - Setting this option will override catalog_info
|
||||||
@ -45,7 +48,10 @@ this template for cinder endpoint
|
|||||||
Possible values:
|
Possible values:
|
||||||
|
|
||||||
* URL for cinder endpoint API
|
* 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:
|
Related options:
|
||||||
|
|
||||||
|
@ -141,6 +141,10 @@ class CinderConnectionFailed(NovaException):
|
|||||||
msg_fmt = _("Connection to cinder host failed: %(reason)s")
|
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):
|
class Forbidden(NovaException):
|
||||||
msg_fmt = _("Forbidden")
|
msg_fmt = _("Forbidden")
|
||||||
code = 403
|
code = 403
|
||||||
|
@ -14,10 +14,9 @@
|
|||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from cinderclient.v1 import client as cinder_client_v1
|
|
||||||
from cinderclient.v2 import client as cinder_client_v2
|
from cinderclient.v2 import client as cinder_client_v2
|
||||||
|
import mock
|
||||||
from requests_mock.contrib import fixture
|
from requests_mock.contrib import fixture
|
||||||
from testtools import matchers
|
|
||||||
|
|
||||||
import nova.conf
|
import nova.conf
|
||||||
from nova import context
|
from nova import context
|
||||||
@ -115,63 +114,25 @@ class BaseCinderTestCase(object):
|
|||||||
self.assertEqual(cacert, self.create_client().client.session.verify)
|
self.assertEqual(cacert, self.create_client().client.session.verify)
|
||||||
|
|
||||||
|
|
||||||
class CinderTestCase(BaseCinderTestCase, test.NoDBTestCase):
|
# NOTE(mriedem): This does not extend BaseCinderTestCase because Cinder v1 is
|
||||||
"""Test case for cinder volume v1 api."""
|
# 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"
|
@mock.patch.object(cinder.ks_loading, 'load_session_from_conf_options')
|
||||||
|
@mock.patch.object(cinder.cinder_client, 'get_volume_api_from_url',
|
||||||
CATALOG = [{
|
return_value='1')
|
||||||
"type": "volumev2",
|
def test_cinderclient_unsupported_v1(self, get_api_version, load_session):
|
||||||
"name": "cinderv2",
|
"""Tests that we fail if trying to use Cinder v1."""
|
||||||
"endpoints": [{"publicURL": URL}]
|
self.flags(catalog_info='volume:cinder:publicURL', group='cinder')
|
||||||
}]
|
# setup mocks
|
||||||
|
get_endpoint = mock.Mock(
|
||||||
def create_client(self):
|
return_value='http://localhost:8776/v1/%(project_id)s')
|
||||||
c = super(CinderTestCase, self).create_client()
|
fake_session = mock.Mock(get_endpoint=get_endpoint)
|
||||||
self.assertIsInstance(c, cinder_client_v1.Client)
|
load_session.return_value = fake_session
|
||||||
return c
|
ctxt = context.get_admin_context()
|
||||||
|
self.assertRaises(exception.UnsupportedCinderAPIVersion,
|
||||||
def stub_volume(self, **kwargs):
|
cinder.cinderclient, ctxt)
|
||||||
volume = {
|
get_api_version.assert_called_once_with(get_endpoint.return_value)
|
||||||
'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'])
|
|
||||||
|
|
||||||
|
|
||||||
class CinderV2TestCase(BaseCinderTestCase, test.NoDBTestCase):
|
class CinderV2TestCase(BaseCinderTestCase, test.NoDBTestCase):
|
||||||
|
@ -25,7 +25,6 @@ import sys
|
|||||||
|
|
||||||
from cinderclient import client as cinder_client
|
from cinderclient import client as cinder_client
|
||||||
from cinderclient import exceptions as cinder_exception
|
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 exceptions as keystone_exception
|
||||||
from keystoneauth1 import loading as ks_loading
|
from keystoneauth1 import loading as ks_loading
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
@ -47,7 +46,6 @@ CONF = nova.conf.CONF
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
_SESSION = None
|
_SESSION = None
|
||||||
_V1_ERROR_RAISED = False
|
|
||||||
|
|
||||||
|
|
||||||
def reset_globals():
|
def reset_globals():
|
||||||
@ -59,7 +57,6 @@ def reset_globals():
|
|||||||
|
|
||||||
def cinderclient(context):
|
def cinderclient(context):
|
||||||
global _SESSION
|
global _SESSION
|
||||||
global _V1_ERROR_RAISED
|
|
||||||
|
|
||||||
if not _SESSION:
|
if not _SESSION:
|
||||||
_SESSION = ks_loading.load_session_from_conf_options(
|
_SESSION = ks_loading.load_session_from_conf_options(
|
||||||
@ -87,13 +84,8 @@ def cinderclient(context):
|
|||||||
# values.
|
# values.
|
||||||
version = cinder_client.get_volume_api_from_url(url)
|
version = cinder_client.get_volume_api_from_url(url)
|
||||||
|
|
||||||
if version == '1' and not _V1_ERROR_RAISED:
|
if version == '1':
|
||||||
msg = _LW('Cinder V1 API is deprecated as of the Juno '
|
raise exception.UnsupportedCinderAPIVersion(version=version)
|
||||||
'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
|
|
||||||
|
|
||||||
return cinder_client.Client(version,
|
return cinder_client.Client(version,
|
||||||
session=_SESSION,
|
session=_SESSION,
|
||||||
@ -132,14 +124,8 @@ def _untranslate_volume_summary_view(context, vol):
|
|||||||
d['attach_status'] = 'attached'
|
d['attach_status'] = 'attached'
|
||||||
else:
|
else:
|
||||||
d['attach_status'] = 'detached'
|
d['attach_status'] = 'detached'
|
||||||
# NOTE(dzyu) volume(cinder) v2 API uses 'name' instead of 'display_name',
|
d['display_name'] = vol.name
|
||||||
# and use 'description' instead of 'display_description' for volume.
|
d['display_description'] = vol.description
|
||||||
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
|
|
||||||
# TODO(jdg): Information may be lost in this translation
|
# TODO(jdg): Information may be lost in this translation
|
||||||
d['volume_type_id'] = vol.volume_type
|
d['volume_type_id'] = vol.volume_type
|
||||||
d['snapshot_id'] = vol.snapshot_id
|
d['snapshot_id'] = vol.snapshot_id
|
||||||
@ -163,15 +149,8 @@ def _untranslate_snapshot_summary_view(context, snapshot):
|
|||||||
d['progress'] = snapshot.progress
|
d['progress'] = snapshot.progress
|
||||||
d['size'] = snapshot.size
|
d['size'] = snapshot.size
|
||||||
d['created_at'] = snapshot.created_at
|
d['created_at'] = snapshot.created_at
|
||||||
|
d['display_name'] = snapshot.name
|
||||||
# NOTE(dzyu) volume(cinder) v2 API uses 'name' instead of 'display_name',
|
d['display_description'] = snapshot.description
|
||||||
# '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['volume_id'] = snapshot.volume_id
|
d['volume_id'] = snapshot.volume_id
|
||||||
d['project_id'] = snapshot.project_id
|
d['project_id'] = snapshot.project_id
|
||||||
@ -438,14 +417,9 @@ class API(object):
|
|||||||
project_id=context.project_id,
|
project_id=context.project_id,
|
||||||
availability_zone=availability_zone,
|
availability_zone=availability_zone,
|
||||||
metadata=metadata,
|
metadata=metadata,
|
||||||
imageRef=image_id)
|
imageRef=image_id,
|
||||||
|
name=name,
|
||||||
if isinstance(client, v1_client.Client):
|
description=description)
|
||||||
kwargs['display_name'] = name
|
|
||||||
kwargs['display_description'] = description
|
|
||||||
else:
|
|
||||||
kwargs['name'] = name
|
|
||||||
kwargs['description'] = description
|
|
||||||
|
|
||||||
item = client.volumes.create(size, **kwargs)
|
item = client.volumes.create(size, **kwargs)
|
||||||
return _untranslate_volume_summary_view(context, item)
|
return _untranslate_volume_summary_view(context, item)
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- Nova no longer supports the deprecated Cinder v1 API.
|
Loading…
Reference in New Issue
Block a user