summaryrefslogtreecommitdiff
path: root/heat
diff options
context:
space:
mode:
authorZane Bitter <zbitter@redhat.com>2014-04-01 11:04:10 -0400
committerSteve Baker <sbaker@redhat.com>2014-04-09 07:35:37 +1200
commit878554cb29f3524fc256c415f49fa8e0611fb996 (patch)
tree79c8f725f20f976fabe548222c6e668be52590a7 /heat
parentce5d1ff18bbbd3fee411ed4c86d070dcc3f3b64b (diff)
downloadheat-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.py4
-rw-r--r--heat/engine/hot/functions.py21
-rw-r--r--heat/tests/test_hot.py72
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."""