Add an add_output() method to Template

This helps with dynamically building templates, and is similar to the
add_resource method.

Change-Id: I51ce5c913438083d6d43eb6d8a8bf55cfa8ea3ee
Related-Bug: #1660831
This commit is contained in:
Zane Bitter 2017-06-29 09:07:02 -04:00
parent 91561ead32
commit 4250958a03
6 changed files with 66 additions and 0 deletions

View File

@ -75,6 +75,9 @@ class CfnTemplateBase(template_common.CommonTemplate):
'deletion_policy': RES_DELETION_POLICY, 'deletion_policy': RES_DELETION_POLICY,
'update_policy': RES_UPDATE_POLICY} 'update_policy': RES_UPDATE_POLICY}
HOT_TO_CFN_OUTPUT_ATTRS = {'description': OUTPUT_DESCRIPTION,
'value': OUTPUT_VALUE}
def __getitem__(self, section): def __getitem__(self, section):
"""Get the relevant section in the template.""" """Get the relevant section in the template."""
if section not in self.SECTIONS: if section not in self.SECTIONS:
@ -157,6 +160,15 @@ class CfnTemplateBase(template_common.CommonTemplate):
self.t[self.RESOURCES] = {} self.t[self.RESOURCES] = {}
self.t[self.RESOURCES][name] = cfn_tmpl self.t[self.RESOURCES][name] = cfn_tmpl
def add_output(self, definition):
hot_op = definition.render_hot()
cfn_op = dict((self.HOT_TO_CFN_OUTPUT_ATTRS[k], v)
for k, v in hot_op.items())
if self.t.get(self.OUTPUTS) is None:
self.t[self.OUTPUTS] = {}
self.t[self.OUTPUTS][definition.name] = cfn_op
class CfnTemplate(CfnTemplateBase): class CfnTemplate(CfnTemplateBase):

View File

@ -268,6 +268,11 @@ class HOTemplate20130523(template_common.CommonTemplate):
self.t[self.RESOURCES] = {} self.t[self.RESOURCES] = {}
self.t[self.RESOURCES][name] = definition.render_hot() self.t[self.RESOURCES][name] = definition.render_hot()
def add_output(self, definition):
if self.t.get(self.OUTPUTS) is None:
self.t[self.OUTPUTS] = {}
self.t[self.OUTPUTS][definition.name] = definition.render_hot()
class HOTemplate20141016(HOTemplate20130523): class HOTemplate20141016(HOTemplate20130523):
functions = { functions = {

View File

@ -11,6 +11,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import copy
import six import six
from heat.engine import function from heat.engine import function
@ -49,3 +50,10 @@ class OutputDefinition(object):
return 'No description given' return 'No description given'
return six.text_type(self._description) return six.text_type(self._description)
def render_hot(self):
def items():
if self._description is not None:
yield 'description', self._description
yield 'value', copy.deepcopy(self._value)
return dict(items())

View File

@ -255,6 +255,13 @@ class Template(collections.Mapping):
""" """
pass pass
def add_output(self, definition):
"""Add an output to the template.
The output is passed as a OutputDefinition object.
"""
raise NotImplementedError
def remove_resource(self, name): def remove_resource(self, name):
"""Remove a resource from the template.""" """Remove a resource from the template."""
self.t.get(self.RESOURCES, {}).pop(name) self.t.get(self.RESOURCES, {}).pop(name)

View File

@ -1857,6 +1857,23 @@ conditions:
self.assertEqual(hot_tpl['resources'], empty.t['resources']) self.assertEqual(hot_tpl['resources'], empty.t['resources'])
def test_add_output(self):
hot_tpl = template_format.parse('''
heat_template_version: 2013-05-23
outputs:
output1:
description: An output
value: bar
''')
source = template.Template(hot_tpl)
empty = template.Template(copy.deepcopy(hot_tpl_empty))
stack = parser.Stack(utils.dummy_context(), 'test_stack', source)
for defn in six.itervalues(source.outputs(stack)):
empty.add_output(defn)
self.assertEqual(hot_tpl['outputs'], empty.t['outputs'])
def test_filter(self): def test_filter(self):
snippet = {'filter': [[None], [1, None, 4, 2, None]]} snippet = {'filter': [[None], [1, None, 4, 2, None]]}
tmpl = template.Template(hot_ocata_tpl_empty) tmpl = template.Template(hot_ocata_tpl_empty)

View File

@ -1429,6 +1429,23 @@ class TemplateTest(common.HeatTestCase):
self.assertEqual(cfn_tpl['Resources'], empty.t['Resources']) self.assertEqual(cfn_tpl['Resources'], empty.t['Resources'])
def test_add_output(self):
cfn_tpl = template_format.parse('''
AWSTemplateFormatVersion: 2010-09-09
Outputs:
output1:
Description: An output
Value: foo
''')
source = template.Template(cfn_tpl)
empty = template.Template(copy.deepcopy(empty_template))
stk = stack.Stack(self.ctx, 'test_stack', source)
for defn in six.itervalues(source.outputs(stk)):
empty.add_output(defn)
self.assertEqual(cfn_tpl['Outputs'], empty.t['Outputs'])
def test_create_empty_template_default_version(self): def test_create_empty_template_default_version(self):
empty_template = template.Template.create_empty_template() empty_template = template.Template.create_empty_template()
self.assertEqual(hot_t.HOTemplate20150430, empty_template.__class__) self.assertEqual(hot_t.HOTemplate20150430, empty_template.__class__)