From e55b40c2359ef6c38b1ae5af48fffb68d0710cec Mon Sep 17 00:00:00 2001 From: Feng Shengqin Date: Tue, 16 May 2017 13:53:36 +0800 Subject: [PATCH] Zun execute without command returned 500 If we run "zun exec ..." without a command, Zun server should return 400 (Bad request) instead of 500 (Server fault) in this case. Change-Id: I8e5a91668556b35fc3902d53737a122248601c50 Closes-Bug: #1690907 --- zun/api/controllers/v1/containers.py | 2 ++ zun/api/controllers/v1/schemas/containers.py | 10 ++++++++++ zun/common/validation/parameter_types.py | 5 +++++ .../unit/api/controllers/v1/test_containers.py | 17 +++++++++++++++++ 4 files changed, 34 insertions(+) diff --git a/zun/api/controllers/v1/containers.py b/zun/api/controllers/v1/containers.py index cf6c53caa..bc9cda69c 100644 --- a/zun/api/controllers/v1/containers.py +++ b/zun/api/controllers/v1/containers.py @@ -413,6 +413,8 @@ class ContainersController(base.Controller): @pecan.expose('json') @exception.wrap_pecan_controller_exception + @validation.validate_query_param(pecan.request, + schema.query_param_execute_command) def execute(self, container_id, run=True, interactive=False, **kw): container = _get_container(container_id) check_policy_on_container(container.as_dict(), "container:execute") diff --git a/zun/api/controllers/v1/schemas/containers.py b/zun/api/controllers/v1/schemas/containers.py index 24dcc0124..ca1860a2b 100644 --- a/zun/api/controllers/v1/schemas/containers.py +++ b/zun/api/controllers/v1/schemas/containers.py @@ -126,3 +126,13 @@ query_param_signal = { }, 'additionalProperties': False } + +query_param_execute_command = { + 'type': 'object', + 'properties': { + 'run': parameter_types.boolean, + 'interactive': parameter_types.boolean, + 'command': parameter_types.exec_command, + }, + 'additionalProperties': False +} diff --git a/zun/common/validation/parameter_types.py b/zun/common/validation/parameter_types.py index 216461f43..bbb255ef3 100644 --- a/zun/common/validation/parameter_types.py +++ b/zun/common/validation/parameter_types.py @@ -184,3 +184,8 @@ signal = { 'type': ['string', 'null'], 'enum': SIGNALS } + +exec_command = { + 'type': ['string'], + 'minLength': 1, +} diff --git a/zun/tests/unit/api/controllers/v1/test_containers.py b/zun/tests/unit/api/controllers/v1/test_containers.py index 10f1a1608..9f4572c0f 100644 --- a/zun/tests/unit/api/controllers/v1/test_containers.py +++ b/zun/tests/unit/api/controllers/v1/test_containers.py @@ -862,6 +862,23 @@ class TestContainerController(api_base.FunctionalTest): self.app.post('/v1/containers/%s/%s/' % (test_object.uuid, 'execute'), cmd) + @patch('zun.common.utils.validate_container_state') + @patch('zun.compute.api.API.container_exec') + @patch('zun.objects.Container.get_by_uuid') + def test_execute_without_command_by_uuid(self, mock_get_by_uuid, + mock_container_exec, + mock_validate): + test_container = utils.get_test_container() + test_container_obj = objects.Container(self.context, **test_container) + mock_get_by_uuid.return_value = test_container_obj + + container_uuid = test_container.get('uuid') + cmd = {'command': ''} + self.assertRaises(AppError, self.app.post, + '/v1/containers/%s/execute' % + container_uuid, cmd) + self.assertFalse(mock_container_exec.called) + @patch('zun.common.utils.validate_container_state') @patch('zun.compute.api.API.container_delete') @patch('zun.objects.Container.get_by_uuid')