Skip to content

Commit

Permalink
[Resolve #1336] Add bugfix in Stack Differ (#1337)
Browse files Browse the repository at this point in the history
In the case of a parameter dictionary that contains nulls (None) the
Boto3 library has been found to take care of converting None to "". This
means that launching such a stack in CloudFormation with a parameter
dict containing params set to None works fine, whereas this differ
raised an exception when it tried to strip newlines.

This patch stops newlines being stripped in the case of a parameter that
is set to None.
  • Loading branch information
alexharv074 committed May 15, 2023
1 parent dcae1a9 commit cfb73b0
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
7 changes: 7 additions & 0 deletions sceptre/diffing/stack_differ.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ def _extract_parameters_from_generated_stack(self, stack: Stack) -> dict:
"""
formatted_parameters = {}
for key, value in stack.parameters.items():
# When boto3 receives "None" for a cloudformation parameter, it treats it as if the
# value is not passed at all. To be consistent in our diffing, we need to skip Nones
# altogether.
if value is None:
continue

if isinstance(value, list):
value = ",".join(item.rstrip("\n") for item in value)
formatted_parameters[key] = value.rstrip("\n")
Expand Down Expand Up @@ -219,6 +225,7 @@ def _handle_special_parameter_situations(
self._remove_deployed_default_parameters_that_arent_passed(
deployed_template_summary, generated_config, deployed_config
)

if not self.show_no_echo:
# We don't actually want to show parameters Sceptre is passing that the local template
# marks as NoEcho parameters (unless show_no_echo is set to true). Therefore those
Expand Down
15 changes: 13 additions & 2 deletions tests/test_diffing/test_stack_differ.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def get_local_template_summary(self):
def expected_generated_config(self):
return StackConfiguration(
stack_name=self.external_name,
parameters=self.parameters_on_stack_config,
parameters=deepcopy(self.parameters_on_stack_config),
stack_tags=deepcopy(self.tags),
notifications=deepcopy(self.notifications),
cloudformation_service_role=self.cloudformation_service_role,
Expand All @@ -168,7 +168,7 @@ def expected_generated_config(self):
def expected_deployed_config(self):
return StackConfiguration(
stack_name=self.external_name,
parameters=self.deployed_parameters,
parameters=deepcopy(self.deployed_parameters),
stack_tags=deepcopy(self.deployed_tags),
notifications=deepcopy(self.deployed_notification_arns),
cloudformation_service_role=self.deployed_cloudformation_service_role,
Expand Down Expand Up @@ -332,6 +332,17 @@ def test_diff__deployed_stack_has_default_values__passes_different_value__compar
self.expected_deployed_config, self.expected_generated_config
)

def test_diff__generated_stack_has_none_for_parameter_value__its_treated_like_its_not_specified(
self,
):
self.parameters_on_stack_config["new"] = None
expected_generated = self.expected_generated_config
del expected_generated.parameters["new"]
self.differ.diff(self.actions)
self.command_capturer.compare_stack_configurations.assert_called_with(
self.expected_deployed_config, expected_generated
)

def test_diff__stack_exists_with_same_config_but_template_does_not__compares_identical_configs(
self,
):
Expand Down

0 comments on commit cfb73b0

Please sign in to comment.