check the validity of metadata when update volume

The volume update API also allow users to update the volume'metadata.
But cinder doesn't check the length limit. It'will raise 500 error
if the metadata is longer than 255. We should check it and raise
413 at the api layer to keep the same with the volume metadata
update API.

Change-Id: I3928ffff9aab6a8071d0641fa6b40b10b1f6bc10
Closes-bug: #1598007
This commit is contained in:
wangxiyuan 2016-07-01 16:32:38 +08:00
parent 6f2112caa8
commit f6aec5bb96
3 changed files with 49 additions and 0 deletions

View File

@ -341,6 +341,10 @@ class VolumeController(wsgi.Controller):
self.volume_api.update(context, volume, update_dict)
except exception.VolumeNotFound as error:
raise exc.HTTPNotFound(explanation=error.msg)
except exception.InvalidVolumeMetadata as error:
raise webob.exc.HTTPBadRequest(explanation=error.msg)
except exception.InvalidVolumeMetadataSize as error:
raise webob.exc.HTTPRequestEntityTooLarge(explanation=error.msg)
volume.update(update_dict)

View File

@ -23,6 +23,7 @@ import six
from six.moves import range
from six.moves import urllib
import webob
from webob import exc
from cinder.api import common
from cinder.api import extensions
@ -659,6 +660,48 @@ class VolumeApiTest(test.TestCase):
self.assertEqual(2, len(self.notifier.notifications))
self.assertTrue(mock_validate.called)
@mock.patch(
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
def test_volume_update_metadata_value_too_long(self, mock_validate):
self.stubs.Set(volume_api.API, 'get', stubs.stub_volume_api_get)
updates = {
"metadata": {"key1": ("a" * 260)}
}
body = {"volume": updates}
req = fakes.HTTPRequest.blank('/v2/volumes/%s' % fake.VOLUME_ID)
self.assertEqual(0, len(self.notifier.notifications))
self.assertRaises(exc.HTTPRequestEntityTooLarge,
self.controller.update, req, fake.VOLUME_ID, body)
@mock.patch(
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
def test_volume_update_metadata_key_too_long(self, mock_validate):
self.stubs.Set(volume_api.API, 'get', stubs.stub_volume_api_get)
updates = {
"metadata": {("a" * 260): "value1"}
}
body = {"volume": updates}
req = fakes.HTTPRequest.blank('/v2/volumes/%s' % fake.VOLUME_ID)
self.assertEqual(0, len(self.notifier.notifications))
self.assertRaises(exc.HTTPRequestEntityTooLarge,
self.controller.update, req, fake.VOLUME_ID, body)
@mock.patch(
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
def test_volume_update_metadata_empty_key(self, mock_validate):
self.stubs.Set(volume_api.API, 'get', stubs.stub_volume_api_get)
updates = {
"metadata": {"": "value1"}
}
body = {"volume": updates}
req = fakes.HTTPRequest.blank('/v2/volumes/%s' % fake.VOLUME_ID)
self.assertEqual(0, len(self.notifier.notifications))
self.assertRaises(exc.HTTPBadRequest,
self.controller.update, req, fake.VOLUME_ID, body)
@mock.patch(
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
def test_volume_update_with_admin_metadata(self, mock_validate):

View File

@ -449,6 +449,8 @@ class API(base.Base):
msg = _("The volume cannot be updated during maintenance.")
raise exception.InvalidVolume(reason=msg)
utils.check_metadata_properties(fields.get('metadata', None))
volume.update(fields)
volume.save()
LOG.info(_LI("Volume updated successfully."), resource=volume)