Deprecate the V1 API
This gives a warning for using the V1 API in Juno and encourages users to switch to V2 before the K release where it will be removed. DocImpact Implements blueprint deprecate-v1-api Change-Id: I89eb9eb2a7819edb2a97b2ea2b5239a89124ca4d
This commit is contained in:
parent
e412605618
commit
dce0424d90
@ -18,12 +18,20 @@
|
||||
from oslo.config import cfg
|
||||
import paste.urlmap
|
||||
|
||||
from cinder.openstack.common.gettextutils import _
|
||||
from cinder.openstack.common import log as logging
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def root_app_factory(loader, global_conf, **local_conf):
|
||||
if not CONF.enable_v1_api:
|
||||
if CONF.enable_v1_api:
|
||||
LOG.warn(_('The v1 api is deprecated and will be removed after the '
|
||||
'Juno release. You should set enable_v1_api=false and '
|
||||
'enable_v2_api=true in your cinder.conf file.'))
|
||||
else:
|
||||
del local_conf['/v1']
|
||||
if not CONF.enable_v2_api:
|
||||
del local_conf['/v2']
|
||||
|
@ -46,7 +46,8 @@ CONF.register_opts(api_common_opts)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
XML_NS_V1 = 'http://docs.openstack.org/volume/api/v1'
|
||||
XML_NS_V1 = 'http://docs.openstack.org/api/openstack-block-storage/1.0/content'
|
||||
XML_NS_V2 = 'http://docs.openstack.org/api/openstack-block-storage/2.0/content'
|
||||
|
||||
|
||||
# Regex that matches alphanumeric characters, periods, hypens,
|
||||
|
@ -57,7 +57,7 @@ class Volume_host_attribute(extensions.ExtensionDescriptor):
|
||||
name = "VolumeHostAttribute"
|
||||
alias = "os-vol-host-attr"
|
||||
namespace = ("http://docs.openstack.org/volume/ext/"
|
||||
"volume_host_attribute/api/v1")
|
||||
"volume_host_attribute/api/v2")
|
||||
updated = "2011-11-03T00:00:00+00:00"
|
||||
|
||||
def get_controller_extensions(self):
|
||||
|
@ -55,7 +55,7 @@ class Volume_tenant_attribute(extensions.ExtensionDescriptor):
|
||||
name = "VolumeTenantAttribute"
|
||||
alias = "os-vol-tenant-attr"
|
||||
namespace = ("http://docs.openstack.org/volume/ext/"
|
||||
"volume_tenant_attribute/api/v1")
|
||||
"volume_tenant_attribute/api/v2")
|
||||
updated = "2011-11-03T00:00:00+00:00"
|
||||
|
||||
def get_controller_extensions(self):
|
||||
|
@ -33,8 +33,9 @@ from cinder import utils
|
||||
from cinder import wsgi
|
||||
|
||||
|
||||
XMLNS_V1 = 'http://docs.openstack.org/volume/api/v1'
|
||||
XMLNS_ATOM = 'http://www.w3.org/2005/Atom'
|
||||
XML_NS_V1 = 'http://docs.openstack.org/api/openstack-block-storage/1.0/content'
|
||||
XML_NS_V2 = 'http://docs.openstack.org/api/openstack-block-storage/2.0/content'
|
||||
XML_NS_ATOM = 'http://www.w3.org/2005/Atom'
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -1168,7 +1169,7 @@ class Fault(webob.exc.HTTPException):
|
||||
# 'code' is an attribute on the fault tag itself
|
||||
metadata = {'attributes': {fault_name: 'code'}}
|
||||
|
||||
xml_serializer = XMLDictSerializer(metadata, XMLNS_V1)
|
||||
xml_serializer = XMLDictSerializer(metadata, XML_NS_V2)
|
||||
|
||||
content_type = req.best_match_content_type()
|
||||
serializer = {
|
||||
@ -1229,7 +1230,7 @@ class OverLimitFault(webob.exc.HTTPException):
|
||||
self.content['overLimitFault']['details'] = \
|
||||
translate(self.content['overLimitFault']['details'])
|
||||
|
||||
xml_serializer = XMLDictSerializer(metadata, XMLNS_V1)
|
||||
xml_serializer = XMLDictSerializer(metadata, XML_NS_V2)
|
||||
serializer = {
|
||||
'application/xml': xml_serializer,
|
||||
'application/json': JSONDictSerializer(),
|
||||
|
@ -52,8 +52,8 @@ _KNOWN_VERSIONS = {
|
||||
},
|
||||
"v1.0": {
|
||||
"id": "v1.0",
|
||||
"status": "CURRENT",
|
||||
"updated": "2012-01-04T11:33:21Z",
|
||||
"status": "SUPPORTED",
|
||||
"updated": "2014-06-28T12:20:21Z",
|
||||
"links": [
|
||||
{
|
||||
"rel": "describedby",
|
||||
@ -139,7 +139,7 @@ class AtomSerializer(wsgi.XMLDictSerializer):
|
||||
def __init__(self, metadata=None, xmlns=None):
|
||||
self.metadata = metadata or {}
|
||||
if not xmlns:
|
||||
self.xmlns = wsgi.XMLNS_ATOM
|
||||
self.xmlns = wsgi.XML_NS_ATOM
|
||||
else:
|
||||
self.xmlns = xmlns
|
||||
|
||||
|
@ -26,8 +26,9 @@ XMLNS_V10 = 'http://docs.rackspacecloud.com/servers/api/v1.0'
|
||||
XMLNS_V11 = 'http://docs.openstack.org/compute/api/v1.1'
|
||||
XMLNS_COMMON_V10 = 'http://docs.openstack.org/common/api/v1.0'
|
||||
XMLNS_ATOM = 'http://www.w3.org/2005/Atom'
|
||||
XMLNS_VOLUME_V1 = 'http://docs.openstack.org/volume/api/v1'
|
||||
XMLNS_VOLUME_V2 = ('http://docs.openstack.org/api/openstack-volume/2.0/'
|
||||
XMLNS_VOLUME_V1 = ('http://docs.openstack.org/api/openstack-block-storage/1.0/'
|
||||
'content')
|
||||
XMLNS_VOLUME_V2 = ('http://docs.openstack.org/api/openstack-block-storage/2.0/'
|
||||
'content')
|
||||
|
||||
_split_pattern = re.compile(r'([^:{]*{[^}]*}[^:]*|[^:]+)')
|
||||
|
@ -116,7 +116,7 @@ global_opts = [
|
||||
help='The topic that volume backup nodes listen on'),
|
||||
cfg.BoolOpt('enable_v1_api',
|
||||
default=True,
|
||||
help=_("Deploy v1 of the Cinder API.")),
|
||||
help=_("DEPRECATED: Deploy v1 of the Cinder API.")),
|
||||
cfg.BoolOpt('enable_v2_api',
|
||||
default=True,
|
||||
help=_("Deploy v2 of the Cinder API.")),
|
||||
|
@ -400,27 +400,27 @@ class ServicesTest(test.TestCase):
|
||||
|
||||
def test_services_enable_with_service_key(self):
|
||||
body = {'host': 'host1', 'service': 'cinder-volume'}
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/os-services/enable')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/os-services/enable')
|
||||
res_dict = self.controller.update(req, "enable", body)
|
||||
|
||||
self.assertEqual(res_dict['status'], 'enabled')
|
||||
|
||||
def test_services_enable_with_binary_key(self):
|
||||
body = {'host': 'host1', 'binary': 'cinder-volume'}
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/os-services/enable')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/os-services/enable')
|
||||
res_dict = self.controller.update(req, "enable", body)
|
||||
|
||||
self.assertEqual(res_dict['status'], 'enabled')
|
||||
|
||||
def test_services_disable_with_service_key(self):
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/os-services/disable')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/os-services/disable')
|
||||
body = {'host': 'host1', 'service': 'cinder-volume'}
|
||||
res_dict = self.controller.update(req, "disable", body)
|
||||
|
||||
self.assertEqual(res_dict['status'], 'disabled')
|
||||
|
||||
def test_services_disable_with_binary_key(self):
|
||||
req = fakes.HTTPRequest.blank('/v1/fake/os-services/disable')
|
||||
req = fakes.HTTPRequest.blank('/v2/fake/os-services/disable')
|
||||
body = {'host': 'host1', 'binary': 'cinder-volume'}
|
||||
res_dict = self.controller.update(req, "disable", body)
|
||||
|
||||
|
@ -121,7 +121,7 @@ class VolumeHostAttributeTest(test.TestCase):
|
||||
res = req.get_response(app())
|
||||
vol = etree.XML(res.body)
|
||||
host_key = ('{http://docs.openstack.org/volume/ext/'
|
||||
'volume_host_attribute/api/v1}host')
|
||||
'volume_host_attribute/api/v2}host')
|
||||
self.assertEqual(vol.get(host_key), 'host001')
|
||||
|
||||
def test_list_volumes_detail_xml(self):
|
||||
@ -133,5 +133,5 @@ class VolumeHostAttributeTest(test.TestCase):
|
||||
res = req.get_response(app())
|
||||
vol = list(etree.XML(res.body))[0]
|
||||
host_key = ('{http://docs.openstack.org/volume/ext/'
|
||||
'volume_host_attribute/api/v1}host')
|
||||
'volume_host_attribute/api/v2}host')
|
||||
self.assertEqual(vol.get(host_key), 'host001')
|
||||
|
@ -121,7 +121,7 @@ class VolumeTenantAttributeTest(test.TestCase):
|
||||
res = req.get_response(app())
|
||||
vol = etree.XML(res.body)
|
||||
tenant_key = ('{http://docs.openstack.org/volume/ext/'
|
||||
'volume_tenant_attribute/api/v1}tenant_id')
|
||||
'volume_tenant_attribute/api/v2}tenant_id')
|
||||
self.assertEqual(vol.get(tenant_key), PROJECT_ID)
|
||||
|
||||
def test_list_volumes_detail_xml(self):
|
||||
@ -133,5 +133,5 @@ class VolumeTenantAttributeTest(test.TestCase):
|
||||
res = req.get_response(app())
|
||||
vol = list(etree.XML(res.body))[0]
|
||||
tenant_key = ('{http://docs.openstack.org/volume/ext/'
|
||||
'volume_tenant_attribute/api/v1}tenant_id')
|
||||
'volume_tenant_attribute/api/v2}tenant_id')
|
||||
self.assertEqual(vol.get(tenant_key), PROJECT_ID)
|
||||
|
@ -186,14 +186,14 @@ class TestFaults(test.TestCase):
|
||||
self.assertEqual(fault.status_int, 400)
|
||||
|
||||
def test_xml_serializer(self):
|
||||
"""Ensure that a v1.1 request responds with a v1 xmlns."""
|
||||
request = webob.Request.blank('/v1',
|
||||
"""Ensure that a v2 request responds with a v2 xmlns."""
|
||||
request = webob.Request.blank('/v2',
|
||||
headers={"Accept": "application/xml"})
|
||||
|
||||
fault = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='scram'))
|
||||
response = request.get_response(fault)
|
||||
|
||||
self.assertIn(common.XML_NS_V1, response.body)
|
||||
self.assertIn(common.XML_NS_V2, response.body)
|
||||
self.assertEqual(response.content_type, "application/xml")
|
||||
self.assertEqual(response.status_int, 400)
|
||||
|
||||
@ -277,3 +277,84 @@ class FaultsXMLSerializationTestV11(test.TestCase):
|
||||
""") % common.XML_NS_V1)
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
|
||||
class FaultsXMLSerializationTestV2(test.TestCase):
|
||||
"""Tests covering `cinder.api.openstack.faults:Fault` class."""
|
||||
|
||||
def _prepare_xml(self, xml_string):
|
||||
xml_string = xml_string.replace(" ", "")
|
||||
xml_string = xml_string.replace("\n", "")
|
||||
xml_string = xml_string.replace("\t", "")
|
||||
return xml_string
|
||||
|
||||
def test_400_fault(self):
|
||||
metadata = {'attributes': {"badRequest": 'code'}}
|
||||
serializer = wsgi.XMLDictSerializer(metadata=metadata,
|
||||
xmlns=common.XML_NS_V2)
|
||||
|
||||
fixture = {
|
||||
"badRequest": {
|
||||
"message": "scram",
|
||||
"code": 400,
|
||||
},
|
||||
}
|
||||
|
||||
output = serializer.serialize(fixture)
|
||||
actual = minidom.parseString(self._prepare_xml(output))
|
||||
|
||||
expected = minidom.parseString(self._prepare_xml("""
|
||||
<badRequest code="400" xmlns="%s">
|
||||
<message>scram</message>
|
||||
</badRequest>
|
||||
""") % common.XML_NS_V2)
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_413_fault(self):
|
||||
metadata = {'attributes': {"overLimit": 'code'}}
|
||||
serializer = wsgi.XMLDictSerializer(metadata=metadata,
|
||||
xmlns=common.XML_NS_V2)
|
||||
|
||||
fixture = {
|
||||
"overLimit": {
|
||||
"message": "sorry",
|
||||
"code": 413,
|
||||
"retryAfter": 4,
|
||||
},
|
||||
}
|
||||
|
||||
output = serializer.serialize(fixture)
|
||||
actual = minidom.parseString(self._prepare_xml(output))
|
||||
|
||||
expected = minidom.parseString(self._prepare_xml("""
|
||||
<overLimit code="413" xmlns="%s">
|
||||
<message>sorry</message>
|
||||
<retryAfter>4</retryAfter>
|
||||
</overLimit>
|
||||
""") % common.XML_NS_V2)
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_404_fault(self):
|
||||
metadata = {'attributes': {"itemNotFound": 'code'}}
|
||||
serializer = wsgi.XMLDictSerializer(metadata=metadata,
|
||||
xmlns=common.XML_NS_V2)
|
||||
|
||||
fixture = {
|
||||
"itemNotFound": {
|
||||
"message": "sorry",
|
||||
"code": 404,
|
||||
},
|
||||
}
|
||||
|
||||
output = serializer.serialize(fixture)
|
||||
actual = minidom.parseString(self._prepare_xml(output))
|
||||
|
||||
expected = minidom.parseString(self._prepare_xml("""
|
||||
<itemNotFound code="404" xmlns="%s">
|
||||
<message>sorry</message>
|
||||
</itemNotFound>
|
||||
""") % common.XML_NS_V2)
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
@ -33,7 +33,7 @@ from cinder import utils
|
||||
from cinder.volume import api as volume_api
|
||||
|
||||
|
||||
NS = '{http://docs.openstack.org/volume/api/v1}'
|
||||
NS = '{http://docs.openstack.org/api/openstack-block-storage/1.0/content}'
|
||||
|
||||
TEST_SNAPSHOT_UUID = '00000000-0000-0000-0000-000000000001'
|
||||
|
||||
|
@ -36,7 +36,7 @@ from cinder.volume import api as volume_api
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
NS = '{http://docs.openstack.org/api/openstack-volume/2.0/content}'
|
||||
NS = '{http://docs.openstack.org/api/openstack-block-storage/2.0/content}'
|
||||
|
||||
TEST_SNAPSHOT_UUID = '00000000-0000-0000-0000-000000000001'
|
||||
|
||||
|
@ -80,7 +80,7 @@ class _IntegratedTestBase(test.TestCase):
|
||||
self.osapi.start()
|
||||
# FIXME(ja): this is not the auth url - this is the service url
|
||||
# FIXME(ja): this needs fixed in nova as well
|
||||
self.auth_url = 'http://%s:%s/v1' % (self.osapi.host, self.osapi.port)
|
||||
self.auth_url = 'http://%s:%s/v2' % (self.osapi.host, self.osapi.port)
|
||||
LOG.warn(self.auth_url)
|
||||
|
||||
def _get_flags(self):
|
||||
|
@ -35,7 +35,7 @@ class VolumesTest(integrated_helpers._IntegratedTestBase):
|
||||
def _start_api_service(self):
|
||||
self.osapi = service.WSGIService("osapi_volume")
|
||||
self.osapi.start()
|
||||
self.auth_url = 'http://%s:%s/v1' % (self.osapi.host, self.osapi.port)
|
||||
self.auth_url = 'http://%s:%s/v2' % (self.osapi.host, self.osapi.port)
|
||||
LOG.warn(self.auth_url)
|
||||
|
||||
def _get_flags(self):
|
||||
@ -179,16 +179,16 @@ class VolumesTest(integrated_helpers._IntegratedTestBase):
|
||||
def test_create_and_update_volume(self):
|
||||
# Create vol1
|
||||
created_volume = self.api.post_volume({'volume': {
|
||||
'size': 1, 'display_name': 'vol1'}})
|
||||
self.assertEqual(created_volume['display_name'], 'vol1')
|
||||
'size': 1, 'name': 'vol1'}})
|
||||
self.assertEqual(created_volume['name'], 'vol1')
|
||||
created_volume_id = created_volume['id']
|
||||
|
||||
# update volume
|
||||
body = {'volume': {'display_name': 'vol-one'}}
|
||||
body = {'volume': {'name': 'vol-one'}}
|
||||
updated_volume = self.api.put_volume(created_volume_id, body)
|
||||
self.assertEqual(updated_volume['display_name'], 'vol-one')
|
||||
self.assertEqual(updated_volume['name'], 'vol-one')
|
||||
|
||||
# check for update
|
||||
found_volume = self.api.get_volume(created_volume_id)
|
||||
self.assertEqual(created_volume_id, found_volume['id'])
|
||||
self.assertEqual(found_volume['display_name'], 'vol-one')
|
||||
self.assertEqual(found_volume['name'], 'vol-one')
|
||||
|
@ -38,7 +38,6 @@ class XmlTests(integrated_helpers._IntegratedTestBase):
|
||||
# self.assertEqual(root.nsmap.get(None), xmlutil.XMLNS_COMMON_V10)
|
||||
|
||||
def test_namespace_volumes(self):
|
||||
"""/servers should have v1.1 namespace (has changed in 1.1)."""
|
||||
headers = {}
|
||||
headers['Accept'] = 'application/xml'
|
||||
|
||||
@ -47,4 +46,4 @@ class XmlTests(integrated_helpers._IntegratedTestBase):
|
||||
data = response.raw
|
||||
LOG.warn("data: %s" % data)
|
||||
root = etree.parse(data).getroot()
|
||||
self.assertEqual(root.nsmap.get(None), common.XML_NS_V1)
|
||||
self.assertEqual(root.nsmap.get(None), common.XML_NS_V2)
|
||||
|
@ -529,7 +529,7 @@
|
||||
# The topic that volume backup nodes listen on (string value)
|
||||
#backup_topic=cinder-backup
|
||||
|
||||
# Deploy v1 of the Cinder API. (boolean value)
|
||||
# DEPRECATED: Deploy v1 of the Cinder API. (boolean value)
|
||||
#enable_v1_api=true
|
||||
|
||||
# Deploy v2 of the Cinder API. (boolean value)
|
||||
|
Loading…
Reference in New Issue
Block a user