]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Limit resources per stack in nested stacks
authorClint Byrum <clint@fewbar.com>
Thu, 5 Sep 2013 22:10:16 +0000 (15:10 -0700)
committerClint Byrum <clint@fewbar.com>
Fri, 20 Sep 2013 00:44:29 +0000 (17:44 -0700)
In an earlier patch, the root stack creation was limited by the
max_resources_per_stack config setting. Now we need to apply the same
limit for nested stacks.

Change-Id: I2f871a5d5f4c51dd9cd7c93e94f8b0c8d87fa069
Partial-Bug: #1215100

heat/engine/stack_resource.py
heat/tests/test_nested_stack.py

index 0e15bddd389fa8bbd444ab160caa35187f961eda..cd20edccc9b5e8d9c36afb46719a1bf106a2bb59 100644 (file)
@@ -21,6 +21,7 @@ from heat.engine import environment
 from heat.engine import parser
 from heat.engine import resource
 from heat.engine import scheduler
+from heat.engine import template as tmpl
 
 from heat.openstack.common import log as logging
 
@@ -75,6 +76,10 @@ class StackResource(resource.Resource):
                 cfg.CONF.max_nested_stack_depth
             raise exception.RequestLimitExceeded(message=msg)
         template = parser.Template(child_template)
+        if ((len(template[tmpl.RESOURCES]) +
+             self.stack.root_stack.total_resources() >
+             cfg.CONF.max_resources_per_stack)):
+            raise exception.StackResourceLimitExceeded()
         self._outputs_to_attribs(child_template)
 
         # Note we disable rollback for nested stacks, since they
index e7434800fab5f90e15bcd6ca5396e49399bcb3f3..b8e8d6a375046bd4dddffe204b94970039839eec 100644 (file)
 
 import copy
 
+from oslo.config import cfg
+
+cfg.CONF.import_opt('max_resources_per_stack', 'heat.common.config')
+
 from heat.common import exception
 from heat.common import template_format
 from heat.common import urlfetch
@@ -105,6 +109,62 @@ Outputs:
 
         self.m.VerifyAll()
 
+    def test_nested_stack_create_exceeds_resource_limit(self):
+        cfg.CONF.set_override('max_resources_per_stack', 1)
+        resource._register_class('GenericResource',
+                                 generic_rsrc.GenericResource)
+        urlfetch.get('https://server.test/the.template').MultipleTimes().\
+            AndReturn('''
+HeatTemplateFormatVersion: '2012-12-12'
+Parameters:
+  KeyName:
+    Type: String
+Resources:
+  NestedResource:
+    Type: GenericResource
+Outputs:
+  Foo:
+    Value: bar
+''')
+        self.m.ReplayAll()
+
+        t = template_format.parse(self.test_template)
+        stack = self.parse_stack(t)
+        stack.create()
+        self.assertEquals(stack.state, (stack.CREATE, stack.FAILED))
+        self.assertIn('Maximum resources per stack exceeded',
+                      stack.status_reason)
+
+        self.m.VerifyAll()
+
+    def test_nested_stack_create_equals_resource_limit(self):
+        cfg.CONF.set_override('max_resources_per_stack', 2)
+        resource._register_class('GenericResource',
+                                 generic_rsrc.GenericResource)
+        urlfetch.get('https://server.test/the.template').MultipleTimes().\
+            AndReturn('''
+HeatTemplateFormatVersion: '2012-12-12'
+Parameters:
+  KeyName:
+    Type: String
+Resources:
+  NestedResource:
+    Type: GenericResource
+Outputs:
+  Foo:
+    Value: bar
+''')
+        self.m.ReplayAll()
+
+        t = template_format.parse(self.test_template)
+        stack = self.parse_stack(t)
+        stack.create()
+        self.assertEquals(stack.state, (stack.CREATE, stack.COMPLETE))
+        self.assertIn('NestedResource',
+                      stack.resources['the_nested'].nested().resources)
+
+        self.m.VerifyAll()
+
     def test_nested_stack_update(self):
         urlfetch.get('https://server.test/the.template').MultipleTimes().\
             AndReturn(self.nested_template)