From 36c420157674e8ed34d407f19062b06a657e6490 Mon Sep 17 00:00:00 2001 From: Avishay Traeger Date: Sun, 29 Sep 2013 13:17:51 +0300 Subject: [PATCH] Validate force_host_copy API param for migration For the force_host_copy parameter of volume migration, make sure that we get a boolean or string that we can convert to boolean. Change-Id: I7a77ca1780a4ef80bc351aa89df0efaaea0d7cf4 Closes-Bug: #1232698 --- cinder/api/contrib/admin_actions.py | 9 ++++++++ .../tests/api/contrib/test_admin_actions.py | 23 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/cinder/api/contrib/admin_actions.py b/cinder/api/contrib/admin_actions.py index 71cd53da1..f00bcdf90 100644 --- a/cinder/api/contrib/admin_actions.py +++ b/cinder/api/contrib/admin_actions.py @@ -20,6 +20,7 @@ from cinder.api.openstack import wsgi from cinder import db from cinder import exception from cinder.openstack.common import log as logging +from cinder.openstack.common import strutils from cinder import volume @@ -152,6 +153,14 @@ class VolumeAdminController(AdminController): params = body['os-migrate_volume'] host = params['host'] force_host_copy = params.get('force_host_copy', False) + if isinstance(force_host_copy, basestring): + try: + force_host_copy = strutils.bool_from_string(force_host_copy, + strict=True) + except ValueError: + raise exc.HTTPBadRequest("Bad value for 'force_host_copy'") + elif not isinstance(force_host_copy, bool): + raise exc.HTTPBadRequest("'force_host_copy' not string or bool") self.volume_api.migrate_volume(context, volume, host, force_host_copy) return webob.Response(status_int=202) diff --git a/cinder/tests/api/contrib/test_admin_actions.py b/cinder/tests/api/contrib/test_admin_actions.py index 49dc32abe..5a0f419db 100644 --- a/cinder/tests/api/contrib/test_admin_actions.py +++ b/cinder/tests/api/contrib/test_admin_actions.py @@ -552,13 +552,16 @@ class AdminActionsTest(test.TestCase): 'attach_status': ''}) return volume - def _migrate_volume_exec(self, ctx, volume, host, expected_status): + def _migrate_volume_exec(self, ctx, volume, host, expected_status, + force_host_copy=False): admin_ctx = context.get_admin_context() # build request to migrate to host req = webob.Request.blank('/v2/fake/volumes/%s/action' % volume['id']) req.method = 'POST' req.headers['content-type'] = 'application/json' - req.body = jsonutils.dumps({'os-migrate_volume': {'host': host}}) + body = {'os-migrate_volume': {'host': host, + 'force_host_copy': force_host_copy}} + req.body = jsonutils.dumps(body) req.environ['cinder.context'] = ctx resp = req.get_response(app()) # verify status @@ -612,6 +615,22 @@ class AdminActionsTest(test.TestCase): db.snapshot_create(ctx, {'volume_id': volume['id']}) self._migrate_volume_exec(ctx, volume, host, expected_status) + def test_migrate_volume_bad_force_host_copy1(self): + expected_status = 400 + host = 'test2' + ctx = context.RequestContext('admin', 'fake', True) + volume = self._migrate_volume_prep() + self._migrate_volume_exec(ctx, volume, host, expected_status, + force_host_copy='foo') + + def test_migrate_volume_bad_force_host_copy2(self): + expected_status = 400 + host = 'test2' + ctx = context.RequestContext('admin', 'fake', True) + volume = self._migrate_volume_prep() + self._migrate_volume_exec(ctx, volume, host, expected_status, + force_host_copy=1) + def _migrate_volume_comp_exec(self, ctx, volume, new_volume, error, expected_status, expected_id): admin_ctx = context.get_admin_context() -- 2.45.2