]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Stop stack updates from exceeding resource limit
authorClint Byrum <clint@fewbar.com>
Fri, 6 Sep 2013 03:00:56 +0000 (20:00 -0700)
committerClint Byrum <clint@fewbar.com>
Fri, 20 Sep 2013 23:19:02 +0000 (16:19 -0700)
Previous patches raise an error when a newly created stack would exceed
the limit. This one applies the same logic during an update. Note that
nested stack updates will be handled in another patch.

Change-Id: Ic5d32501f582640cb77629b902c32c8cb9c20b42
Partial-Bug: #1215100

heat/engine/service.py
heat/tests/test_engine_service.py

index 9241c8d2a32524f963fcf6013d40fb9c34ab9fa7..f5cddd83eadd7c0f2047cadb175f1b78b6c0ef63 100644 (file)
@@ -300,6 +300,8 @@ class EngineService(service.Service):
         # Now parse the template and any parameters for the updated
         # stack definition.
         tmpl = parser.Template(template, files=files)
+        if len(tmpl[tpl.RESOURCES]) > cfg.CONF.max_resources_per_stack:
+            raise exception.StackResourceLimitExceeded()
         stack_name = current_stack.name
         common_params = api.extract_args(args)
         env = environment.Environment(params)
index 46829da42ea43296f1211cd71bde72d62011dc4b..f9d8f70d5d8cda0947698d472f2681633a3ffaed 100644 (file)
@@ -578,6 +578,76 @@ class StackServiceCreateUpdateDeleteTest(HeatTestCase):
         self.assertTrue(result['stack_id'])
         self.m.VerifyAll()
 
+    def test_stack_update_equals(self):
+        stack_name = 'test_stack_update_equals_resource_limit'
+        params = {}
+        res._register_class('GenericResourceType',
+                            generic_rsrc.GenericResource)
+        tpl = {'Resources': {
+               'A': {'Type': 'GenericResourceType'},
+               'B': {'Type': 'GenericResourceType'},
+               'C': {'Type': 'GenericResourceType'}}}
+
+        template = parser.Template(tpl)
+
+        old_stack = parser.Stack(self.ctx, stack_name, template)
+        sid = old_stack.store()
+        s = db_api.stack_get(self.ctx, sid)
+
+        stack = parser.Stack(self.ctx, stack_name, template)
+
+        self.m.StubOutWithMock(parser, 'Stack')
+        self.m.StubOutWithMock(parser.Stack, 'load')
+        parser.Stack.load(self.ctx, stack=s).AndReturn(old_stack)
+
+        self.m.StubOutWithMock(parser, 'Template')
+        self.m.StubOutWithMock(environment, 'Environment')
+
+        parser.Template(template, files=None).AndReturn(stack.t)
+        environment.Environment(params).AndReturn(stack.env)
+        parser.Stack(self.ctx, stack.name,
+                     stack.t, stack.env).AndReturn(stack)
+
+        self.m.StubOutWithMock(stack, 'validate')
+        stack.validate().AndReturn(None)
+
+        self.m.StubOutWithMock(threadgroup, 'ThreadGroup')
+        threadgroup.ThreadGroup().AndReturn(DummyThreadGroup())
+
+        self.m.ReplayAll()
+
+        cfg.CONF.set_override('max_resources_per_stack', 3)
+
+        result = self.man.update_stack(self.ctx, old_stack.identifier(),
+                                       template, params, None, {})
+        self.assertEqual(old_stack.identifier(), result)
+        self.assertTrue(isinstance(result, dict))
+        self.assertTrue(result['stack_id'])
+        self.assertEquals(3, old_stack.root_stack.total_resources())
+        self.m.VerifyAll()
+
+    def test_stack_update_exceeds_resource_limit(self):
+        stack_name = 'test_stack_update_exceeds_resource_limit'
+        params = {}
+        res._register_class('GenericResourceType',
+                            generic_rsrc.GenericResource)
+        tpl = {'Resources': {
+               'A': {'Type': 'GenericResourceType'},
+               'B': {'Type': 'GenericResourceType'},
+               'C': {'Type': 'GenericResourceType'}}}
+
+        template = parser.Template(tpl)
+
+        old_stack = parser.Stack(self.ctx, stack_name, template)
+        sid = old_stack.store()
+        s = db_api.stack_get(self.ctx, sid)
+
+        cfg.CONF.set_override('max_resources_per_stack', 2)
+
+        self.assertRaises(exception.StackResourceLimitExceeded,
+                          self.man.update_stack, self.ctx,
+                          old_stack.identifier(), template, params, None, {})
+
     def test_stack_update_verify_err(self):
         stack_name = 'service_update_verify_err_test_stack'
         params = {'foo': 'bar'}