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
This commit is contained in:
parent
b43018834e
commit
03638aad74
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in New Issue