From: Liang Chen Date: Wed, 28 Aug 2013 14:55:42 +0000 (+0800) Subject: Fix CFN API error responses X-Git-Tag: 2014.1~101^2 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=03638aad74d416f31439aa1150dff29e1c7855be;p=openstack-build%2Fheat-build.git Fix CFN API error responses A remote exception (included in conf.allowed_rpc_exception_modules) is now restored to a subclass of its original type (with the exception of non heap types which will always be restored to its original type). Catching rpc_common.RemoteError is not enough anymore. Fixes bug #1214831 Change-Id: Iae3ce0c9d0d3f6565fab25ec899f83f19d46e81b --- diff --git a/heat/api/aws/exception.py b/heat/api/aws/exception.py index a0207b67..1a6fbe31 100644 --- a/heat/api/aws/exception.py +++ b/heat/api/aws/exception.py @@ -19,6 +19,7 @@ import webob.exc from heat.common import wsgi +import heat.openstack.common.rpc.common as rpc_common class HeatAPIException(webob.exc.HTTPError): @@ -270,12 +271,17 @@ def map_remote_error(ex): denied_errors = ('Forbidden', 'NotAuthorized') already_exists_errors = ('StackExists') - if ex.exc_type in inval_param_errors: - return HeatInvalidParameterValueError(detail=ex.value) - elif ex.exc_type in denied_errors: - return HeatAccessDeniedError(detail=ex.value) - elif ex.exc_type in already_exists_errors: - return AlreadyExistsError(detail=ex.value) + ex_type = ex.__class__.__name__ + + if ex_type.endswith(rpc_common._REMOTE_POSTFIX): + ex_type = ex_type[:-len(rpc_common._REMOTE_POSTFIX)] + + if ex_type in inval_param_errors: + return HeatInvalidParameterValueError(detail=str(ex.message)) + elif ex_type in denied_errors: + return HeatAccessDeniedError(detail=str(ex.message)) + elif ex_type in already_exists_errors: + return AlreadyExistsError(detail=str(ex.message)) else: # Map everything else to internal server error for now - return HeatInternalFailureError(detail=ex.value) + return HeatInternalFailureError(detail=str(ex.message)) diff --git a/heat/api/cfn/v1/signal.py b/heat/api/cfn/v1/signal.py index 47ad866b..235963b6 100644 --- a/heat/api/cfn/v1/signal.py +++ b/heat/api/cfn/v1/signal.py @@ -17,7 +17,6 @@ from heat.common import wsgi from heat.rpc import client as rpc_client from heat.common import identifier from heat.api.aws import exception -import heat.openstack.common.rpc.common as rpc_common class SignalController(object): @@ -34,7 +33,7 @@ class SignalController(object): stack_identity=dict(identity.stack()), resource_name=identity.resource_name, metadata=body) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) return {'resource': identity.resource_name, 'metadata': md} @@ -48,7 +47,7 @@ class SignalController(object): stack_identity=dict(identity.stack()), resource_name=identity.resource_name, details=body) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) diff --git a/heat/api/cfn/v1/stacks.py b/heat/api/cfn/v1/stacks.py index 4d89ecaf..f6e867c4 100644 --- a/heat/api/cfn/v1/stacks.py +++ b/heat/api/cfn/v1/stacks.py @@ -31,8 +31,6 @@ from heat.common import identifier from heat.common import urlfetch from heat.common import policy -import heat.openstack.common.rpc.common as rpc_common - from heat.openstack.common import log as logging from heat.openstack.common.gettextutils import _ @@ -146,7 +144,7 @@ class StackController(object): con = req.context try: stack_list = self.engine_rpcapi.list_stacks(con) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) res = {'StackSummaries': [format_stack_summary(s) for s in stack_list]} @@ -237,7 +235,7 @@ class StackController(object): stack_list = self.engine_rpcapi.show_stack(con, identity) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) res = {'Stacks': [format_stack(s) for s in stack_list]} @@ -353,7 +351,7 @@ class StackController(object): args['stack_identity'] = self._get_identity(con, stack_name) result = engine_action[action](con, **args) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) try: @@ -376,7 +374,7 @@ class StackController(object): try: identity = self._get_identity(con, req.params['StackName']) templ = self.engine_rpcapi.get_template(con, identity) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) if templ is None: @@ -445,7 +443,7 @@ class StackController(object): res['Parameters'] = [format_validate_parameter(k, v) for k, v in res['Parameters'].items()] return api_utils.format_response('ValidateTemplate', res) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) def delete(self, req): @@ -460,7 +458,7 @@ class StackController(object): identity = self._get_identity(con, req.params['StackName']) res = self.engine_rpcapi.delete_stack(con, identity, cast=False) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) if res is None: @@ -505,7 +503,7 @@ class StackController(object): try: identity = stack_name and self._get_identity(con, stack_name) events = self.engine_rpcapi.list_events(con, identity) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) result = [format_stack_event(e) for e in events] @@ -557,7 +555,7 @@ class StackController(object): stack_identity=identity, resource_name=req.params.get('LogicalResourceId')) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) result = format_resource_detail(resource_details) @@ -623,7 +621,7 @@ class StackController(object): stack_identity=identity, resource_name=req.params.get('LogicalResourceId')) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) result = [format_stack_resource(r) for r in resources] @@ -663,7 +661,7 @@ class StackController(object): resources = self.engine_rpcapi.list_stack_resources( con, stack_identity=identity) - except rpc_common.RemoteError as ex: + except Exception as ex: return exception.map_remote_error(ex) summaries = [format_resource_summary(r) for r in resources] diff --git a/heat/tests/test_api_cfn_v1.py b/heat/tests/test_api_cfn_v1.py index 83a7b555..bc1e2091 100644 --- a/heat/tests/test_api_cfn_v1.py +++ b/heat/tests/test_api_cfn_v1.py @@ -17,10 +17,10 @@ import os from oslo.config import cfg +from heat.common import exception as heat_exception from heat.common import identifier from heat.common import policy from heat.openstack.common import rpc -import heat.openstack.common.rpc.common as rpc_common from heat.common.wsgi import Request from heat.rpc import api as rpc_api from heat.api.aws import exception @@ -152,7 +152,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'list_stacks', 'args': {}, 'version': self.api_version}, - None).AndRaise(rpc_common.RemoteError("AttributeError")) + None).AndRaise(AttributeError()) self.m.ReplayAll() @@ -174,7 +174,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'list_stacks', 'args': {}, 'version': self.api_version}, - None).AndRaise(rpc_common.RemoteError("Exception")) + None).AndRaise(Exception()) self.m.ReplayAll() @@ -372,7 +372,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'show_stack', 'args': {'stack_identity': identity}, 'version': self.api_version}, - None).AndRaise(rpc_common.RemoteError("InvalidTenant")) + None).AndRaise(heat_exception.InvalidTenant()) self.m.ReplayAll() @@ -400,7 +400,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'show_stack', 'args': {'stack_identity': identity}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("AttributeError")) + ).AndRaise(AttributeError()) self.m.ReplayAll() @@ -422,7 +422,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'identify_stack', 'args': {'stack_name': stack_name}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("StackNotFound")) + ).AndRaise(heat_exception.StackNotFound()) self.m.ReplayAll() @@ -743,7 +743,7 @@ class CfnStackControllerTest(HeatTestCase): 'files': {}, 'args': engine_args}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("AttributeError")) + ).AndRaise(AttributeError()) rpc.call(dummy_req.context, self.topic, {'namespace': None, 'method': 'create_stack', @@ -753,7 +753,7 @@ class CfnStackControllerTest(HeatTestCase): 'files': {}, 'args': engine_args}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("UnknownUserParameter")) + ).AndRaise(heat_exception.UnknownUserParameter()) rpc.call(dummy_req.context, self.topic, {'namespace': None, 'method': 'create_stack', @@ -763,7 +763,7 @@ class CfnStackControllerTest(HeatTestCase): 'files': {}, 'args': engine_args}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("UserParameterMissing")) + ).AndRaise(heat_exception.UserParameterMissing()) self.m.ReplayAll() @@ -811,7 +811,7 @@ class CfnStackControllerTest(HeatTestCase): 'files': {}, 'args': engine_args}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("StackExists")) + ).AndRaise(heat_exception.StackExists()) self.m.ReplayAll() @@ -847,9 +847,8 @@ class CfnStackControllerTest(HeatTestCase): 'files': {}, 'args': engine_args}, 'version': self.api_version}, None).AndRaise( - rpc_common.RemoteError( - 'StackValidationFailed', - 'Something went wrong')) + heat_exception.StackValidationFailed( + message='Something went wrong')) self.m.ReplayAll() @@ -926,7 +925,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'identify_stack', 'args': {'stack_name': stack_name}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("StackNotFound")) + ).AndRaise(heat_exception.StackNotFound()) self.m.ReplayAll() @@ -993,7 +992,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'get_template', 'args': {'stack_identity': identity}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("AttributeError")) + ).AndRaise(AttributeError()) self.m.ReplayAll() @@ -1016,7 +1015,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'identify_stack', 'args': {'stack_name': stack_name}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("StackNotFound")) + ).AndRaise(heat_exception.StackNotFound()) self.m.ReplayAll() @@ -1161,7 +1160,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'delete_stack', 'args': {'stack_identity': identity}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("AttributeError")) + ).AndRaise(AttributeError()) self.m.ReplayAll() @@ -1184,7 +1183,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'identify_stack', 'args': {'stack_name': stack_name}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("StackNotFound")) + ).AndRaise(heat_exception.StackNotFound()) self.m.ReplayAll() @@ -1273,7 +1272,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'list_events', 'args': {'stack_identity': identity}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("Exception")) + ).AndRaise(Exception()) self.m.ReplayAll() @@ -1295,7 +1294,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'identify_stack', 'args': {'stack_name': stack_name}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("StackNotFound")) + ).AndRaise(heat_exception.StackNotFound()) self.m.ReplayAll() @@ -1390,7 +1389,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'identify_stack', 'args': {'stack_name': stack_name}, 'version': self.api_version}, - None).AndRaise(rpc_common.RemoteError("StackNotFound")) + None).AndRaise(heat_exception.StackNotFound()) self.m.ReplayAll() @@ -1424,7 +1423,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'describe_stack_resource', 'args': args, 'version': self.api_version}, - None).AndRaise(rpc_common.RemoteError("ResourceNotFound")) + None).AndRaise(heat_exception.ResourceNotFound()) self.m.ReplayAll() @@ -1517,7 +1516,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'identify_stack', 'args': {'stack_name': stack_name}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("StackNotFound")) + ).AndRaise(heat_exception.StackNotFound()) self.m.ReplayAll() @@ -1614,7 +1613,7 @@ class CfnStackControllerTest(HeatTestCase): 'aaaaaaaa-9f88-404d-cccc-ffffffffffff'}, 'version': self.api_version}, None).AndRaise( - rpc_common.RemoteError("PhysicalResourceNotFound")) + heat_exception.PhysicalResourceNotFound()) self.m.ReplayAll() @@ -1709,7 +1708,7 @@ class CfnStackControllerTest(HeatTestCase): 'method': 'identify_stack', 'args': {'stack_name': stack_name}, 'version': self.api_version}, None - ).AndRaise(rpc_common.RemoteError("StackNotFound")) + ).AndRaise(heat_exception.StackNotFound()) self.m.ReplayAll()