]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
ValidateTemplate API call framework
authorSteven Dake <sdake@redhat.com>
Fri, 4 May 2012 17:09:41 +0000 (10:09 -0700)
committerSteven Dake <sdake@redhat.com>
Fri, 4 May 2012 17:16:52 +0000 (10:16 -0700)
This is a start on issue #111

While no actual validation is done by this patch, this patch introduces
the framework for validating in each of the resource types and returning
an appropriate error when a validation error occurs.

Signed-off-by: Steven Dake <sdake@redhat.com>
bin/heat
heat/api/v1/stacks.py
heat/engine/eip.py
heat/engine/instance.py
heat/engine/manager.py
heat/engine/parser.py
heat/engine/resources.py
heat/engine/security_group.py
heat/engine/volume.py
heat/engine/wait_condition.py

index 6c8122956315bfed1006721a9e840044e7322c8e..fa55ad51898ac16f6faa7760b81384f1d3b3f525 100755 (executable)
--- a/bin/heat
+++ b/bin/heat
@@ -61,7 +61,8 @@ def template_validate(options, arguments):
     it is in the correct format.
 
     Usage: heat validate \\
-        [--template-file=<template file>|--template-url=<template URL>]
+        [--template-file=<template file>|--template-url=<template URL>] \\
+        [options]
 
     --template-file: Specify a local template file.
     --template-url:  Specify a URL pointing to a stack description template.
@@ -75,6 +76,14 @@ def template_validate(options, arguments):
         logging.error('Please specify a template file or url')
         return utils.FAILURE
 
+    if options.parameters:
+        count = 1
+        for p in options.parameters.split(';'):
+            (n, v) = p.split('=')
+            parameters['Parameters.member.%d.ParameterKey' % count] = n
+            parameters['Parameters.member.%d.ParameterValue' % count] = v
+            count = count + 1
+
     client = get_client(options)
     result = client.validate_template(**parameters)
     print json.dumps(result, indent=2)
index c1deb0314bd22480382a0ca53621a9847a2682f4..5e5e04dc022c072ec485845b54d91b00051d8923 100644 (file)
@@ -164,7 +164,10 @@ class StackController(object):
 
         logger.info('validate_template')
         try:
-            return con.validate_template(stack, **req.params)
+            return rpc.call(con, 'engine',
+                            {'method': 'validate_template',
+                             'args': {'template': stack,
+                                      'params': dict(req.params)}})
         except rpc_common.RemoteError as ex:
             return webob.exc.HTTPBadRequest(str(ex))
 
