]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Move abstract nested stack class to separate file
authorZane Bitter <zbitter@redhat.com>
Tue, 15 Jan 2013 12:42:56 +0000 (13:42 +0100)
committerGerrit Code Review <review@openstack.org>
Thu, 17 Jan 2013 10:15:13 +0000 (10:15 +0000)
The class heat.engine.resources.stack.Stack is intended to be an abstract
class which resources that are implemented as nested stacks may inherit
from. Rename it to StackResource and move it to the
heat.engine.stack_resource module, so that other resource modules
(including plugins) may include it without having to also import the
NestedStack class (which implements the AWS::CloudFormation::Stack resource
type).

Change-Id: Ie7c05ec64e1c9632c7a24d96b5d790c9e50b691f
Signed-off-by: Zane Bitter <zbitter@redhat.com>
heat/engine/resources/stack.py
heat/engine/stack_resource.py [new file with mode: 0644]
heat/tests/test_dbinstance.py

index db99b438d1fb5299a80b39634ec1649845a4ee44..c18ef6129fadc5205a955dc18a472afdd31d4850 100644 (file)
@@ -14,9 +14,9 @@
 #    under the License.
 
 from heat.common import exception
-from heat.common import template_format
-from heat.engine import resource
 from heat.engine import parser
+from heat.engine import stack_resource
+from heat.common import template_format
 from heat.common import urlfetch
 
 from heat.openstack.common import log as logging
@@ -29,61 +29,11 @@ logger = logging.getLogger(__name__)
  PROP_PARAMETERS) = ('TemplateURL', 'TimeoutInMinutes', 'Parameters')
 
 
-class Stack(resource.Resource):
-    def __init__(self, name, json_snippet, stack):
-        super(Stack, self).__init__(name, json_snippet, stack)
-        self._nested = None
-
-    def nested(self):
-        if self._nested is None and self.resource_id is not None:
-            self._nested = parser.Stack.load(self.context,
-                                             self.resource_id)
-
-            if self._nested is None:
-                raise exception.NotFound('Nested stack not found in DB')
-
-        return self._nested
-
-    def create_with_template(self, child_template, user_params):
-        '''
-        Handle the creation of the nested stack from a given JSON template.
-        '''
-        template = parser.Template(child_template)
-        params = parser.Parameters(self.physical_resource_name(), template,
-                                   user_params)
-
-        self._nested = parser.Stack(self.context,
-                                    self.physical_resource_name(),
-                                    template,
-                                    params)
-
-        nested_id = self._nested.store(self.stack)
-        self.resource_id_set(nested_id)
-        self._nested.create()
-        if self._nested.state != self._nested.CREATE_COMPLETE:
-            raise exception.Error(self._nested.state_description)
-
-    def delete_nested(self):
-        try:
-            stack = self.nested()
-        except exception.NotFound:
-            logger.info("Stack not found to delete")
-        else:
-            if stack is not None:
-                stack.delete()
-
-    def get_output(self, op):
-        stack = self.nested()
-        if not stack:
-            return None
-        if op not in stack.outputs:
-            raise exception.InvalidTemplateAttribute(
-                resource=self.physical_resource_name(), key=key)
-
-        return stack.output(op)
-
+class NestedStack(stack_resource.StackResource):
+    '''
+    A Resource representing a child stack to allow composition of templates.
+    '''
 
-class NestedStack(Stack):
     properties_schema = {PROP_TEMPLATE_URL: {'Type': 'String',
                                              'Required': True},
                          PROP_TIMEOUT_MINS: {'Type': 'Number'},
diff --git a/heat/engine/stack_resource.py b/heat/engine/stack_resource.py
new file mode 100644 (file)
index 0000000..f392abb
--- /dev/null
@@ -0,0 +1,93 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from heat.common import exception
+from heat.engine import resource
+from heat.engine import parser
+
+from heat.openstack.common import log as logging
+
+logger = logging.getLogger(__name__)
+
+
+class StackResource(resource.Resource):
+    '''
+    An abstract Resource subclass that allows the management of an entire Stack
+    as a resource in a parent stack.
+    '''
+
+    def __init__(self, name, json_snippet, stack):
+        super(StackResource, self).__init__(name, json_snippet, stack)
+        self._nested = None
+
+    def nested(self):
+        '''
+        Return a Stack object representing the nested (child) stack.
+        '''
+        if self._nested is None and self.resource_id is not None:
+            self._nested = parser.Stack.load(self.context,
+                                             self.resource_id)
+
+            if self._nested is None:
+                raise exception.NotFound('Nested stack not found in DB')
+
+        return self._nested
+
+    def create_with_template(self, child_template, user_params):
+        '''
+        Handle the creation of the nested stack from a given JSON template.
+        '''
+        template = parser.Template(child_template)
+        params = parser.Parameters(self.physical_resource_name(), template,
+                                   user_params)
+
+        self._nested = parser.Stack(self.context,
+                                    self.physical_resource_name(),
+                                    template,
+                                    params)
+
+        nested_id = self._nested.store(self.stack)
+        self.resource_id_set(nested_id)
+        self._nested.create()
+        if self._nested.state != self._nested.CREATE_COMPLETE:
+            raise exception.Error(self._nested.state_description)
+
+    def delete_nested(self):
+        '''
+        Delete the nested stack.
+        '''
+        try:
+            stack = self.nested()
+        except exception.NotFound:
+            logger.info("Stack not found to delete")
+        else:
+            if stack is not None:
+                stack.delete()
+
+    def get_output(self, op):
+        '''
+        Return the specified Output value from the nested stack.
+
+        If the output key does not exist, raise an InvalidTemplateAttribute
+        exception.
+        '''
+        stack = self.nested()
+        if not stack:
+            return None
+        if op not in stack.outputs:
+            raise exception.InvalidTemplateAttribute(
+                resource=self.physical_resource_name(), key=key)
+
+        return stack.output(op)
index 498e7df45fa346dc0ef53358b9f838acfdf05063..f99b81150b978166be0f61e372734ea598c51109 100644 (file)
@@ -24,7 +24,6 @@ from heat.common import context
 from heat.common import exception
 from heat.common import template_format
 from heat.engine import parser
-from heat.engine.resources import stack
 from heat.engine.resources import dbinstance as dbi
 
 
@@ -33,7 +32,7 @@ from heat.engine.resources import dbinstance as dbi
 class DBInstanceTest(unittest.TestCase):
     def setUp(self):
         self.m = mox.Mox()
-        self.m.StubOutWithMock(stack.Stack, 'create_with_template')
+        self.m.StubOutWithMock(dbi.DBInstance, 'create_with_template')
         self.m.StubOutWithMock(dbi.DBInstance, 'nested')
 
     def tearDown(self):
@@ -90,8 +89,8 @@ class DBInstanceTest(unittest.TestCase):
             'Port': '3306'
         }
 
-        stack.Stack.create_with_template(mox.IgnoreArg(),
-                                         params).AndReturn(None)
+        dbi.DBInstance.create_with_template(mox.IgnoreArg(),
+                                            params).AndReturn(None)
 
         fn = FakeNested()