Make an attempt at passing exception messages from engine to cli.

Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
changes/40/40/1
Angus Salkeld 11 years ago
parent 65b1ed9e89
commit b7b29add11
  1. 40
      heat/api/v1/stacks.py
  2. 2
      heat/common/client.py
  3. 4
      heat/common/exception.py
  4. 18
      heat/engine/parser.py
  5. 10
      heat/engine/resources.py

@ -31,6 +31,9 @@ from heat.common import wsgi
from heat.common import config
from heat import rpc
from heat import context
import heat.rpc.common as rpc_common
logger = logging.getLogger('heat.api.v1.stacks')
@ -67,10 +70,15 @@ class StackController(object):
"""
con = context.get_admin_context()
stack_list = rpc.call(con, 'engine',
try:
stack_list = rpc.call(con, 'engine',
{'method': 'show_stack',
'args': {'stack_name': req.params['StackName'],
'params': dict(req.params)}})
except rpc_common.RemoteError as ex:
return webob.exc.HTTPBadRequest(str(ex))
res = {'DescribeStacksResult': {'Stacks': [] } }
stacks = res['DescribeStacksResult']['Stacks']
for s in stack_list['stacks']:
@ -125,11 +133,15 @@ class StackController(object):
return webob.exc.HTTPBadRequest(explanation=msg)
stack['StackName'] = req.params['StackName']
return rpc.call(con, 'engine',
{'method': 'create_stack',
'args': {'stack_name': req.params['StackName'],
'template': stack,
'params': dict(req.params)}})
try:
return rpc.call(con, 'engine',
{'method': 'create_stack',
'args': {'stack_name': req.params['StackName'],
'template': stack,
'params': dict(req.params)}})
except rpc_common.RemoteError as ex:
return webob.exc.HTTPBadRequest(str(ex))
def validate_template(self, req):
@ -151,7 +163,10 @@ class StackController(object):
return webob.exc.HTTPBadRequest(explanation=msg)
logger.info('validate_template')
return con.validate_template(stack, **req.params)
try:
return con.validate_template(stack, **req.params)
except rpc_common.RemoteError as ex:
return webob.exc.HTTPBadRequest(str(ex))
def delete(self, req):
"""
@ -159,10 +174,13 @@ class StackController(object):
"""
con = context.get_admin_context()
res = rpc.call(con, 'engine',
try:
res = rpc.call(con, 'engine',
{'method': 'delete_stack',
'args': {'stack_name': req.params['StackName'],
'params': dict(req.params)}})
except rpc_common.RemoteError as ex:
return webob.exc.HTTPBadRequest(str(ex))
if res == None:
return {'DeleteStackResult': ''}
@ -176,9 +194,13 @@ class StackController(object):
"""
con = context.get_admin_context()
stack_name = req.params.get('StackName', None)
event_res = rpc.call(con, 'engine',
try:
event_res = rpc.call(con, 'engine',
{'method': 'list_events',
'args': {'stack_name': stack_name}})
except rpc_common.RemoteError as ex:
return webob.exc.HTTPBadRequest(str(ex))
events = 'Error' not in event_res and event_res['events'] or []
return {'DescribeStackEventsResult': {'StackEvents': events}}

@ -537,7 +537,7 @@ class BaseClient(object):
elif status_code == httplib.CONFLICT:
raise exception.Duplicate(res.read())
elif status_code == httplib.BAD_REQUEST:
raise exception.Invalid(res.read())
raise exception.Invalid(reason=res.read())
elif status_code == httplib.MULTIPLE_CHOICES:
raise exception.MultipleChoices(body=res.read())
elif status_code == httplib.REQUEST_ENTITY_TOO_LARGE:

@ -103,7 +103,7 @@ class NotAuthorized(Forbidden):
class Invalid(OpenstackException):
message = _("Data supplied was not valid.")
message = _("Data supplied was not valid: %(reason)s")
class AuthorizationRedirect(OpenstackException):
@ -168,6 +168,8 @@ class RegionAmbiguity(OpenstackException):
class UserParameterMissing(OpenstackException):
message = _("The Parameter (%(key)s) was not provided.")
class InvalidTemplateAttribute(OpenstackException):
message = _("The Referenced Attribute (%(resource)s %(key)s) is incorrect.")
class UserKeyPairMissing(OpenstackException):
message = _("The Key (%(key_name)s) could not be found.")

@ -16,7 +16,8 @@
import eventlet
import json
import logging
import traceback
from heat.common import exception
from heat.engine import resources
from heat.db import api as db_api
@ -144,9 +145,7 @@ class Stack(object):
try:
self.resources[r].create()
except Exception as ex:
readable = traceback.format_exc()
logger.error('%s', readable)
logger.error('create: %s' % str(ex))
logger.exception('create')
failed = True
self.resources[r].state_set(self.resources[r].CREATE_FAILED, str(ex))
else:
@ -238,15 +237,13 @@ class Stack(object):
def parameter_get(self, key):
if self.parms[key] == None:
logger.warn('Trying to reference parameter: %s, but it is empty' % key)
return ''
raise exception.UserParameterMissing(key=key)
elif self.parms[key].has_key('Value'):
return self.parms[key]['Value']
elif self.parms[key].has_key('Default'):
return self.parms[key]['Default']
else:
logger.warn('Trying to reference parameter: %s, but no Value or Default' % key)
return ''
raise exception.UserParameterMissing(key=key)
def resolve_static_refs(self, s):
'''
@ -309,8 +306,9 @@ class Stack(object):
res = self.resources.get(resource_name)
rc = None
if res:
rc = res.FnGetAtt(key_name)
#print 'found attr:%s.%s=%s' % (res.name, key_name, rc)
return res.FnGetAtt(key_name)
else:
raise exception.InvalidTemplateAttribute(resource=resource_name, key=key_name)
return rc
else:
s[i] = self.resolve_attributes(s[i])

@ -165,8 +165,7 @@ http://docs.amazonwebservices.com/AWSCloudFormation/latest/UserGuide/intrinsic-f
'''
http://docs.amazonwebservices.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html
'''
print '%s.GetAtt(%s)' % (self.name, key)
return unicode('not-this-surely')
raise exception.InvalidTemplateAttribute(resource=self.name, key=key)
def FnBase64(self, data):
'''
@ -278,8 +277,7 @@ class ElasticIp(Resource):
if key == 'AllocationId':
return unicode(self.instance_id)
else:
logger.warn('%s.GetAtt(%s) is not handled' % (self.name, key))
return unicode('')
raise exception.InvalidTemplateAttribute(resource=self.name, key=key)
class ElasticIpAssociation(Resource):
def __init__(self, name, json_snippet, stack):
@ -437,13 +435,13 @@ class Instance(Resource):
def FnGetAtt(self, key):
res = 'not-this-surely'
res = None
if key == 'AvailabilityZone':
res = self.t['Properties']['AvailabilityZone']
elif key == 'PublicIp':
res = self.ipaddress
else:
logger.warn('%s.GetAtt(%s) is not handled' % (self.name, key))
raise exception.InvalidTemplateAttribute(resource=self.name, key=key)
# TODO(asalkeld) PrivateDnsName, PublicDnsName & PrivateIp

Loading…
Cancel
Save