diff --git a/nova/api/openstack/compute/contrib/admin_actions.py b/nova/api/openstack/compute/contrib/admin_actions.py index 632e4f226d..00de15122f 100644 --- a/nova/api/openstack/compute/contrib/admin_actions.py +++ b/nova/api/openstack/compute/contrib/admin_actions.py @@ -26,6 +26,7 @@ from nova.compute import vm_states from nova import exception from nova.openstack.common.gettextutils import _ from nova.openstack.common import log as logging +from nova.openstack.common import strutils LOG = logging.getLogger(__name__) @@ -312,6 +313,14 @@ class AdminActionsController(wsgi.Controller): "be specified for live migration.") raise exc.HTTPBadRequest(explanation=msg) + try: + block_migration = strutils.bool_from_string(block_migration, + strict=True) + disk_over_commit = strutils.bool_from_string(disk_over_commit, + strict=True) + except ValueError as err: + raise exc.HTTPBadRequest(explanation=str(err)) + try: instance = self.compute_api.get(context, id, want_objects=True) self.compute_api.live_migrate(context, instance, block_migration, diff --git a/nova/api/openstack/compute/plugins/v3/admin_actions.py b/nova/api/openstack/compute/plugins/v3/admin_actions.py index 63777f95bc..14a1f2cb8b 100644 --- a/nova/api/openstack/compute/plugins/v3/admin_actions.py +++ b/nova/api/openstack/compute/plugins/v3/admin_actions.py @@ -25,6 +25,7 @@ from nova.compute import vm_states from nova import exception from nova.openstack.common.gettextutils import _ from nova.openstack.common import log as logging +from nova.openstack.common import strutils LOG = logging.getLogger(__name__) ALIAS = "os-admin-actions" @@ -290,6 +291,14 @@ class AdminActionsController(wsgi.Controller): "be specified for live migration.") raise exc.HTTPBadRequest(explanation=msg) + try: + block_migration = strutils.bool_from_string(block_migration, + strict=True) + disk_over_commit = strutils.bool_from_string(disk_over_commit, + strict=True) + except ValueError as err: + raise exc.HTTPBadRequest(explanation=str(err)) + try: instance = self.compute_api.get(context, id, want_objects=True) self.compute_api.live_migrate(context, instance, block_migration, diff --git a/nova/tests/api/openstack/compute/contrib/test_admin_actions.py b/nova/tests/api/openstack/compute/contrib/test_admin_actions.py index 84c3006e91..495f6e7353 100644 --- a/nova/tests/api/openstack/compute/contrib/test_admin_actions.py +++ b/nova/tests/api/openstack/compute/contrib/test_admin_actions.py @@ -224,7 +224,7 @@ class AdminActionsTest(CommonMixin, test.NoDBTestCase): {'migrate': None}) self.assertEqual(expected_result, res.status_int) - def test_migrate_live_enabled(self): + def _test_migrate_live_succeeded(self, param): self.mox.StubOutWithMock(self.compute_api, 'live_migrate') instance = self._stub_instance_get() self.compute_api.live_migrate(self.context, instance, False, @@ -233,12 +233,21 @@ class AdminActionsTest(CommonMixin, test.NoDBTestCase): self.mox.ReplayAll() res = self._make_request('/servers/%s/action' % instance['uuid'], - {'os-migrateLive': - {'host': 'hostname', - 'block_migration': False, - 'disk_over_commit': False}}) + {'os-migrateLive': param}) self.assertEqual(202, res.status_int) + def test_migrate_live_enabled(self): + param = {'host': 'hostname', + 'block_migration': False, + 'disk_over_commit': False} + self._test_migrate_live_succeeded(param) + + def test_migrate_live_enabled_with_string_param(self): + param = {'host': 'hostname', + 'block_migration': "False", + 'disk_over_commit': "False"} + self._test_migrate_live_succeeded(param) + def test_migrate_live_missing_dict_param(self): body = {'os-migrateLive': {'dummy': 'hostname', 'block_migration': False, @@ -246,6 +255,20 @@ class AdminActionsTest(CommonMixin, test.NoDBTestCase): res = self._make_request('/servers/FAKE/action', body) self.assertEqual(400, res.status_int) + def test_migrate_live_with_invalid_block_migration(self): + body = {'os-migrateLive': {'host': 'hostname', + 'block_migration': "foo", + 'disk_over_commit': False}} + res = self._make_request('/servers/FAKE/action', body) + self.assertEqual(400, res.status_int) + + def test_migrate_live_with_invalid_disk_over_commit(self): + body = {'os-migrateLive': {'host': 'hostname', + 'block_migration': False, + 'disk_over_commit': "foo"}} + res = self._make_request('/servers/FAKE/action', body) + self.assertEqual(400, res.status_int) + def _test_migrate_live_failed_with_exception(self, fake_exc, uuid=None): self.mox.StubOutWithMock(self.compute_api, 'live_migrate') diff --git a/nova/tests/api/openstack/compute/plugins/v3/test_admin_actions.py b/nova/tests/api/openstack/compute/plugins/v3/test_admin_actions.py index d604aace82..bf9f29e7f1 100644 --- a/nova/tests/api/openstack/compute/plugins/v3/test_admin_actions.py +++ b/nova/tests/api/openstack/compute/plugins/v3/test_admin_actions.py @@ -234,7 +234,7 @@ class AdminActionsTest(CommonMixin, test.NoDBTestCase): allowed=0, resource='') self._test_migrate_exception(exc_info, 413) - def test_migrate_live_enabled(self): + def _test_migrate_live_succeeded(self, param): self.mox.StubOutWithMock(self.compute_api, 'live_migrate') instance = self._stub_instance_get() self.compute_api.live_migrate(self.context, instance, False, @@ -243,12 +243,21 @@ class AdminActionsTest(CommonMixin, test.NoDBTestCase): self.mox.ReplayAll() res = self._make_request('/servers/%s/action' % instance.uuid, - {'migrate_live': - {'host': 'hostname', - 'block_migration': False, - 'disk_over_commit': False}}) + {'migrate_live': param}) self.assertEqual(202, res.status_int) + def test_migrate_live_enabled(self): + param = {'host': 'hostname', + 'block_migration': False, + 'disk_over_commit': False} + self._test_migrate_live_succeeded(param) + + def test_migrate_live_enabled_with_string_param(self): + param = {'host': 'hostname', + 'block_migration': "False", + 'disk_over_commit': "False"} + self._test_migrate_live_succeeded(param) + def test_migrate_live_missing_dict_param(self): res = self._make_request('/servers/FAKE/action', {'migrate_live': {'dummy': 'hostname', @@ -256,6 +265,20 @@ class AdminActionsTest(CommonMixin, test.NoDBTestCase): 'disk_over_commit': False}}) self.assertEqual(400, res.status_int) + def test_migrate_live_with_invalid_block_migration(self): + res = self._make_request('/servers/FAKE/action', + {'migrate_live': {'host': 'hostname', + 'block_migration': "foo", + 'disk_over_commit': False}}) + self.assertEqual(400, res.status_int) + + def test_migrate_live_with_invalid_disk_over_commit(self): + res = self._make_request('/servers/FAKE/action', + {'migrate_live': {'host': 'hostname', + 'block_migration': False, + 'disk_over_commit': "foo"}}) + self.assertEqual(400, res.status_int) + def _test_migrate_live_failed_with_exception(self, fake_exc, uuid=None): self.mox.StubOutWithMock(self.compute_api, 'live_migrate')