""" Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: MIT-0 """ from cfnlint.languageExtensions import LanguageExtensions from cfnlint.rules import CloudFormationLintRule, RuleMatch class Length(CloudFormationLintRule): """Check if Length values are correct""" id = "E1030" shortdesc = "Length validation of parameters" description = "Making sure Fn::Length is configured correctly" source_url = "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-length.html" tags = ["functions", "length"] supported_functions = ["Fn::Split", "Fn::FindInMap"] def match(self, cfn): has_language_extensions_transform = cfn.has_language_extensions_transform() intrinsic_function = "Fn::Length" matches = [] fn_length_objects = cfn.search_deep_keys(intrinsic_function) for fn_length_object in fn_length_objects: tree = fn_length_object[:-1] LanguageExtensions.validate_transform_is_declared( self, has_language_extensions_transform, matches, tree, intrinsic_function, ) self.validate_type(fn_length_object, matches, tree) self.validate_ref(fn_length_object, matches, tree, cfn) return matches def validate_ref(self, fn_length_object, matches, tree, cfn): fn_length_value = fn_length_object[-1] if isinstance(fn_length_value, dict): if len(fn_length_value.keys()) != 1 or ( list(fn_length_value.keys())[0] not in ["Ref"] + self.supported_functions ): self.addMatch( matches, tree, f"Fn::Length expects either an array, a Ref to an array or {', '.join(self.supported_functions)}, " "but found unexpected object under Fn::Length at {0}", ) return if "Ref" in fn_length_value: if fn_length_value["Ref"] not in cfn.get_parameter_names(): self.addMatch( matches, tree, "Fn::Length can only reference list parameters at {0}", ) else: referenced_parameter = cfn.get_parameters().get( fn_length_value["Ref"] ) parameter_type = referenced_parameter.get("Type") if "List" not in parameter_type: self.addMatch( matches, tree, "Fn::Length can only reference list parameters at {0}", ) def addMatch(self, matches, tree, message): matches.append(RuleMatch(tree[:], message.format("/".join(map(str, tree))))) def validate_type(self, fn_length_object, matches, tree): fn_length_value = fn_length_object[-1] if not isinstance(fn_length_value, dict) and not isinstance( fn_length_value, list ): message = "Fn::Length needs a list or a reference to a list at {0}" matches.append(RuleMatch(tree[:], message.format("/".join(map(str, tree)))))
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
__pycache__ | Folder | 0755 |
|
|
Base64.py | File | 1.72 KB | 0644 |
|
Cidr.py | File | 11.94 KB | 0644 |
|
DynamicReferenceSecureString.py | File | 5.72 KB | 0644 |
|
FindInMap.py | File | 11.25 KB | 0644 |
|
FindInMapKeys.py | File | 3.89 KB | 0644 |
|
GetAtt.py | File | 6.05 KB | 0644 |
|
GetAz.py | File | 2.76 KB | 0644 |
|
If.py | File | 1.45 KB | 0644 |
|
ImportValue.py | File | 2.45 KB | 0644 |
|
Join.py | File | 8.63 KB | 0644 |
|
Length.py | File | 3.31 KB | 0644 |
|
Not.py | File | 978 B | 0644 |
|
Ref.py | File | 1.02 KB | 0644 |
|
RefExist.py | File | 1.26 KB | 0644 |
|
RefInCondition.py | File | 1.36 KB | 0644 |
|
RelationshipConditions.py | File | 5.35 KB | 0644 |
|
Select.py | File | 4.41 KB | 0644 |
|
Split.py | File | 3.11 KB | 0644 |
|
Sub.py | File | 9.49 KB | 0644 |
|
SubNeeded.py | File | 5.48 KB | 0644 |
|
SubNotJoin.py | File | 2 KB | 0644 |
|
SubParametersUsed.py | File | 1.4 KB | 0644 |
|
SubUnneeded.py | File | 1.27 KB | 0644 |
|
ToJsonString.py | File | 1.75 KB | 0644 |
|
__init__.py | File | 106 B | 0644 |
|