diff options
author | Zane Bitter <zbitter@redhat.com> | 2014-04-01 11:04:10 -0400 |
---|---|---|
committer | Steve Baker <sbaker@redhat.com> | 2014-04-09 07:35:37 +1200 |
commit | 878554cb29f3524fc256c415f49fa8e0611fb996 (patch) | |
tree | 79c8f725f20f976fabe548222c6e668be52590a7 /heat | |
parent | ce5d1ff18bbbd3fee411ed4c86d070dcc3f3b64b (diff) | |
download | heat-878554cb29f3524fc256c415f49fa8e0611fb996.tar.gz |
Add a resource_facade intrinsic function to HOT
Add a native version of the function, rather than continue to rely on
Fn::ResourceFacade from the Heat-flavoured-cfn templates.
Closes-bug: #1299205
Change-Id: Iee118aeaa72d59e4d6a27ed487b99e9aba9779cd
Diffstat (limited to 'heat')
-rw-r--r-- | heat/engine/cfn/functions.py | 4 | ||||
-rw-r--r-- | heat/engine/hot/functions.py | 21 | ||||
-rw-r--r-- | heat/tests/test_hot.py | 72 |
3 files changed, 95 insertions, 2 deletions
diff --git a/heat/engine/cfn/functions.py b/heat/engine/cfn/functions.py index f21975a95..1bfbace5b 100644 --- a/heat/engine/cfn/functions.py +++ b/heat/engine/cfn/functions.py @@ -527,10 +527,10 @@ class ResourceFacade(function.Function): if attr == self.METADATA: return self.stack.parent_resource.metadata elif attr == self.UPDATE_POLICY: - up = self.stack.parent_resource.t.get(attr, {}) + up = self.stack.parent_resource.t.get('UpdatePolicy', {}) return function.resolve(up) elif attr == self.DELETION_POLICY: - dp = self.stack.parent_resource.t.get(attr, 'Delete') + dp = self.stack.parent_resource.t.get('DeletionPolicy', 'Delete') return function.resolve(dp) diff --git a/heat/engine/hot/functions.py b/heat/engine/hot/functions.py index 470413b94..6c6fb87a0 100644 --- a/heat/engine/hot/functions.py +++ b/heat/engine/hot/functions.py @@ -203,6 +203,26 @@ class GetFile(function.Function): return f +class ResourceFacade(cfn_funcs.ResourceFacade): + ''' + A function for obtaining data from the facade resource from within the + corresponding provider template. + + Takes the form:: + + resource_facade: <attribute_type> + + where the valid attribute types are "metadata", "deletion_policy" and + "update_policy". + ''' + + _RESOURCE_ATTRIBUTES = ( + METADATA, DELETION_POLICY, UPDATE_POLICY, + ) = ( + 'metadata', 'deletion_policy', 'update_policy' + ) + + def function_mapping(version_key, version): if version_key != 'heat_template_version': return {} @@ -221,6 +241,7 @@ def function_mapping(version_key, version): 'Fn::Replace': cfn_funcs.Replace, 'Fn::Base64': cfn_funcs.Base64, 'Fn::MemberListToMap': cfn_funcs.MemberListToMap, + 'resource_facade': ResourceFacade, 'Fn::ResourceFacade': cfn_funcs.ResourceFacade, 'get_file': GetFile, } diff --git a/heat/tests/test_hot.py b/heat/tests/test_hot.py index f38c922f8..7946f9e39 100644 --- a/heat/tests/test_hot.py +++ b/heat/tests/test_hot.py @@ -512,6 +512,78 @@ class HOTemplateTest(HeatTestCase): observed = parsed_tmpl.version self.assertEqual(expected, observed) + def test_resource_facade(self): + metadata_snippet = {'resource_facade': 'metadata'} + deletion_policy_snippet = {'resource_facade': 'deletion_policy'} + update_policy_snippet = {'resource_facade': 'update_policy'} + + class DummyClass(object): + pass + parent_resource = DummyClass() + parent_resource.metadata = {"foo": "bar"} + parent_resource.t = {'DeletionPolicy': 'Retain', + 'UpdatePolicy': {"blarg": "wibble"}} + parent_resource.stack = parser.Stack(utils.dummy_context(), + 'toplevel_stack', + parser.Template({})) + stack = parser.Stack(utils.dummy_context(), 'test_stack', + parser.Template(hot_tpl_empty), + parent_resource=parent_resource) + self.assertEqual({"foo": "bar"}, + self.resolve(metadata_snippet, stack.t, stack)) + self.assertEqual('Retain', + self.resolve(deletion_policy_snippet, stack.t, stack)) + self.assertEqual({"blarg": "wibble"}, + self.resolve(update_policy_snippet, stack.t, stack)) + + def test_resource_facade_function(self): + deletion_policy_snippet = {'resource_facade': 'deletion_policy'} + + class DummyClass(object): + pass + parent_resource = DummyClass() + parent_resource.metadata = {"foo": "bar"} + parent_resource.stack = parser.Stack(utils.dummy_context(), + 'toplevel_stack', + parser.Template({})) + parent_snippet = {'DeletionPolicy': {'Fn::Join': ['eta', + ['R', 'in']]}} + parent_tmpl = parent_resource.stack.t.parse(parent_resource.stack, + parent_snippet) + parent_resource.t = parent_tmpl + + stack = parser.Stack(utils.dummy_context(), 'test_stack', + parser.Template(hot_tpl_empty), + parent_resource=parent_resource) + self.assertEqual('Retain', + self.resolve(deletion_policy_snippet, stack.t, stack)) + + def test_resource_facade_invalid_arg(self): + snippet = {'resource_facade': 'wibble'} + stack = parser.Stack(utils.dummy_context(), 'test_stack', + parser.Template(hot_tpl_empty)) + error = self.assertRaises(ValueError, + self.resolve, + snippet, + stack.t, stack) + self.assertIn(snippet.keys()[0], str(error)) + + def test_resource_facade_missing_deletion_policy(self): + snippet = {'resource_facade': 'deletion_policy'} + + class DummyClass(object): + pass + parent_resource = DummyClass() + parent_resource.metadata = {"foo": "bar"} + parent_resource.t = {} + parent_resource.stack = parser.Stack(utils.dummy_context(), + 'toplevel_stack', + parser.Template({})) + stack = parser.Stack(utils.dummy_context(), 'test_stack', + parser.Template(hot_tpl_empty), + parent_resource=parent_resource) + self.assertEqual('Delete', self.resolve(snippet, stack.t, stack)) + class StackTest(test_parser.StackTest): """Test stack function when stack was created from HOT template.""" |