Skip to content

Commit

Permalink
walk FindInMap to pass mapping in resolution failure (#3131)
Browse files Browse the repository at this point in the history
  • Loading branch information
kddejong authored Apr 4, 2024
1 parent 8d1343b commit c445a02
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/cfnlint/template/transforms/_language_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def _walk(self, item: Any, params: MutableMapping[str, Any], cfn: Any):
elif k == "Fn::FindInMap":
try:
mapping = _ForEachValueFnFindInMap(get_hash(v), v)
map_value = mapping.value(cfn, params, True)
map_value = mapping.value(cfn, params, True, False)
# if we get None this means its all strings but couldn't be resolved
# we will pass this forward
if map_value is None:
Expand Down Expand Up @@ -298,6 +298,7 @@ def value(
cfn: Any,
params: Optional[Mapping[str, Any]] = None,
only_params: bool = False,
default_on_resolver_failure: bool = True,
) -> Any:
if params is None:
params = {}
Expand Down Expand Up @@ -361,11 +362,11 @@ def value(
t_map[2].value(cfn, params, only_params)
)
except _ResolveError as e:
if len(self._map) == 4:
if len(self._map) == 4 and default_on_resolver_failure:
return self._map[3].value(cfn, params, only_params)
raise _ResolveError("Can't resolve Fn::FindInMap", self._obj) from e

if len(self._map) == 4:
if len(self._map) == 4 and default_on_resolver_failure:
return self._map[3].value(cfn, params, only_params)
raise _ResolveError("Can't resolve Fn::FindInMap", self._obj)

Expand Down
26 changes: 26 additions & 0 deletions test/unit/module/template/transforms/test_language_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,32 @@ def test_bad_mappings(self):
with self.assertRaises(_ValueError):
_ForEachValueFnFindInMap("", ["foo"])

def test_find_in_map_values_with_default(self):
map = _ForEachValueFnFindInMap(
"a", ["Bucket", {"Ref": "Foo"}, "Key", {"DefaultValue": "bar"}]
)

self.assertEqual(map.value(self.cfn, None, False, True), "bar")
with self.assertRaises(_ResolveError):
map.value(self.cfn, None, False, False)

def test_find_in_map_values_without_default(self):
map = _ForEachValueFnFindInMap("a", ["Bucket", {"Ref": "Foo"}, "Key"])

with self.assertRaises(_ResolveError):
self.assertEqual(map.value(self.cfn, None, False, True), "bar")
with self.assertRaises(_ResolveError):
map.value(self.cfn, None, False, False)

def test_mapping_not_found(self):
map = _ForEachValueFnFindInMap(
"a", ["Foo", {"Ref": "Foo"}, "Key", {"DefaultValue": "bar"}]
)

self.assertEqual(map.value(self.cfn, None, False, True), "bar")
with self.assertRaises(_ResolveError):
map.value(self.cfn, None, False, False)

def test_two_mappings(self):
template_obj = deepcopy(self.template_obj)
template_obj["Mappings"]["Foo"] = {"Bar": {"Key": ["a", "b"]}}
Expand Down

0 comments on commit c445a02

Please sign in to comment.