From b927d03cf7a6215ca3cfa0e368e7b1bc9b064758 Mon Sep 17 00:00:00 2001 From: wangqun Date: Thu, 10 Mar 2016 08:31:42 +0000 Subject: [PATCH] Fix baymodel with invalid parameter can updated. Now, when we update baymodel with the invalid flavor_id or master_flavor_id parameters, the baymodel can be updated successfully. We need to validate the flavor_id, master_flavor, keypair and so on before patching baymodel. Closes-Bug: #1555490 Change-Id: I4ae3cd7c0be1161dacb6f0a80c5ee1b53d06d03d --- magnum/api/controllers/v1/baymodel.py | 2 + magnum/tests/functional/api/v1/test_bay.py | 11 +--- .../unit/api/controllers/v1/test_baymodel.py | 59 +++++++++++++++++++ 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/magnum/api/controllers/v1/baymodel.py b/magnum/api/controllers/v1/baymodel.py index 90c5c9ae1a..8c05c449ba 100644 --- a/magnum/api/controllers/v1/baymodel.py +++ b/magnum/api/controllers/v1/baymodel.py @@ -342,6 +342,8 @@ class BayModelsController(rest.RestController): except api_utils.JSONPATCH_EXCEPTIONS as e: raise exception.PatchError(patch=patch, reason=e) + new_baymodel_dict = new_baymodel.as_dict() + attr_validator.validate_os_resources(context, new_baymodel_dict) # check permissions when updating baymodel public flag if baymodel.public != new_baymodel.public: if not policy.enforce(context, "baymodel:publish", None, diff --git a/magnum/tests/functional/api/v1/test_bay.py b/magnum/tests/functional/api/v1/test_bay.py index 60798065b7..6c043b5ca8 100644 --- a/magnum/tests/functional/api/v1/test_bay.py +++ b/magnum/tests/functional/api/v1/test_bay.py @@ -177,17 +177,8 @@ class BayTest(base.BaseMagnumTest): self.assertEqual(resp.status, 201) self.assertIsNotNone(baymodel.uuid) - patch_model = datagen.baymodel_flavor_patch_data() - resp, new_model = self.baymodel_client.patch_baymodel( - baymodel.uuid, patch_model) - self.assertEqual(200, resp.status) - - resp, model = self.baymodel_client.get_baymodel(new_model.uuid) - self.assertEqual(200, resp.status) - self.assertEqual(baymodel.uuid, new_model.uuid) - self.assertEqual(model.flavor_id, new_model.flavor_id) - gen_model = datagen.valid_bay_data(baymodel_id=baymodel.uuid) + gen_model.flavor_id = 'aaa' self.assertRaises( exceptions.BadRequest, self.bay_client.post_bay, gen_model) diff --git a/magnum/tests/unit/api/controllers/v1/test_baymodel.py b/magnum/tests/unit/api/controllers/v1/test_baymodel.py index 56b4aff1a2..b22f1afa5c 100644 --- a/magnum/tests/unit/api/controllers/v1/test_baymodel.py +++ b/magnum/tests/unit/api/controllers/v1/test_baymodel.py @@ -194,12 +194,19 @@ class TestPatch(api_base.FunctionalTest): def setUp(self): super(TestPatch, self).setUp() + p = mock.patch.object(attr_validator, 'validate_os_resources') + self.mock_valid_os_res = p.start() + self.addCleanup(p.stop) self.baymodel = obj_utils.create_test_baymodel( self.context, name='bay_model_example_A', image_id='nerdherd', apiserver_port=8080, fixed_network='private', + flavor_id='m1.magnum', + master_flavor_id='m1.magnum', + external_network_id='public', + keypair_id='test', volume_driver='rexray', public=False, docker_volume_size=20, @@ -293,6 +300,58 @@ class TestPatch(api_base.FunctionalTest): self.assertEqual(self.baymodel.labels, response['labels']) + def test_replace_baymodel_with_no_exist_flavor_id(self): + self.mock_valid_os_res.side_effect = exception.FlavorNotFound("aaa") + response = self.patch_json('/baymodels/%s' % self.baymodel.uuid, + [{'path': '/flavor_id', 'value': 'aaa', + 'op': 'replace'}], + expect_errors=True) + self.assertEqual('application/json', response.content_type) + self.assertEqual(400, response.status_code) + self.assertTrue(response.json['errors']) + + def test_replace_baymodel_with_no_exist_keypair_id(self): + self.mock_valid_os_res.side_effect = exception.KeyPairNotFound("aaa") + response = self.patch_json('/baymodels/%s' % self.baymodel.uuid, + [{'path': '/keypair_id', 'value': 'aaa', + 'op': 'replace'}], + expect_errors=True) + self.assertEqual('application/json', response.content_type) + self.assertEqual(404, response.status_code) + self.assertTrue(response.json['errors']) + + def test_replace_baymodel_with_no_exist_external_network_id(self): + self.mock_valid_os_res.side_effect = exception.NetworkNotFound("aaa") + response = self.patch_json('/baymodels/%s' % self.baymodel.uuid, + [{'path': '/external_network_id', + 'value': 'aaa', + 'op': 'replace'}], + expect_errors=True) + self.assertEqual('application/json', response.content_type) + self.assertEqual(400, response.status_code) + self.assertTrue(response.json['errors']) + + def test_replace_baymodel_with_no_exist_image_id(self): + self.mock_valid_os_res.side_effect = exception.ImageNotFound("aaa") + response = self.patch_json('/baymodels/%s' % self.baymodel.uuid, + [{'path': '/image_id', 'value': 'aaa', + 'op': 'replace'}], + expect_errors=True) + self.assertEqual('application/json', response.content_type) + self.assertEqual(400, response.status_code) + self.assertTrue(response.json['errors']) + + def test_create_baymodel_with_no_os_distro_image(self): + image_exce = exception.OSDistroFieldNotFound('img') + self.mock_valid_os_res.side_effect = image_exce + response = self.patch_json('/baymodels/%s' % self.baymodel.uuid, + [{'path': '/image_id', 'value': 'img', + 'op': 'replace'}], + expect_errors=True) + self.assertEqual('application/json', response.content_type) + self.assertEqual(400, response.status_code) + self.assertTrue(response.json['errors']) + def test_remove_singular(self): baymodel = obj_utils.create_test_baymodel(self.context, uuid=utils.generate_uuid())