forked from aws-cloudformation/cfn-lint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFindInMapKeys.py
64 lines (56 loc) · 2.99 KB
/
FindInMapKeys.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""
import six
from cfnlint.rules import CloudFormationLintRule
from cfnlint.rules import RuleMatch
class FindInMapKeys(CloudFormationLintRule):
"""Check if FindInMap values are correct"""
id = 'W1011'
shortdesc = 'FindInMap keys exist in the map'
description = 'Checks the keys in a FindInMap to make sure they exist. ' \
'Check only if the Map Name is a string and if the key is a string.'
source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html'
tags = ['functions', 'findinmap']
def check_keys(self, map_name, keys, mappings, tree):
""" Check the validity of the first key """
matches = []
first_key = keys[0]
second_key = keys[1]
if isinstance(second_key, (six.string_types, int)):
if isinstance(map_name, (six.string_types)):
mapping = mappings.get(map_name)
if mapping:
if isinstance(first_key, (six.string_types, int)):
if isinstance(map_name, (six.string_types)):
if mapping.get(first_key) is None:
message = 'FindInMap first key "{0}" doesn\'t exist in map "{1}" at {3}'
matches.append(RuleMatch(
tree[:] + [1],
message.format(first_key, map_name, first_key, '/'.join(map(str, tree)))))
if mapping.get(first_key):
# Don't double error if they first key doesn't exist
if mapping.get(first_key, {}).get(second_key) is None:
message = 'FindInMap second key "{0}" doesn\'t exist in map "{1}" under "{2}" at {3}'
matches.append(RuleMatch(
tree[:] + [2],
message.format(second_key, map_name, first_key, '/'.join(map(str, tree)))))
else:
for key, value in mapping.items():
if value.get(second_key) is None:
message = 'FindInMap second key "{0}" doesn\'t exist in map "{1}" under "{2}" at {3}'
matches.append(RuleMatch(
tree[:] + [2],
message.format(second_key, map_name, key, '/'.join(map(str, tree)))))
return matches
def match(self, cfn):
matches = []
findinmaps = cfn.search_deep_keys('Fn::FindInMap')
mappings = cfn.get_mappings()
for findinmap in findinmaps:
tree = findinmap[:-1]
map_obj = findinmap[-1]
if len(map_obj) == 3:
matches.extend(self.check_keys(map_obj[0], map_obj[1:], mappings, tree))
return matches