Skip to content

Commit b43492e

Browse files
committed
blueprints: raw: handle Troposphere objects in Jinja templates
1 parent 75e3a44 commit b43492e

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

stacker/blueprints/raw.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import os
99
import sys
1010

11-
from jinja2 import Template
11+
from jinja2 import Environment
1212

1313
from ..util import parse_cloudformation_template
1414
from ..exceptions import InvalidConfig, UnresolvedVariable
@@ -196,17 +196,25 @@ def rendered(self):
196196
if not self._rendered:
197197
template_path = get_template_path(self.raw_template_path)
198198
if template_path:
199-
with open(template_path, 'r') as template:
199+
with open(template_path, 'r') as template_file:
200+
template_data = template_file.read()
201+
200202
if len(os.path.splitext(template_path)) == 2 and (
201203
os.path.splitext(template_path)[1] == '.j2'):
202-
self._rendered = Template(template.read()).render(
204+
205+
ext_name = ('stacker.blueprints.templating'
206+
'.TroposphereFnHandlerExtension')
207+
environment = Environment(extensions=[ext_name])
208+
template = environment.from_string(template_data)
209+
210+
self._rendered = template.render(
203211
context=self.context,
204212
mappings=self.mappings,
205213
name=self.name,
206214
variables=self.resolved_variables
207215
)
208216
else:
209-
self._rendered = template.read()
217+
self._rendered = template_data
210218
else:
211219
raise InvalidConfig(
212220
'Could not find template %s' % self.raw_template_path

stacker/blueprints/templating.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from __future__ import print_function
2+
from __future__ import division
3+
from __future__ import absolute_import
4+
import json
5+
6+
from jinja2.lexer import Token
7+
from jinja2.ext import Extension
8+
from troposphere import AWSHelperFn
9+
10+
11+
def render_troposphere_fn(obj):
12+
if isinstance(obj, AWSHelperFn):
13+
return json.dumps(obj.to_dict())
14+
15+
return obj
16+
17+
18+
class TroposphereFnHandlerExtension(Extension):
19+
def __init__(self, environment):
20+
super(TroposphereFnHandlerExtension, self).__init__(environment)
21+
environment.filters['render_troposphere_fn'] = render_troposphere_fn
22+
23+
def filter_stream(self, stream):
24+
for token in stream:
25+
if token.type == 'variable_end':
26+
yield Token(token.lineno, 'pipe', '|')
27+
yield Token(token.lineno, 'name', 'render_troposphere_fn')
28+
29+
yield token

stacker/tests/blueprints/test_raw.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import json
66
import unittest
77

8+
import troposphere
89
from mock import MagicMock
910

1011
from stacker.blueprints.raw import (
@@ -144,6 +145,9 @@ def test_j2_to_json(self):
144145
"Outputs": {
145146
"DummyId": {
146147
"Value": "dummy-bar-param1val-foo-1234"
148+
},
149+
"DummyTroposphereFn": {
150+
"Value": {"Ref": "AWS::Region"}
147151
}
148152
}
149153
},
@@ -156,13 +160,15 @@ def test_j2_to_json(self):
156160
extra_config_args={'stacks': [{'name': 'stack1',
157161
'template_path': 'unused',
158162
'variables': {
159-
'Param1': 'param1val',
160-
'bar': 'foo'}}]},
163+
'Param1': '',
164+
'bar': '',
165+
'region': ''}}]},
161166
environment={'foo': 'bar'}),
162167
raw_template_path=RAW_J2_TEMPLATE_PATH
163168
)
164169
blueprint.resolve_variables([Variable("Param1", "param1val"),
165-
Variable("bar", "foo")])
170+
Variable("bar", "foo"),
171+
Variable("region", troposphere.Region)])
166172
self.assertEqual(
167173
expected_json,
168174
blueprint.to_json()

stacker/tests/fixtures/cfn_template.json.j2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
"Outputs": {
1919
"DummyId": {
2020
"Value": "dummy-{{ context.environment.foo }}-{{ variables.Param1 }}-{{ variables.bar }}-1234"
21+
},
22+
"DummyTroposphereFn": {
23+
"Value": {{ variables.region }}
2124
}
2225
}
2326
}

0 commit comments

Comments
 (0)