heat engine : add Resource update_template_diff method
Add method to top-level Resource class update_template_diff() which allows us to determine the difference between old/new templates for a resource update, and also raise an error if the changed keys are not in the list of those defined as supported for update by the resource ref blueprint instance-update-stack Change-Id: Ibef07a0cecbc15f7f1d6c2c663743e3af8023057 Signed-off-by: Steven Hardy <shardy@redhat.com>
This commit is contained in:
parent
b3744f28af
commit
3569bf2323
|
@ -101,6 +101,10 @@ class Resource(object):
|
||||||
|
|
||||||
metadata = Metadata()
|
metadata = Metadata()
|
||||||
|
|
||||||
|
# Resource implementation set this to the subset of template keys
|
||||||
|
# which are supported for handle_update, used by update_template_diff
|
||||||
|
update_allowed_keys = ()
|
||||||
|
|
||||||
def __new__(cls, name, json, stack):
|
def __new__(cls, name, json, stack):
|
||||||
'''Create a new Resource of the appropriate class for its type.'''
|
'''Create a new Resource of the appropriate class for its type.'''
|
||||||
|
|
||||||
|
@ -174,6 +178,32 @@ class Resource(object):
|
||||||
template = self.t.get(section, default)
|
template = self.t.get(section, default)
|
||||||
return self.stack.resolve_runtime_data(template)
|
return self.stack.resolve_runtime_data(template)
|
||||||
|
|
||||||
|
def update_template_diff(self, json_snippet=None):
|
||||||
|
'''
|
||||||
|
Returns the difference between json_template and self.t
|
||||||
|
If something has been removed in json_snippet which exists
|
||||||
|
in self.t we set it to None. If any keys have changed which
|
||||||
|
are not in update_allowed_keys, raises NotImplementedError
|
||||||
|
'''
|
||||||
|
update_allowed_set = set(self.update_allowed_keys)
|
||||||
|
|
||||||
|
# Create a set containing the keys in both current and update template
|
||||||
|
current_snippet = self.parsed_template()
|
||||||
|
template_keys = set(current_snippet.keys())
|
||||||
|
template_keys.update(set(json_snippet.keys()))
|
||||||
|
|
||||||
|
# Create a set of keys which differ (or are missing/added)
|
||||||
|
changed_keys_set = set([k for k in template_keys
|
||||||
|
if current_snippet.get(k, None) !=
|
||||||
|
json_snippet.get(k, None)])
|
||||||
|
|
||||||
|
if not changed_keys_set.issubset(update_allowed_set):
|
||||||
|
badkeys = changed_keys_set - update_allowed_set
|
||||||
|
raise NotImplementedError("Cannot update keys %s for %s" %
|
||||||
|
(badkeys, self.name))
|
||||||
|
|
||||||
|
return dict((k, json_snippet.get(k, None)) for k in changed_keys_set)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '%s "%s"' % (self.__class__.__name__, self.name)
|
return '%s "%s"' % (self.__class__.__name__, self.name)
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,44 @@ class ResourceTest(unittest.TestCase):
|
||||||
|
|
||||||
self.assertNotEqual(res1, res2)
|
self.assertNotEqual(res1, res2)
|
||||||
|
|
||||||
|
def test_update_template_diff_empty(self):
|
||||||
|
tmpl = {'Type': 'Foo'}
|
||||||
|
update_snippet = {}
|
||||||
|
res = resource.GenericResource('test_resource', tmpl, self.stack)
|
||||||
|
self.assertRaises(NotImplementedError, res.update_template_diff,
|
||||||
|
update_snippet)
|
||||||
|
|
||||||
|
def test_update_template_diff_changed_notallowed(self):
|
||||||
|
tmpl = {'Type': 'Foo'}
|
||||||
|
update_snippet = {'Type': 'Bar'}
|
||||||
|
res = resource.GenericResource('test_resource', tmpl, self.stack)
|
||||||
|
self.assertRaises(NotImplementedError, res.update_template_diff,
|
||||||
|
update_snippet)
|
||||||
|
|
||||||
|
def test_update_template_diff_changed_modified(self):
|
||||||
|
tmpl = {'Type': 'Foo', 'Metadata': {'foo': 123}}
|
||||||
|
update_snippet = {'Type': 'Foo', 'Metadata': {'foo': 456}}
|
||||||
|
res = resource.GenericResource('test_resource', tmpl, self.stack)
|
||||||
|
res.update_allowed_keys = ['Metadata']
|
||||||
|
diff = res.update_template_diff(json_snippet=update_snippet)
|
||||||
|
self.assertEqual(diff, {'Metadata': {'foo': 456}})
|
||||||
|
|
||||||
|
def test_update_template_diff_changed_add(self):
|
||||||
|
tmpl = {'Type': 'Foo'}
|
||||||
|
update_snippet = {'Type': 'Foo', 'Metadata': {'foo': 123}}
|
||||||
|
res = resource.GenericResource('test_resource', tmpl, self.stack)
|
||||||
|
res.update_allowed_keys = ['Metadata']
|
||||||
|
diff = res.update_template_diff(json_snippet=update_snippet)
|
||||||
|
self.assertEqual(diff, {'Metadata': {'foo': 123}})
|
||||||
|
|
||||||
|
def test_update_template_diff_changed_remove(self):
|
||||||
|
tmpl = {'Type': 'Foo', 'Metadata': {'foo': 123}}
|
||||||
|
update_snippet = {'Type': 'Foo'}
|
||||||
|
res = resource.GenericResource('test_resource', tmpl, self.stack)
|
||||||
|
res.update_allowed_keys = ['Metadata']
|
||||||
|
diff = res.update_template_diff(json_snippet=update_snippet)
|
||||||
|
self.assertEqual(diff, {'Metadata': None})
|
||||||
|
|
||||||
|
|
||||||
@attr(tag=['unit', 'resource'])
|
@attr(tag=['unit', 'resource'])
|
||||||
@attr(speed='fast')
|
@attr(speed='fast')
|
||||||
|
|
Loading…
Reference in New Issue