diff --git a/heat/api/middleware/fault.py b/heat/api/middleware/fault.py index 403a1872ac..c18afa8b1f 100644 --- a/heat/api/middleware/fault.py +++ b/heat/api/middleware/fault.py @@ -91,6 +91,7 @@ class FaultWrapper(wsgi.Middleware): 'UnsupportedObjectError': webob.exc.HTTPBadRequest, 'ResourceTypeUnavailable': webob.exc.HTTPBadRequest, 'InvalidBreakPointHook': webob.exc.HTTPBadRequest, + 'ImmutableParameterModified': webob.exc.HTTPBadRequest } def _map_exception_to_error(self, class_exception): diff --git a/heat/tests/api/openstack_v1/test_stacks.py b/heat/tests/api/openstack_v1/test_stacks.py index b063f3d31b..a360a468fd 100644 --- a/heat/tests/api/openstack_v1/test_stacks.py +++ b/heat/tests/api/openstack_v1/test_stacks.py @@ -1284,6 +1284,53 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase): self.assertEqual({'resource_changes': resource_changes}, result) self.m.VerifyAll() + @mock.patch.object(rpc_client.EngineClient, 'call') + def test_update_immutable_parameter(self, mock_call, mock_enforce): + self._mock_enforce_setup(mock_enforce, 'update', True) + identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '6') + template = {u'Foo': u'bar'} + parameters = {u'param1': u'bar'} + body = {'template': template, + 'parameters': parameters, + 'files': {}, + 'timeout_mins': 30} + + req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % + identity, json.dumps(body)) + + error = heat_exc.ImmutableParameterModified(keys='param1') + self.m.StubOutWithMock(rpc_client.EngineClient, 'call') + rpc_client.EngineClient.call( + req.context, + ('update_stack', + {'stack_identity': dict(identity), + 'template': template, + 'params': {u'parameters': parameters, + u'encrypted_param_names': [], + u'parameter_defaults': {}, + u'event_sinks': [], + u'resource_registry': {}}, + 'files': {}, + 'environment_files': None, + 'args': {'timeout_mins': 30}}), + version='1.23' + ).AndRaise(tools.to_remote_error(error)) + self.m.ReplayAll() + + resp = tools.request_with_middleware(fault.FaultWrapper, + self.controller.update, + req, tenant_id=identity.tenant, + stack_name=identity.stack_name, + stack_id=identity.stack_id, + body=body) + + self.assertEqual(400, resp.json['code']) + self.assertEqual('ImmutableParameterModified', + resp.json['error']['type']) + self.assertIn("The following parameters are immutable", + six.text_type(resp.json['error']['message'])) + self.m.VerifyAll() + def test_lookup(self, mock_enforce): self._mock_enforce_setup(mock_enforce, 'lookup', True) identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '1') diff --git a/heat_integrationtests/functional/test_immutable_parameters.py b/heat_integrationtests/functional/test_immutable_parameters.py index b8c498d451..d223b1495b 100644 --- a/heat_integrationtests/functional/test_immutable_parameters.py +++ b/heat_integrationtests/functional/test_immutable_parameters.py @@ -126,7 +126,7 @@ outputs: stack_identifier, template=immutable_true, parameters=update_parameters) - except heat_exceptions.HTTPInternalServerError as exc: + except heat_exceptions.HTTPBadRequest as exc: exp = ('The following parameters are immutable and may not be ' 'updated: param1') self.assertIn(exp, str(exc))