From dfed072c0150e06592920e8016247326369ceffb Mon Sep 17 00:00:00 2001 From: Steven Hardy Date: Tue, 29 Jan 2013 13:57:02 +0000 Subject: [PATCH] heat engine : Support Metadata update for Instance resource Allow Instance Metadata to be updated via UpdateStack ref blueprint instance-update-stack Change-Id: I7c2fd281650e0715c86bf63b8ab61114a9b81da8 Signed-off-by: Steven Hardy --- heat/engine/resources/instance.py | 19 +++++++++++++- heat/tests/test_instance.py | 43 +++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/heat/engine/resources/instance.py b/heat/engine/resources/instance.py index 4e777d23..ef38f2b3 100644 --- a/heat/engine/resources/instance.py +++ b/heat/engine/resources/instance.py @@ -108,6 +108,10 @@ class Instance(resource.Resource): 'Volumes': {'Type': 'List', 'Implemented': False}} + # template keys supported for handle_update, note trailing comma + # is required for a single item to get a tuple not a string + update_allowed_keys = ('Metadata',) + def __init__(self, name, json_snippet, stack): super(Instance, self).__init__(name, json_snippet, stack) self.ipaddress = None @@ -283,7 +287,20 @@ class Instance(resource.Resource): self.name, server.status)) def handle_update(self, json_snippet): - return self.UPDATE_REPLACE + status = self.UPDATE_REPLACE + try: + tmpl_diff = self.update_template_diff(json_snippet) + except NotImplementedError: + return self.UPDATE_REPLACE + + for k in tmpl_diff: + if k == 'Metadata': + self.metadata = json_snippet.get('Metadata', {}) + status = self.UPDATE_COMPLETE + else: + return self.UPDATE_REPLACE + + return status def validate(self): ''' diff --git a/heat/tests/test_instance.py b/heat/tests/test_instance.py index e74bd964..2a59558d 100644 --- a/heat/tests/test_instance.py +++ b/heat/tests/test_instance.py @@ -14,6 +14,7 @@ import os +import copy import unittest import mox @@ -140,3 +141,45 @@ class instancesTest(unittest.TestCase): self.assertEqual(private_ip, '4.5.6.7') private_ip = instance.FnGetAtt('PrivateDnsName') self.assertEqual(private_ip, '4.5.6.7') + + def test_instance_update_metadata(self): + f = open("%s/WordPress_Single_Instance_gold.template" % self.path) + t = template_format.parse(f.read()) + f.close() + + stack_name = 'instance_update_test_stack' + template = parser.Template(t) + params = parser.Parameters(stack_name, template, {'KeyName': 'test'}) + stack = parser.Stack(None, stack_name, template, params, + stack_id=uuidutils.generate_uuid()) + + t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2' + t['Resources']['WebServer']['Properties']['InstanceType'] = \ + '256 MB Server' + instance = instances.Instance('create_instance_name', + t['Resources']['WebServer'], stack) + + self.m.StubOutWithMock(instance, 'nova') + instance.nova().MultipleTimes().AndReturn(self.fc) + + instance.t = instance.stack.resolve_runtime_data(instance.t) + + # need to resolve the template functions + server_userdata = instance._build_userdata( + instance.t['Properties']['UserData']) + self.m.StubOutWithMock(self.fc.servers, 'create') + self.fc.servers.create( + image=1, flavor=1, key_name='test', + name='%s.%s' % (stack_name, instance.name), + security_groups=None, + userdata=server_userdata, scheduler_hints=None, + meta=None).AndReturn(self.fc.servers.list()[1]) + self.m.ReplayAll() + + self.assertEqual(instance.create(), None) + + update_template = copy.deepcopy(instance.t) + update_template['Metadata'] = {'test': 123} + self.assertEqual(instance.update(update_template), + instance.UPDATE_COMPLETE) + self.assertEqual(instance.metadata, {'test': 123}) -- 2.45.2