From ee154544a23ad61318b38b2cebc2cfef60e20b00 Mon Sep 17 00:00:00 2001 From: Clint Byrum Date: Thu, 5 Sep 2013 15:10:16 -0700 Subject: [PATCH] Limit resources per stack in nested stacks 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 | 5 +++ heat/tests/test_nested_stack.py | 60 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/heat/engine/stack_resource.py b/heat/engine/stack_resource.py index 0e15bddd..cd20edcc 100644 --- a/heat/engine/stack_resource.py +++ b/heat/engine/stack_resource.py @@ -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 diff --git a/heat/tests/test_nested_stack.py b/heat/tests/test_nested_stack.py index e7434800..b8e8d6a3 100644 --- a/heat/tests/test_nested_stack.py +++ b/heat/tests/test_nested_stack.py @@ -15,6 +15,10 @@ 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) -- 2.45.2