]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
heat engine : Add metadata validation to WaitConditionHandle
authorSteven Hardy <shardy@redhat.com>
Fri, 11 Jan 2013 13:43:52 +0000 (13:43 +0000)
committerSteven Hardy <shardy@redhat.com>
Mon, 14 Jan 2013 18:09:59 +0000 (18:09 +0000)
Validate metadata before updating the WaitConditionHandle resource
metadata, if we raise a ValueError in response to incorrectly
formatted metadata then the CFN API will map this to a
HeatInvalidParameterValueError, resulting in a descriptive error
response to the malformed request

Change-Id: I6fde27066e9e0eaee97b59a7fbbace09ca620b48
Signed-off-by: Steven Hardy <shardy@redhat.com>
heat/engine/resources/wait_condition.py
heat/tests/test_waitcondition.py

index 100ef5e060e2c6fac6b5f80788f1eb9f40cdb60f..49557b78a2cc71d17a736d902f199c7f6ae881fc 100644 (file)
@@ -113,11 +113,29 @@ class WaitConditionHandle(resource.Resource):
         else:
             return unicode(self.name)
 
+    def _metadata_format_ok(self, metadata):
+        """
+        Check the format of the provided metadata is as expected.
+        metadata must use the following format:
+        {
+            "Status" : "Status (should be SUCCESS or FAILURE)"
+            "UniqueId" : "Some ID, must be unique for Count>1",
+            "Data" : "Arbitrary Data",
+            "Reason" : "Reason String"
+        }
+        """
+        expected_keys = ['Data', 'Reason', 'Status', 'UniqueId']
+        return sorted(metadata.keys()) == expected_keys
+
     def metadata_update(self, metadata):
         '''
-        Update the resource metadata
+        Validate and update the resource metadata
         '''
-        self.metadata = metadata
+        if self._metadata_format_ok(metadata):
+            self.metadata = metadata
+        else:
+            logger.error("Metadata failed validation for %s" % self.name)
+            raise ValueError("Metadata format invalid")
 
 
 WAIT_STATUSES = (
index e74791874f2d7f46dafa69c7b38cc3afd47bdd85..c11e1864d3f9e1ac292ff54742479dd8b5b29d5a 100644 (file)
@@ -239,10 +239,38 @@ class WaitConditionHandleTest(unittest.TestCase):
         resource = stack.resources['WaitHandle']
         self.assertEqual(resource.state, 'CREATE_COMPLETE')
 
-        test_metadata = {'foo': 'bar', 'baz': 'quux', 'blarg': 'wibble'}
+        test_metadata = {'Data': 'foo', 'Reason': 'bar',
+                         'Status': 'SUCCESS', 'UniqueId': '123'}
         resource.metadata_update(test_metadata)
         self.assertEqual(resource.metadata, test_metadata)
 
         stack.delete()
 
         self.m.VerifyAll()
+
+    def test_metadata_update_invalid(self):
+        stack = self.create_stack()
+        self.m.ReplayAll()
+        stack.create()
+
+        resource = stack.resources['WaitHandle']
+        self.assertEqual(resource.state, 'CREATE_COMPLETE')
+
+        # metadata_update should raise a ValueError if the metadata
+        # is missing any of the expected keys
+        err1_metadata = {'Data': 'foo', 'Status': 'SUCCESS', 'UniqueId': '123'}
+        self.assertRaises(ValueError, resource.metadata_update, err1_metadata)
+
+        err1_metadata = {'Data': 'foo', 'Reason': 'bar', 'UniqueId': '1234'}
+        self.assertRaises(ValueError, resource.metadata_update, err1_metadata)
+
+        err1_metadata = {'Data': 'foo', 'Reason': 'bar', 'UniqueId': '1234'}
+        self.assertRaises(ValueError, resource.metadata_update, err1_metadata)
+
+        err1_metadata = {'data': 'foo', 'reason': 'bar',
+                         'status': 'SUCCESS', 'uniqueid': '1234'}
+        self.assertRaises(ValueError, resource.metadata_update, err1_metadata)
+
+        stack.delete()
+
+        self.m.VerifyAll()