]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Make an attempt at passing exception messages from engine to cli.
authorAngus Salkeld <asalkeld@redhat.com>
Mon, 16 Apr 2012 05:37:26 +0000 (15:37 +1000)
committerAngus Salkeld <asalkeld@redhat.com>
Mon, 16 Apr 2012 05:37:26 +0000 (15:37 +1000)
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
heat/api/v1/stacks.py
heat/common/client.py
heat/common/exception.py
heat/engine/parser.py
heat/engine/resources.py

index 50bd3ac3b21274cc8a455d1121a755bbb7f891da..11c135c8f54cfc9513068095aa117d5a3a71319f 100644 (file)
@@ -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}}
index a3a49d347fc940d563588478d6a4d45c79e1cb7f..9cf0d7cf13636c43b82efc74e62e0c1ea5b4bea0 100644 (file)
@@ -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:
index 8b6e875b5f850a83922427e61dc72ad87258568a..46ab31aa89d5804b4609059ffb601a7883058eb3 100644 (file)
@@ -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.")
index 9454ed760c18395e610fcbfd36d2fca51b193190..08869255e934834f08bc0d044708196fa858c565 100644 (file)
@@ -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])
index 430d27c3d988d041d02e1e2f2ac4346d8b865768..303d331d9949cdec2075d625796bc48ba53a1ac5 100644 (file)
@@ -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