From 38e42cf6beb0930c063ac917dd2258c881150848 Mon Sep 17 00:00:00 2001 From: Jerry Chen Date: Sun, 22 Oct 2023 07:09:06 +1100 Subject: [PATCH] Fix Parameters.validate incorrect validate for CommaDelimitedList (#2191) --- tests/test_parameters.py | 28 ++++++++++++++++++++++++++++ troposphere/__init__.py | 22 ++++++++++++++++++---- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/tests/test_parameters.py b/tests/test_parameters.py index 1c3d98cf9..dc28b20fd 100644 --- a/tests/test_parameters.py +++ b/tests/test_parameters.py @@ -17,5 +17,33 @@ def test_ref_can_be_requested(self): self.assertDictEqual(reference.data, {"Ref": "title"}) +class TestParameterValidator(unittest.TestCase): + def test_allowed_pattern_for_number(self): + with self.assertRaises(ValueError): + Parameter("Foo", Type="Number", AllowedPattern="^[a-zA-Z0-9]*$").validate() + + def test_allowed_pattern_for_comma_delimited_list_and_string(self): + Parameter( + "Foo", + Type="CommaDelimitedList", + AllowedPattern="^[A-Z]{2}$", + Default="", + ).validate() + + Parameter( + "Foo", + Type="String", + AllowedPattern="^[A-Z]{2}$", + Default="", + ).validate() + + def test_aws_specific_type(self): + Parameter( + "Foo", + Type="AWS::EC2::KeyPair::KeyName", + Default="", + ).validate() + + if __name__ == "__main__": unittest.main() diff --git a/troposphere/__init__.py b/troposphere/__init__.py index 05b1592c9..db483c112 100644 --- a/troposphere/__init__.py +++ b/troposphere/__init__.py @@ -1011,6 +1011,7 @@ def add_to_template(self) -> None: class Parameter(AWSDeclaration): STRING_PROPERTIES = ["AllowedPattern", "MaxLength", "MinLength"] NUMBER_PROPERTIES = ["MaxValue", "MinValue"] + COMMA_DELIMITED_LIST = ["AllowedPattern"] props = { "Type": (str, True), "Default": ((str, int, float), False), @@ -1076,15 +1077,28 @@ def check_type(t: type, v: Any) -> bool: if not any(check_type(x, d) for x in allowed): raise ValueError(error_str % (param_type, type(d), dlist)) - if self.properties["Type"] != "String": - for p in self.STRING_PROPERTIES: + if self.properties["Type"] == "String": + not_allowed = [ + p for p in self.COMMA_DELIMITED_LIST if p not in self.STRING_PROPERTIES + ] + self.NUMBER_PROPERTIES + for p in not_allowed: if p in self.properties: raise ValueError( "%s can only be used with parameters of " "the String type." % p ) - if self.properties["Type"] != "Number": - for p in self.NUMBER_PROPERTIES: + if self.properties["Type"] == "Number": + for p in list(set(self.STRING_PROPERTIES + self.COMMA_DELIMITED_LIST)): if p in self.properties: raise ValueError( "%s can only be used with parameters of " "the Number type." % p ) + if self.properties["Type"] == "CommaDelimitedList": + not_allowed = [ + p for p in self.STRING_PROPERTIES if p not in self.COMMA_DELIMITED_LIST + ] + self.NUMBER_PROPERTIES + for p in not_allowed: + if p in self.properties: + raise ValueError( + "%s can only be used with parameters of " + "the CommaDelimitedList type." % p + )