Skip to content

Commit fdc433a

Browse files
authored
Merge pull request #541 from troyready/fix_diff_with_yaml_template
fix diff with local yaml templates
2 parents 7ae24af + 1083a58 commit fdc433a

3 files changed

Lines changed: 120 additions & 22 deletions

File tree

stacker/actions/diff.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,27 @@ def diff_parameters(old_params, new_params):
143143
return diff
144144

145145

146+
def normalize_json(template):
147+
"""Normalize our template for diffing.
148+
149+
Args:
150+
template(str): string representing the template
151+
152+
Returns:
153+
list: json representation of the parameters
154+
"""
155+
obj = parse_cloudformation_template(template)
156+
json_str = json.dumps(obj, sort_keys=True, indent=4)
157+
result = []
158+
lines = json_str.split("\n")
159+
for line in lines:
160+
result.append(line + "\n")
161+
return result
162+
163+
146164
def print_stack_changes(stack_name, new_stack, old_stack, new_params,
147165
old_params):
148-
"""Prints out the paramters (if changed) and stack diff"""
166+
"""Prints out the parameters (if changed) and stack diff"""
149167
from_file = "old_%s" % (stack_name,)
150168
to_file = "new_%s" % (stack_name,)
151169
lines = difflib.context_diff(
@@ -156,9 +174,10 @@ def print_stack_changes(stack_name, new_stack, old_stack, new_params,
156174
template_changes = list(lines)
157175
if not template_changes:
158176
print "*** No changes to template ***"
159-
else:
160-
param_diffs = diff_parameters(old_params, new_params)
177+
param_diffs = diff_parameters(old_params, new_params)
178+
if param_diffs:
161179
print format_params_diff(param_diffs)
180+
if template_changes:
162181
print "".join(template_changes)
163182

164183

@@ -174,23 +193,6 @@ class Action(build.Action):
174193
config.
175194
"""
176195

177-
def _normalize_json(self, template):
178-
"""Normalizes our template for diffing
179-
180-
Args:
181-
template(str): json string representing the template
182-
183-
Returns:
184-
list: json representation of the parameters
185-
"""
186-
obj = json.loads(template)
187-
json_str = json.dumps(obj, sort_keys=True, indent=4)
188-
result = []
189-
lines = json_str.split("\n")
190-
for line in lines:
191-
result.append(line + "\n")
192-
return result
193-
194196
def _print_new_stack(self, stack, parameters):
195197
"""Prints out the parameters & stack contents of a new stack"""
196198
print "New template parameters:"
@@ -229,7 +231,7 @@ def _diff_stack(self, stack, **kwargs):
229231
for p in parameters:
230232
new_params[p['ParameterKey']] = p['ParameterValue']
231233
new_template = stack.blueprint.rendered
232-
new_stack = self._normalize_json(new_template)
234+
new_stack = normalize_json(new_template)
233235

234236
print "============== Stack: %s ==============" % (stack.name,)
235237
# If this is a completely new template dump our params & stack
@@ -244,7 +246,7 @@ def _diff_stack(self, stack, **kwargs):
244246
# ->
245247
# AWSTemplateFormatVersion: "2010-09-09"
246248
old_template = parse_cloudformation_template(old_template)
247-
old_stack = self._normalize_json(
249+
old_stack = normalize_json(
248250
json.dumps(old_template,
249251
sort_keys=True,
250252
indent=4)

stacker/tests/actions/test_diff.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import os
12
import unittest
23

34
from operator import attrgetter
45
from stacker.actions.diff import (
56
diff_dictionaries,
67
diff_parameters,
8+
normalize_json,
79
DictValue
810
)
911

@@ -81,3 +83,58 @@ def test_diff_parameters_no_changes(self):
8183

8284
param_diffs = diff_parameters(old_params, new_params)
8385
self.assertEquals(param_diffs, [])
86+
87+
88+
class TestDiffFunctions(unittest.TestCase):
89+
"""Test functions in diff."""
90+
91+
def test_normalize_json(self):
92+
"""Ensure normalize_json parses yaml correctly."""
93+
with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), # noqa
94+
'fixtures',
95+
'cfn_template.yaml'), 'r') as yamlfile:
96+
template = yamlfile.read()
97+
normalized_template = [
98+
'{\n',
99+
' "AWSTemplateFormatVersion": "2010-09-09", \n',
100+
' "Description": "TestTemplate", \n',
101+
' "Outputs": {\n',
102+
' "DummyId": {\n',
103+
' "Value": "dummy-1234"\n',
104+
' }\n',
105+
' }, \n',
106+
' "Parameters": {\n',
107+
' "Param1": {\n',
108+
' "Type": "String"\n',
109+
' }, \n',
110+
' "Param2": {\n',
111+
' "Default": "default", \n',
112+
' "Type": "CommaDelimitedList"\n',
113+
' }\n',
114+
' }, \n',
115+
' "Resources": {\n',
116+
' "Bucket": {\n',
117+
' "Properties": {\n',
118+
' "BucketName": {\n',
119+
' "Fn::Join": [\n',
120+
' "-", \n',
121+
' [\n',
122+
' {\n',
123+
' "Ref": "AWS::StackName"\n',
124+
' }, \n',
125+
' {\n',
126+
' "Ref": "AWS::Region"\n',
127+
' }\n',
128+
' ]\n',
129+
' ]\n',
130+
' }\n',
131+
' }, \n',
132+
' "Type": "AWS::S3::Bucket"\n',
133+
' }, \n',
134+
' "Dummy": {\n',
135+
' "Type": "AWS::CloudFormation::WaitConditionHandle"\n',
136+
' }\n',
137+
' }\n',
138+
'}\n'
139+
]
140+
self.assertEquals(normalized_template, normalize_json(template))

tests/suite.bats

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,45 @@ EOF
713713
assert_has_line "${STACKER_NAMESPACE}-vpc: complete (stack destroyed)"
714714
}
715715

716+
@test "stacker diff - raw template" {
717+
needs_aws
718+
719+
config1() {
720+
cat <<EOF
721+
namespace: ${STACKER_NAMESPACE}
722+
stacks:
723+
- name: vpc
724+
template_path: ../stacker/tests/fixtures/cfn_template.yaml
725+
variables:
726+
Param1: foobar
727+
EOF
728+
}
729+
730+
config2() {
731+
cat <<EOF
732+
namespace: ${STACKER_NAMESPACE}
733+
stacks:
734+
- name: vpc
735+
template_path: ../stacker/tests/fixtures/cfn_template.yaml
736+
variables:
737+
Param1: newbar
738+
EOF
739+
}
740+
741+
teardown() {
742+
stacker destroy --force <(config1)
743+
}
744+
745+
# Create the new stacks.
746+
stacker build <(config1)
747+
assert "$status" -eq 0
748+
749+
stacker diff <(config2)
750+
assert "$status" -eq 0
751+
assert_has_line "\-Param1 = foobar"
752+
assert_has_line "+Param1 = newbar"
753+
}
754+
716755
@test "stacker build - no parallelism" {
717756
needs_aws
718757

0 commit comments

Comments
 (0)