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']
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,
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):
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):
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__)
# '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 = {
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(),
},
"v1.0": {
"id": "v1.0",
- "status": "CURRENT",
- "updated": "2012-01-04T11:33:21Z",
+ "status": "SUPPORTED",
+ "updated": "2014-06-28T12:20:21Z",
"links": [
{
"rel": "describedby",
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
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'([^:{]*{[^}]*}[^:]*|[^:]+)')
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.")),
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)
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):
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')
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):
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)
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)
""") % 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())
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'
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'
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):
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):
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')
# 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'
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)
# 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)