]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Don't assume parsed JSON in REST API.
authorSteve Baker <sbaker@redhat.com>
Mon, 26 Nov 2012 00:52:34 +0000 (13:52 +1300)
committerSteve Baker <sbaker@redhat.com>
Mon, 26 Nov 2012 20:33:11 +0000 (09:33 +1300)
This checks to see if the 'template' attribute is a dict.

If not it uses format.parse_to_template to parse it.
Change-Id: Ic9b9ef3e88a33a93d5896277cc3d4da4fd55fc25

heat/api/openstack/v1/stacks.py
heat/tests/test_api_openstack_v1.py

index 0461551dbc498a2483007dd31ac814013b4d7958..64a78fec037976994ff9136b9eaa132d656b48c2 100644 (file)
@@ -26,6 +26,7 @@ from webob import exc
 
 from heat.api.openstack.v1 import util
 from heat.common import wsgi
+from heat.engine import format
 from heat.engine import api as engine_api
 from heat.engine import rpcapi as engine_rpcapi
 
@@ -57,16 +58,16 @@ class InstantiationData(object):
         self.data = data
 
     @staticmethod
-    def json_parse(data, data_type):
+    def format_parse(data, data_type):
         """
-        Parse the supplied data as JSON, raising the appropriate exception
-        if it is in the wrong format.
+        Parse the supplied data as JSON or YAML, raising the appropriate
+        exception if it is in the wrong format.
         """
 
         try:
-            return json.loads(data)
+            return format.parse_to_template(data)
         except ValueError:
-            err_reason = "%s not in valid JSON format" % data_type
+            err_reason = "%s not in valid format" % data_type
             raise exc.HTTPBadRequest(explanation=err_reason)
 
     def stack_name(self):
@@ -79,7 +80,8 @@ class InstantiationData(object):
 
     def _load_template(self, template_url):
         """
-        Retrieve a template from a URL, in JSON format.
+        Retrieve a template from a URL, in JSON
+        or YAML format.
         """
         logger.debug('Template URL %s' % template_url)
         url = urlparse.urlparse(template_url)
@@ -98,7 +100,7 @@ class InstantiationData(object):
                 if resp.status != 200:
                     raise exc.HTTPBadRequest(explanation=err_reason)
 
-                return self.json_parse(resp.read(), 'Template')
+                return self.format_parse(resp.read(), 'Template')
             finally:
                 conn.close()
         except socket.gaierror:
@@ -107,10 +109,14 @@ class InstantiationData(object):
     def template(self):
         """
         Get template file contents, either inline or from a URL, in JSON
-        format.
+        or YAML format.
         """
         if self.PARAM_TEMPLATE in self.data:
-            return self.data[self.PARAM_TEMPLATE]
+            tpl = self.data[self.PARAM_TEMPLATE]
+            if isinstance(tpl, dict):
+                return tpl
+            return self.format_parse(self.data[self.PARAM_TEMPLATE],
+                'Template')
         elif self.PARAM_TEMPLATE_URL in self.data:
             return self._load_template(self.data[self.PARAM_TEMPLATE_URL])
 
index 2e42f59c3a8a10c7885cecc3513ccde46acea971..e624192c0e154945b1350bdfb866ce550749be5c 100644 (file)
@@ -18,6 +18,7 @@ import socket
 import nose
 import mox
 import json
+import yaml
 import unittest
 from nose.plugins.attrib import attr
 
@@ -48,16 +49,16 @@ class InstantiationDataTest(unittest.TestCase):
     def tearDown(self):
         self.m.UnsetStubs()
 
-    def test_json_parse(self):
+    def test_format_parse(self):
         data = {"key1": ["val1[0]", "val1[1]"], "key2": "val2"}
         json_repr = '{ "key1": [ "val1[0]", "val1[1]" ], "key2": "val2" }'
-        parsed = stacks.InstantiationData.json_parse(json_repr, 'foo')
+        parsed = stacks.InstantiationData.format_parse(json_repr, 'foo')
         self.assertEqual(parsed, data)
 
-    def test_json_parse_invalid(self):
+    def test_format_parse_invalid(self):
         self.assertRaises(webob.exc.HTTPBadRequest,
-                          stacks.InstantiationData.json_parse,
-                          'not json', 'Garbage')
+                          stacks.InstantiationData.format_parse,
+                          '!@#$%^&not json', 'Garbage')
 
     def test_stack_name(self):
         body = {'stack_name': 'wibble'}
@@ -75,6 +76,20 @@ class InstantiationDataTest(unittest.TestCase):
         data = stacks.InstantiationData(body)
         self.assertEqual(data.template(), template)
 
+    def test_template_string_json(self):
+        template = '{"foo": "bar", "blarg": "wibble"}'
+        body = {'template': template}
+        data = stacks.InstantiationData(body)
+        self.assertEqual(data.template(), json.loads(template))
+
+    def test_template_string_yaml(self):
+        template = '''foo: bar
+blarg: wibble
+'''
+        body = {'template': template}
+        data = stacks.InstantiationData(body)
+        self.assertEqual(data.template(), yaml.load(template))
+
     def test_template_url(self):
         template = {'foo': 'bar', 'blarg': 'wibble'}
         url = 'http://example.com/template'