""" Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: MIT-0 """ from cfnlint.rules import CloudFormationLintRule, RuleMatch class Select(CloudFormationLintRule): """Check if Select values are correct""" id = "E1017" shortdesc = "Select validation of parameters" description = "Making sure the Select function is properly configured" source_url = "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html" tags = ["functions", "select"] supported_functions = [ "Fn::FindInMap", "Fn::GetAtt", "Fn::GetAZs", "Fn::If", "Fn::Split", "Fn::Cidr", "Ref", ] def _test_index_obj(self, index_obj, path): matches = [] if isinstance(index_obj, dict): if len(index_obj) == 1: for index_key, _ in index_obj.items(): if index_key not in [ "Ref", "Fn::FindInMap", "Fn::Select", ]: message = "Select index should be an Integer or a function Ref, Fn::FindInMap, or Fn::Select for {0}" matches.append( RuleMatch( path, message.format("/".join(map(str, path))), ) ) else: message = "Select index should be an Integer or a function Ref, Fn::FindInMap, or Fn::Select for {0}" matches.append( RuleMatch( path, message.format("/".join(map(str, path))), ) ) elif not isinstance(index_obj, int): try: int(index_obj) except (ValueError, TypeError): message = "Select index should be an Integer or a function of Ref, Fn::FindInMap, or Fn::Select for {0}" matches.append( RuleMatch(path, message.format("/".join(map(str, path)))) ) return matches def _test_list_obj(self, list_obj, path): matches = [] if isinstance(list_obj, dict): if len(list_obj) == 1: for key, _ in list_obj.items(): if key not in self.supported_functions: message = "Select should use a supported function of {0}" matches.append( RuleMatch( path, message.format( ", ".join(map(str, self.supported_functions)) ), ) ) else: message = "Select should use a supported function of {0}" matches.append( RuleMatch( path, message.format(", ".join(map(str, self.supported_functions))), ) ) elif not isinstance(list_obj, list): message = "Select should be an array of values for {0}" matches.append(RuleMatch(path, message.format("/".join(map(str, path))))) return matches def _test_select_obj(self, select_obj, path): matches = [] if not isinstance(select_obj, list): message = "Select should be a list of 2 elements for {0}" matches.append(RuleMatch(path, message.format("/".join(map(str, path))))) return matches if len(select_obj) != 2: message = "Select should be a list of 2 elements for {0}" matches.append(RuleMatch(path, message.format("/".join(map(str, path))))) return matches index_obj = select_obj[0] list_of_objs = select_obj[1] matches.extend(self._test_index_obj(index_obj, path[:] + [0])) matches.extend(self._test_list_obj(list_of_objs, path[:] + [1])) return matches def match(self, cfn): matches = [] select_objs = cfn.search_deep_keys("Fn::Select") for select_obj in select_objs: select_value_obj = select_obj[-1] tree = select_obj[:-1] matches.extend(self._test_select_obj(select_value_obj, tree[:])) return matches
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 |
|