Merge "Allow in-place update of nested stack"

This commit is contained in:
Jenkins 2013-08-26 11:20:27 +00:00 committed by Gerrit Code Review
commit d719d0b072
2 changed files with 72 additions and 6 deletions

View File

@ -16,6 +16,7 @@
from heat.common import exception
from heat.common import template_format
from heat.common import urlfetch
from heat.engine.properties import Properties
from heat.engine import stack_resource
from heat.openstack.common import log as logging
@ -38,6 +39,10 @@ class NestedStack(stack_resource.StackResource):
PROP_TIMEOUT_MINS: {'Type': 'Number'},
PROP_PARAMETERS: {'Type': 'Map'}}
update_allowed_keys = ('Properties',)
update_allowed_properties = (PROP_TEMPLATE_URL, PROP_TIMEOUT_MINS,
PROP_PARAMETERS)
def handle_create(self):
template_data = urlfetch.get(self.properties[PROP_TEMPLATE_URL])
template = template_format.parse(template_data)
@ -58,6 +63,20 @@ class NestedStack(stack_resource.StackResource):
def FnGetRefId(self):
return self.nested().identifier().arn()
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
# Nested stack template may be changed even if the prop_diff is empty.
self.properties = Properties(self.properties_schema,
json_snippet.get('Properties', {}),
self.stack.resolve_runtime_data,
self.name)
template_data = urlfetch.get(self.properties[PROP_TEMPLATE_URL])
template = template_format.parse(template_data)
self.update_with_template(template,
self.properties[PROP_PARAMETERS],
self.properties[PROP_TIMEOUT_MINS])
def resource_mapping():
return {

View File

@ -13,6 +13,8 @@
# under the License.
import copy
from heat.common import exception
from heat.common import template_format
from heat.common import urlfetch
@ -47,6 +49,16 @@ Outputs:
Value: bar
'''
update_template = '''
HeatTemplateFormatVersion: '2012-12-12'
Parameters:
KeyName:
Type: String
Outputs:
Bar:
Value: foo
'''
def setUp(self):
super(NestedStackTest, self).setUp()
self.m.StubOutWithMock(urlfetch, 'get')
@ -67,9 +79,9 @@ Outputs:
stack.store()
return stack
def test_nested_stack(self):
urlfetch.get('https://localhost/the.template').AndReturn(
self.nested_template)
def test_nested_stack_create(self):
urlfetch.get('https://localhost/the.template').MultipleTimes().\
AndReturn(self.nested_template)
self.m.ReplayAll()
stack = self.create_stack(self.test_template)
@ -80,9 +92,6 @@ Outputs:
rsrc.physical_resource_name())
self.assertTrue(rsrc.FnGetRefId().startswith(arn_prefix))
self.assertRaises(resource.UpdateReplace,
rsrc.handle_update, {}, {}, {})
self.assertEqual('bar', rsrc.FnGetAtt('Outputs.Foo'))
self.assertRaises(
exception.InvalidTemplateAttribute, rsrc.FnGetAtt, 'Foo')
@ -96,6 +105,44 @@ Outputs:
self.m.VerifyAll()
def test_nested_stack_update(self):
urlfetch.get('https://localhost/the.template').MultipleTimes().\
AndReturn(self.nested_template)
urlfetch.get('https://localhost/new.template').MultipleTimes().\
AndReturn(self.update_template)
self.m.ReplayAll()
stack = self.create_stack(self.test_template)
rsrc = stack['the_nested']
original_nested_id = rsrc.resource_id
t = template_format.parse(self.test_template)
new_res = copy.deepcopy(t['Resources']['the_nested'])
new_res['Properties']['TemplateURL'] = 'https://localhost/new.template'
prop_diff = {'TemplateURL': 'https://localhost/new.template'}
rsrc.handle_update(new_res, {}, prop_diff)
# Expect the physical resource name staying the same after update,
# so that the nested was actually updated instead of replaced.
self.assertEqual(original_nested_id, rsrc.resource_id)
db_nested = db_api.stack_get(stack.context,
rsrc.resource_id)
# Owner_id should be preserved during the update process.
self.assertEqual(stack.id, db_nested.owner_id)
self.assertEqual('foo', rsrc.FnGetAtt('Outputs.Bar'))
self.assertRaises(
exception.InvalidTemplateAttribute, rsrc.FnGetAtt, 'Foo')
self.assertRaises(
exception.InvalidTemplateAttribute, rsrc.FnGetAtt, 'Outputs.Foo')
self.assertRaises(
exception.InvalidTemplateAttribute, rsrc.FnGetAtt, 'Bar')
rsrc.delete()
self.m.VerifyAll()
def test_nested_stack_suspend_resume(self):
urlfetch.get('https://localhost/the.template').AndReturn(
self.nested_template)