@@ -179,6 +182,7 @@ class StackController(object):
                        {'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))
 
index a0d94cdcbc30ec07a19d94b6e460db28e3856f97..5c2103542d5a127ee13a852d162edc281f3d1509 100644 (file)
@@ -45,6 +45,12 @@ class ElasticIp(Resource):
         self.instance_id_set(ips.id)
         self.state_set(self.CREATE_COMPLETE)
 
+    def validate(self):
+        '''
+        Validate the ip address here
+        '''
+        return None
+
     def reload(self):
         '''
         get the ipaddress here
index 951a38edfb182e2d6894feddf3e4f57cf74d6b0f..9ff1e75d9648be2b556aa0ad84023d5a91fe0109 100644 (file)
@@ -193,6 +193,12 @@ class Instance(Resource):
         else:
             self.state_set(self.CREATE_FAILED)
 
+    def validate(self):
+        '''
+        Validate the server's ip address
+        '''
+        return None
+
     def reload(self):
         '''
         re-read the server's ipaddress so FnGetAtt works.
index a1430a281c82ae744ee83b29dbabee0831a6d0c1..3f3b58e511acac91c106f870fe805dcd5a8ab406 100644 (file)
@@ -157,21 +157,22 @@ class EngineManager(manager.Manager):
         return {'stack': {'id': new_s.id, 'name': new_s.name,\
                 'created_at': str(new_s.created_at)}}
 
-    def validate_template(self, req, body=None):
+    def validate_template(self, context, template, params):
         """
         The validate_template method uses the stack parser to check
         the validity of a template.
 
-        arg1 -> http request params.
-        arg2 -> Template body.
+        arg1 -> RPC context.
+        arg3 -> Template of stack you want to create.
+        arg4 -> Params passed from API.
         """
 
         logger.info('validate_template')
-        if body is None:
+        if template is None:
             msg = _("No Template provided.")
             return webob.exc.HTTPBadRequest(explanation=msg)
 
-        s = parser.Stack('validate', body, 0, req.params)
+        s = parser.Stack('validate', template, 0, params)
         res = s.validate()
 
         return res
index 00793b6fd19269cfce495862c675cde23fafc7bd..05d4df1e2cc0eb12bd8890f3378cd2807dbe6977 100644 (file)
@@ -111,10 +111,28 @@ class Stack(object):
         http://docs.amazonwebservices.com/AWSCloudFormation/latest/ \
             APIReference/API_ValidateTemplate.html
         '''
-        response = {'ValidateTemplateResult': {
-                    'Description': 'bla',
-                    'Parameters': []}}
 
+        order = self.get_create_order()
+
+        response = None
+
+        for r in order:
+            try:
+                res = self.resources[r].validate()
+                if res:
+                    print 'setting response'
+                    response = {'ValidateTemplateResult': {
+                           'Description': 'Malformed Query Response [%s]' % res,
+                           'Parameters': []}}
+                    break
+            except Exception as ex:
+                logger.exception('validate')
+                failed = True
+
+        if response == None:
+            response = {'ValidateTemplateResult': {
+                        'Description': 'Successfully validated',
+                        'Parameters': []}}
         for p in self.parms:
             jp = {'member': {}}
             res = jp['member']
index c1bac4147adda1d1142c9453378561b8d11840ca..53a711e6c6531aa6c87c0d70aaa386ba5d9e739b 100644 (file)
@@ -106,6 +106,13 @@ class Resource(object):
         self.stack.resolve_joins(self.t)
         self.stack.resolve_base64(self.t)
 
+    def validate(self):
+        logger.info('validating %s name:%s' % (self.t['Type'], self.name))
+
+        self.stack.resolve_attributes(self.t)
+        self.stack.resolve_joins(self.t)
+        self.stack.resolve_base64(self.t)
+
     def instance_id_set(self, inst):
         self.instance_id = inst
 
index 68b9cb3e28c597946fde139f343896e2ccfeab1d..6d413a6c179f22c1d5528ecf15f9cc8cf67cf6bc 100644 (file)
@@ -73,6 +73,12 @@ class SecurityGroup(Resource):
 
         self.state_set(self.CREATE_COMPLETE)
 
+    def validate(self):
+        '''
+        Validate the security group
+        '''
+        return None
+
     def delete(self):
         if self.state == self.DELETE_IN_PROGRESS or \
            self.state == self.DELETE_COMPLETE:
index d420b442f17bf75cf8f43b4e6f8c7cd3281bcc4a..92cec88684e5f593cde792e05fe8b5a9661d02e7 100644 (file)
@@ -46,6 +46,12 @@ class Volume(Resource):
         else:
             self.state_set(self.CREATE_FAILED)
 
+    def validate(self):
+        '''
+        Validate the volume
+        '''
+        return None
+
     def delete(self):
         if self.state == self.DELETE_IN_PROGRESS or \
            self.state == self.DELETE_COMPLETE:
index 797d0d7eb196d8aeabde1b1795ec39d1e95d1137..2256d0516bc0f556fdbdcf75a03b05dfc4629e1e 100644 (file)
@@ -49,6 +49,12 @@ class WaitConditionHandle(Resource):
 
         self.state_set(self.CREATE_COMPLETE)
 
+    def validate(self):
+        '''
+        Validate the wait condition
+        '''
+        return None
+
     def delete(self):
         if self.state == self.DELETE_IN_PROGRESS or \
            self.state == self.DELETE_COMPLETE: