Skip to content

Commit f90216b

Browse files
authored
Fix an issue with SSM params for ForEach (#3294)
* Fix an issue with SSM params for ForEach * Fix an issue with regional schema validation on RDS
1 parent 1439a97 commit f90216b

File tree

4 files changed

+58
-0
lines changed

4 files changed

+58
-0
lines changed

src/cfnlint/rules/resources/rds/DbClusterInstanceClassEnum.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,13 @@ def __init__(self) -> None:
2525
"dbclusterinstanceclass_enum.json",
2626
),
2727
)
28+
29+
def validate(self, validator, keywords, instance, schema):
30+
# RDS pricing schemas are based on values
31+
validator = validator.evolve(
32+
context=validator.context.evolve(
33+
functions=[],
34+
)
35+
)
36+
37+
yield from super().validate(validator, keywords, instance, schema)

src/cfnlint/rules/resources/rds/DbInstanceDbInstanceClassEnum.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ def validate(self, validator, keywords, instance, schema):
3030
if not validator.is_type(instance, "object"):
3131
return
3232

33+
validator = validator.evolve(
34+
context=validator.context.evolve(
35+
functions=[],
36+
)
37+
)
38+
3339
if validator.is_type(instance.get("Engine"), "string"):
3440
instance["Engine"] = instance["Engine"].lower()
3541

src/cfnlint/template/transforms/_language_extensions.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def language_extension(cfn: Any) -> TransformResult:
5151
try:
5252
return transform.transform(cfn)
5353
except (_ValueError, _TypeError, _ResolveError) as e:
54+
LOGGER.debug(e, exc_info=True)
5455
# pylint: disable=import-outside-toplevel
5556
from cfnlint.match import Match # pylint: disable=cyclic-import
5657
from cfnlint.rules.TransformError import ( # pylint: disable=cyclic-import
@@ -83,6 +84,7 @@ def language_extension(cfn: Any) -> TransformResult:
8384
)
8485
], None
8586
except Exception as e: # pylint: disable=broad-exception-caught
87+
LOGGER.debug(e, exc_info=True)
8688
# pylint: disable=import-outside-toplevel
8789
from cfnlint.match import Match # pylint: disable=cyclic-import
8890
from cfnlint.rules.TransformError import ( # pylint: disable=cyclic-import
@@ -375,6 +377,15 @@ def value(
375377
except _ResolveError as e:
376378
if len(self._map) == 4 and default_on_resolver_failure:
377379
return self._map[3].value(cfn, params, only_params)
380+
# no default value and map 1 exists
381+
try:
382+
for _, v in mapping.get(
383+
t_map[1].value(cfn, params, only_params), {}
384+
).items():
385+
if isinstance(v, list):
386+
return v
387+
except _ResolveError:
388+
pass
378389
raise _ResolveError("Can't resolve Fn::FindInMap", self._obj) from e
379390

380391
if len(self._map) == 4 and default_on_resolver_failure:
@@ -453,6 +464,8 @@ def value(
453464
if not p:
454465
raise _ResolveError("Can't resolve Fn::Ref", self._obj)
455466
t = p.get("Type", "String")
467+
if t.startswith("AWS::SSM::Parameter"):
468+
raise _ResolveError("Can't resolve Fn::Ref", self._obj)
456469
default = p.get("Default")
457470
if default:
458471
if "List" in t:

test/unit/module/template/transforms/test_language_extensions.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ def setUp(self) -> None:
105105
"AccountIds": {
106106
"Type": "CommaDelimitedList",
107107
},
108+
"SSMParameter": {
109+
"Type": "AWS::SSM::Parameter::Value<String>",
110+
"Default": "/global/account/accounttype",
111+
"AllowedValues": ["/global/account/accounttype"],
112+
},
108113
},
109114
}
110115
)
@@ -154,6 +159,10 @@ def test_ref(self):
154159
],
155160
)
156161

162+
fe = _ForEachValue.create({"Ref": "SSMParameter"})
163+
with self.assertRaises(_ResolveError):
164+
fe.value(self.cfn)
165+
157166

158167
class TestFindInMap(TestCase):
159168
def setUp(self) -> None:
@@ -174,6 +183,13 @@ def setUp(self) -> None:
174183
"Mappings": {
175184
"Bucket": {"Production": {"Names": ["foo", "bar"]}},
176185
"AnotherBucket": {"Production": {"Names": ["a", "b"]}},
186+
"Config": {
187+
"DBInstances": {
188+
"Development": "1",
189+
"Stage": ["1", "2"],
190+
"Production": ["1", "2", "3"],
191+
}
192+
},
177193
},
178194
}
179195
)
@@ -273,6 +289,19 @@ def test_find_in_map_values_without_default(self):
273289
with self.assertRaises(_ResolveError):
274290
map.value(self.cfn, None, False, False)
275291

292+
def test_find_in_map_values_without_default_resolve_error(self):
293+
map = _ForEachValueFnFindInMap(
294+
"a", ["Bucket", "Production", {"Ref": "SSMParameter"}]
295+
)
296+
297+
self.assertEqual(map.value(self.cfn, None, False, True), ["foo", "bar"])
298+
299+
map = _ForEachValueFnFindInMap(
300+
"a", ["Config", "DBInstances", {"Ref": "SSMParameter"}]
301+
)
302+
303+
self.assertEqual(map.value(self.cfn, None, False, True), ["1", "2"])
304+
276305
def test_mapping_not_found(self):
277306
map = _ForEachValueFnFindInMap(
278307
"a", ["Foo", {"Ref": "Foo"}, "Key", {"DefaultValue": "bar"}]

0 commit comments

Comments
 (0)