We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fn::Cidr should support Fn::GetAtt (E1024)
* cfn-lint 0.6.1
* I get the following error: 

```
E1024 Cidr ipBlock should be Cidr Range, Ref, or Select for Resources/MySubnet/Properties/CidrBlock/Fn::Select/1/Fn::Cidr/0/template.yml:123:7
```
```
Resources:
  MySubnet:
    Properties:
      CidrBlock: !Select
        - 0
        - !Cidr
          - !GetAtt 'MyVPC.CidrBlock'
          - 16
          - 8
```

Although the documentation doesn't mention the Fn::GetAtt in the list of supported functions, it is used in the CloudFormation examples on the same page. 

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-cidr.html


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cfnlint/rules/functions/Cidr.py`
Content:
```
1 """
2   Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 
4   Permission is hereby granted, free of charge, to any person obtaining a copy of this
5   software and associated documentation files (the "Software"), to deal in the Software
6   without restriction, including without limitation the rights to use, copy, modify,
7   merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8   permit persons to whom the Software is furnished to do so.
9 
10   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
11   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
12   PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
13   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
14   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 """
17 import re
18 import six
19 from cfnlint import CloudFormationLintRule
20 from cfnlint import RuleMatch
21 
22 from cfnlint.helpers import REGEX_CIDR
23 
24 class Cidr(CloudFormationLintRule):
25     """Check if Cidr values are correct"""
26     id = 'E1024'
27     shortdesc = 'Cidr validation of parameters'
28     description = 'Making sure the function CIDR is a list with valid values'
29     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-cidr.html'
30     tags = ['functions', 'cidr']
31 
32     def check_parameter_count(self, cfn, parameter_name):
33         """Check Count Parameter if used"""
34         matches = list()
35         parameter_obj = cfn.get_parameters().get(parameter_name, {})
36         if parameter_obj:
37             tree = ['Parameters', parameter_name]
38             parameter_type = parameter_obj.get('Type')
39             if parameter_type == 'Number':
40                 max_value = parameter_obj.get('MaxValue')
41                 min_value = parameter_obj.get('MinValue')
42                 if (not min_value) or min_value < 1 or min_value > 256:
43                     message = 'Parameter for Cidr count have MinValue between 1 and 256 at {0}'
44                     matches.append(RuleMatch(
45                         tree + ['MinValue'], message.format('/'.join(map(str, tree + ['MinValue'])))))
46                 if (not max_value) or max_value < 1 or max_value > 256:
47                     message = 'Parameter for Cidr count have MaxValue between 1 and 256 at {0}'
48                     matches.append(RuleMatch(
49                         tree + ['MaxValue'], message.format('/'.join(map(str, tree + ['MaxValue'])))))
50             else:
51                 message = 'Parameter for Cidr count have be of Type Number at {0}'
52                 matches.append(RuleMatch(
53                     tree, message.format('/'.join(map(str, tree)))))
54 
55         return matches
56 
57     def check_parameter_size_mask(self, cfn, parameter_name):
58         """Check SizeMask Parameter if used"""
59         matches = list()
60         parameter_obj = cfn.get_parameters().get(parameter_name, {})
61         if parameter_obj:
62             tree = ['Parameters', parameter_name]
63             parameter_type = parameter_obj.get('Type')
64             if parameter_type == 'Number':
65                 max_value = parameter_obj.get('MaxValue')
66                 min_value = parameter_obj.get('MinValue')
67                 if (not min_value) or min_value < 1 or min_value > 256:
68                     message = 'Parameter for Cidr sizeMask have MinValue between 1 and ' \
69                         '128 (for ipv6) and 32 (for ipv4) at {0}'
70                     matches.append(RuleMatch(
71                         tree + ['MinValue'], message.format('/'.join(map(str, tree + ['MinValue'])))))
72                 if (not max_value) or max_value < 1 or max_value > 256:
73                     message = 'Parameter for Cidr count have MaxValue between 1 and ' \
74                         '128 (for ipv6) and 32 (for ipv4) at {0}'
75                     matches.append(RuleMatch(
76                         tree + ['MaxValue'], message.format('/'.join(map(str, tree + ['MaxValue'])))))
77             else:
78                 message = 'Parameter for Cidr count have be of Type Number at {0}'
79                 matches.append(RuleMatch(
80                     tree, message.format('/'.join(map(str, tree)))))
81 
82         return matches
83 
84     def match(self, cfn):
85         """Check CloudFormation Cidr"""
86 
87         matches = list()
88 
89         cidr_objs = cfn.search_deep_keys('Fn::Cidr')
90 
91         supported_functions = [
92             'Fn::Select',
93             'Ref',
94             'Fn::ImportValue'
95         ]
96 
97         count_parameters = []
98         size_mask_parameters = []
99 
100         for cidr_obj in cidr_objs:
101             cidr_value_obj = cidr_obj[-1]
102             tree = cidr_obj[:-1]
103             if isinstance(cidr_value_obj, list):
104                 if len(cidr_value_obj) in [2, 3]:
105                     ip_block_obj = cidr_value_obj[0]
106                     count_obj = cidr_value_obj[1]
107                     if len(cidr_value_obj) == 3:
108                         size_mask_obj = cidr_value_obj[2]
109                     else:
110                         size_mask_obj = None
111 
112                     if isinstance(ip_block_obj, dict):
113                         if len(ip_block_obj) == 1:
114                             for index_key, _ in ip_block_obj.items():
115                                 if index_key not in supported_functions:
116                                     message = 'Cidr ipBlock should be Cidr Range, Ref, or Select for {0}'
117                                     matches.append(RuleMatch(
118                                         tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))
119                     elif isinstance(ip_block_obj, (six.text_type, six.string_types)):
120                         if not re.match(REGEX_CIDR, ip_block_obj):
121                             message = 'Cidr ipBlock should be a Cidr Range based string for {0}'
122                             matches.append(RuleMatch(
123                                 tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))
124                     else:
125                         message = 'Cidr ipBlock should be a string for {0}'
126                         matches.append(RuleMatch(
127                             tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))
128 
129                     if isinstance(count_obj, dict):
130                         if len(count_obj) == 1:
131                             for index_key, index_value in count_obj.items():
132                                 if index_key not in supported_functions:
133                                     message = 'Cidr count should be Int, Ref, or Select for {0}'
134                                     matches.append(RuleMatch(
135                                         tree[:] + [1], message.format('/'.join(map(str, tree[:] + [1])))))
136                                 if index_key == 'Ref':
137                                     count_parameters.append(index_value)
138                     elif not isinstance(count_obj, six.integer_types):
139                         message = 'Cidr count should be a int for {0}'
140                         matches.append(RuleMatch(
141                             tree[:] + [1], message.format('/'.join(map(str, tree[:] + [1])))))
142 
143                     if isinstance(size_mask_obj, dict):
144                         if len(size_mask_obj) == 1:
145                             for index_key, index_value in size_mask_obj.items():
146                                 if index_key not in supported_functions:
147                                     message = 'Cidr sizeMask should be Int, Ref, or Select for {0}'
148                                     matches.append(RuleMatch(
149                                         tree[:] + [2], message.format('/'.join(map(str, tree[:] + [2])))))
150                                 if index_key == 'Ref':
151                                     size_mask_parameters.append(index_value)
152                     elif not isinstance(size_mask_obj, six.integer_types):
153                         message = 'Cidr sizeMask should be a int for {0}'
154                         matches.append(RuleMatch(
155                             tree[:] + [2], message.format('/'.join(map(str, tree[:] + [2])))))
156 
157                 else:
158                     message = 'Cidr should be a list of 2 or 3 elements for {0}'
159                     matches.append(RuleMatch(
160                         tree, message.format('/'.join(map(str, tree)))))
161             else:
162                 message = 'Cidr should be a list of 2 or 3 elements for {0}'
163                 matches.append(RuleMatch(
164                     tree, message.format('/'.join(map(str, tree)))))
165 
166         for count_parameter in set(count_parameters):
167             matches.extend(self.check_parameter_count(cfn, count_parameter))
168         for size_mask_parameter in set(size_mask_parameters):
169             matches.extend(self.check_parameter_size_mask(cfn, size_mask_parameter))
170 
171         return matches
172
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cfnlint/rules/functions/Cidr.py b/src/cfnlint/rules/functions/Cidr.py
--- a/src/cfnlint/rules/functions/Cidr.py
+++ b/src/cfnlint/rules/functions/Cidr.py
@@ -91,6 +91,7 @@
         supported_functions = [
             'Fn::Select',
             'Ref',
+            'Fn::GetAtt',
             'Fn::ImportValue'
         ]
 
@@ -113,7 +114,7 @@
                         if len(ip_block_obj) == 1:
                             for index_key, _ in ip_block_obj.items():
                                 if index_key not in supported_functions:
-                                    message = 'Cidr ipBlock should be Cidr Range, Ref, or Select for {0}'
+                                    message = 'Cidr ipBlock should be Cidr Range, Ref, GetAtt, or Select for {0}'
                                     matches.append(RuleMatch(
                                         tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))
                     elif isinstance(ip_block_obj, (six.text_type, six.string_types)):

{"golden_diff": "diff --git a/src/cfnlint/rules/functions/Cidr.py b/src/cfnlint/rules/functions/Cidr.py\n--- a/src/cfnlint/rules/functions/Cidr.py\n+++ b/src/cfnlint/rules/functions/Cidr.py\n@@ -91,6 +91,7 @@\n         supported_functions = [\n             'Fn::Select',\n             'Ref',\n+            'Fn::GetAtt',\n             'Fn::ImportValue'\n         ]\n \n@@ -113,7 +114,7 @@\n                         if len(ip_block_obj) == 1:\n                             for index_key, _ in ip_block_obj.items():\n                                 if index_key not in supported_functions:\n-                                    message = 'Cidr ipBlock should be Cidr Range, Ref, or Select for {0}'\n+                                    message = 'Cidr ipBlock should be Cidr Range, Ref, GetAtt, or Select for {0}'\n                                     matches.append(RuleMatch(\n                                         tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))\n                     elif isinstance(ip_block_obj, (six.text_type, six.string_types)):\n", "issue": "Fn::Cidr should support Fn::GetAtt (E1024)\n* cfn-lint 0.6.1\r\n* I get the following error: \r\n\r\n```\r\nE1024 Cidr ipBlock should be Cidr Range, Ref, or Select for Resources/MySubnet/Properties/CidrBlock/Fn::Select/1/Fn::Cidr/0/template.yml:123:7\r\n```\r\n```\r\nResources:\r\n  MySubnet:\r\n    Properties:\r\n      CidrBlock: !Select\r\n        - 0\r\n        - !Cidr\r\n          - !GetAtt 'MyVPC.CidrBlock'\r\n          - 16\r\n          - 8\r\n```\r\n\r\nAlthough the documentation doesn't mention the Fn::GetAtt in the list of supported functions, it is used in the CloudFormation examples on the same page. \r\n\r\nhttps://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-cidr.html\r\n\n", "before_files": [{"content": "\"\"\"\n  Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this\n  software and associated documentation files (the \"Software\"), to deal in the Software\n  without restriction, including without limitation the rights to use, copy, modify,\n  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n  permit persons to whom the Software is furnished to do so.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\"\"\"\nimport re\nimport six\nfrom cfnlint import CloudFormationLintRule\nfrom cfnlint import RuleMatch\n\nfrom cfnlint.helpers import REGEX_CIDR\n\nclass Cidr(CloudFormationLintRule):\n    \"\"\"Check if Cidr values are correct\"\"\"\n    id = 'E1024'\n    shortdesc = 'Cidr validation of parameters'\n    description = 'Making sure the function CIDR is a list with valid values'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-cidr.html'\n    tags = ['functions', 'cidr']\n\n    def check_parameter_count(self, cfn, parameter_name):\n        \"\"\"Check Count Parameter if used\"\"\"\n        matches = list()\n        parameter_obj = cfn.get_parameters().get(parameter_name, {})\n        if parameter_obj:\n            tree = ['Parameters', parameter_name]\n            parameter_type = parameter_obj.get('Type')\n            if parameter_type == 'Number':\n                max_value = parameter_obj.get('MaxValue')\n                min_value = parameter_obj.get('MinValue')\n                if (not min_value) or min_value < 1 or min_value > 256:\n                    message = 'Parameter for Cidr count have MinValue between 1 and 256 at {0}'\n                    matches.append(RuleMatch(\n                        tree + ['MinValue'], message.format('/'.join(map(str, tree + ['MinValue'])))))\n                if (not max_value) or max_value < 1 or max_value > 256:\n                    message = 'Parameter for Cidr count have MaxValue between 1 and 256 at {0}'\n                    matches.append(RuleMatch(\n                        tree + ['MaxValue'], message.format('/'.join(map(str, tree + ['MaxValue'])))))\n            else:\n                message = 'Parameter for Cidr count have be of Type Number at {0}'\n                matches.append(RuleMatch(\n                    tree, message.format('/'.join(map(str, tree)))))\n\n        return matches\n\n    def check_parameter_size_mask(self, cfn, parameter_name):\n        \"\"\"Check SizeMask Parameter if used\"\"\"\n        matches = list()\n        parameter_obj = cfn.get_parameters().get(parameter_name, {})\n        if parameter_obj:\n            tree = ['Parameters', parameter_name]\n            parameter_type = parameter_obj.get('Type')\n            if parameter_type == 'Number':\n                max_value = parameter_obj.get('MaxValue')\n                min_value = parameter_obj.get('MinValue')\n                if (not min_value) or min_value < 1 or min_value > 256:\n                    message = 'Parameter for Cidr sizeMask have MinValue between 1 and ' \\\n                        '128 (for ipv6) and 32 (for ipv4) at {0}'\n                    matches.append(RuleMatch(\n                        tree + ['MinValue'], message.format('/'.join(map(str, tree + ['MinValue'])))))\n                if (not max_value) or max_value < 1 or max_value > 256:\n                    message = 'Parameter for Cidr count have MaxValue between 1 and ' \\\n                        '128 (for ipv6) and 32 (for ipv4) at {0}'\n                    matches.append(RuleMatch(\n                        tree + ['MaxValue'], message.format('/'.join(map(str, tree + ['MaxValue'])))))\n            else:\n                message = 'Parameter for Cidr count have be of Type Number at {0}'\n                matches.append(RuleMatch(\n                    tree, message.format('/'.join(map(str, tree)))))\n\n        return matches\n\n    def match(self, cfn):\n        \"\"\"Check CloudFormation Cidr\"\"\"\n\n        matches = list()\n\n        cidr_objs = cfn.search_deep_keys('Fn::Cidr')\n\n        supported_functions = [\n            'Fn::Select',\n            'Ref',\n            'Fn::ImportValue'\n        ]\n\n        count_parameters = []\n        size_mask_parameters = []\n\n        for cidr_obj in cidr_objs:\n            cidr_value_obj = cidr_obj[-1]\n            tree = cidr_obj[:-1]\n            if isinstance(cidr_value_obj, list):\n                if len(cidr_value_obj) in [2, 3]:\n                    ip_block_obj = cidr_value_obj[0]\n                    count_obj = cidr_value_obj[1]\n                    if len(cidr_value_obj) == 3:\n                        size_mask_obj = cidr_value_obj[2]\n                    else:\n                        size_mask_obj = None\n\n                    if isinstance(ip_block_obj, dict):\n                        if len(ip_block_obj) == 1:\n                            for index_key, _ in ip_block_obj.items():\n                                if index_key not in supported_functions:\n                                    message = 'Cidr ipBlock should be Cidr Range, Ref, or Select for {0}'\n                                    matches.append(RuleMatch(\n                                        tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))\n                    elif isinstance(ip_block_obj, (six.text_type, six.string_types)):\n                        if not re.match(REGEX_CIDR, ip_block_obj):\n                            message = 'Cidr ipBlock should be a Cidr Range based string for {0}'\n                            matches.append(RuleMatch(\n                                tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))\n                    else:\n                        message = 'Cidr ipBlock should be a string for {0}'\n                        matches.append(RuleMatch(\n                            tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))\n\n                    if isinstance(count_obj, dict):\n                        if len(count_obj) == 1:\n                            for index_key, index_value in count_obj.items():\n                                if index_key not in supported_functions:\n                                    message = 'Cidr count should be Int, Ref, or Select for {0}'\n                                    matches.append(RuleMatch(\n                                        tree[:] + [1], message.format('/'.join(map(str, tree[:] + [1])))))\n                                if index_key == 'Ref':\n                                    count_parameters.append(index_value)\n                    elif not isinstance(count_obj, six.integer_types):\n                        message = 'Cidr count should be a int for {0}'\n                        matches.append(RuleMatch(\n                            tree[:] + [1], message.format('/'.join(map(str, tree[:] + [1])))))\n\n                    if isinstance(size_mask_obj, dict):\n                        if len(size_mask_obj) == 1:\n                            for index_key, index_value in size_mask_obj.items():\n                                if index_key not in supported_functions:\n                                    message = 'Cidr sizeMask should be Int, Ref, or Select for {0}'\n                                    matches.append(RuleMatch(\n                                        tree[:] + [2], message.format('/'.join(map(str, tree[:] + [2])))))\n                                if index_key == 'Ref':\n                                    size_mask_parameters.append(index_value)\n                    elif not isinstance(size_mask_obj, six.integer_types):\n                        message = 'Cidr sizeMask should be a int for {0}'\n                        matches.append(RuleMatch(\n                            tree[:] + [2], message.format('/'.join(map(str, tree[:] + [2])))))\n\n                else:\n                    message = 'Cidr should be a list of 2 or 3 elements for {0}'\n                    matches.append(RuleMatch(\n                        tree, message.format('/'.join(map(str, tree)))))\n            else:\n                message = 'Cidr should be a list of 2 or 3 elements for {0}'\n                matches.append(RuleMatch(\n                    tree, message.format('/'.join(map(str, tree)))))\n\n        for count_parameter in set(count_parameters):\n            matches.extend(self.check_parameter_count(cfn, count_parameter))\n        for size_mask_parameter in set(size_mask_parameters):\n            matches.extend(self.check_parameter_size_mask(cfn, size_mask_parameter))\n\n        return matches\n", "path": "src/cfnlint/rules/functions/Cidr.py"}], "after_files": [{"content": "\"\"\"\n  Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this\n  software and associated documentation files (the \"Software\"), to deal in the Software\n  without restriction, including without limitation the rights to use, copy, modify,\n  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n  permit persons to whom the Software is furnished to do so.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\"\"\"\nimport re\nimport six\nfrom cfnlint import CloudFormationLintRule\nfrom cfnlint import RuleMatch\n\nfrom cfnlint.helpers import REGEX_CIDR\n\nclass Cidr(CloudFormationLintRule):\n    \"\"\"Check if Cidr values are correct\"\"\"\n    id = 'E1024'\n    shortdesc = 'Cidr validation of parameters'\n    description = 'Making sure the function CIDR is a list with valid values'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-cidr.html'\n    tags = ['functions', 'cidr']\n\n    def check_parameter_count(self, cfn, parameter_name):\n        \"\"\"Check Count Parameter if used\"\"\"\n        matches = list()\n        parameter_obj = cfn.get_parameters().get(parameter_name, {})\n        if parameter_obj:\n            tree = ['Parameters', parameter_name]\n            parameter_type = parameter_obj.get('Type')\n            if parameter_type == 'Number':\n                max_value = parameter_obj.get('MaxValue')\n                min_value = parameter_obj.get('MinValue')\n                if (not min_value) or min_value < 1 or min_value > 256:\n                    message = 'Parameter for Cidr count have MinValue between 1 and 256 at {0}'\n                    matches.append(RuleMatch(\n                        tree + ['MinValue'], message.format('/'.join(map(str, tree + ['MinValue'])))))\n                if (not max_value) or max_value < 1 or max_value > 256:\n                    message = 'Parameter for Cidr count have MaxValue between 1 and 256 at {0}'\n                    matches.append(RuleMatch(\n                        tree + ['MaxValue'], message.format('/'.join(map(str, tree + ['MaxValue'])))))\n            else:\n                message = 'Parameter for Cidr count have be of Type Number at {0}'\n                matches.append(RuleMatch(\n                    tree, message.format('/'.join(map(str, tree)))))\n\n        return matches\n\n    def check_parameter_size_mask(self, cfn, parameter_name):\n        \"\"\"Check SizeMask Parameter if used\"\"\"\n        matches = list()\n        parameter_obj = cfn.get_parameters().get(parameter_name, {})\n        if parameter_obj:\n            tree = ['Parameters', parameter_name]\n            parameter_type = parameter_obj.get('Type')\n            if parameter_type == 'Number':\n                max_value = parameter_obj.get('MaxValue')\n                min_value = parameter_obj.get('MinValue')\n                if (not min_value) or min_value < 1 or min_value > 256:\n                    message = 'Parameter for Cidr sizeMask have MinValue between 1 and ' \\\n                        '128 (for ipv6) and 32 (for ipv4) at {0}'\n                    matches.append(RuleMatch(\n                        tree + ['MinValue'], message.format('/'.join(map(str, tree + ['MinValue'])))))\n                if (not max_value) or max_value < 1 or max_value > 256:\n                    message = 'Parameter for Cidr count have MaxValue between 1 and ' \\\n                        '128 (for ipv6) and 32 (for ipv4) at {0}'\n                    matches.append(RuleMatch(\n                        tree + ['MaxValue'], message.format('/'.join(map(str, tree + ['MaxValue'])))))\n            else:\n                message = 'Parameter for Cidr count have be of Type Number at {0}'\n                matches.append(RuleMatch(\n                    tree, message.format('/'.join(map(str, tree)))))\n\n        return matches\n\n    def match(self, cfn):\n        \"\"\"Check CloudFormation Cidr\"\"\"\n\n        matches = list()\n\n        cidr_objs = cfn.search_deep_keys('Fn::Cidr')\n\n        supported_functions = [\n            'Fn::Select',\n            'Ref',\n            'Fn::GetAtt',\n            'Fn::ImportValue'\n        ]\n\n        count_parameters = []\n        size_mask_parameters = []\n\n        for cidr_obj in cidr_objs:\n            cidr_value_obj = cidr_obj[-1]\n            tree = cidr_obj[:-1]\n            if isinstance(cidr_value_obj, list):\n                if len(cidr_value_obj) in [2, 3]:\n                    ip_block_obj = cidr_value_obj[0]\n                    count_obj = cidr_value_obj[1]\n                    if len(cidr_value_obj) == 3:\n                        size_mask_obj = cidr_value_obj[2]\n                    else:\n                        size_mask_obj = None\n\n                    if isinstance(ip_block_obj, dict):\n                        if len(ip_block_obj) == 1:\n                            for index_key, _ in ip_block_obj.items():\n                                if index_key not in supported_functions:\n                                    message = 'Cidr ipBlock should be Cidr Range, Ref, GetAtt, or Select for {0}'\n                                    matches.append(RuleMatch(\n                                        tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))\n                    elif isinstance(ip_block_obj, (six.text_type, six.string_types)):\n                        if not re.match(REGEX_CIDR, ip_block_obj):\n                            message = 'Cidr ipBlock should be a Cidr Range based string for {0}'\n                            matches.append(RuleMatch(\n                                tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))\n                    else:\n                        message = 'Cidr ipBlock should be a string for {0}'\n                        matches.append(RuleMatch(\n                            tree[:] + [0], message.format('/'.join(map(str, tree[:] + [0])))))\n\n                    if isinstance(count_obj, dict):\n                        if len(count_obj) == 1:\n                            for index_key, index_value in count_obj.items():\n                                if index_key not in supported_functions:\n                                    message = 'Cidr count should be Int, Ref, or Select for {0}'\n                                    matches.append(RuleMatch(\n                                        tree[:] + [1], message.format('/'.join(map(str, tree[:] + [1])))))\n                                if index_key == 'Ref':\n                                    count_parameters.append(index_value)\n                    elif not isinstance(count_obj, six.integer_types):\n                        message = 'Cidr count should be a int for {0}'\n                        matches.append(RuleMatch(\n                            tree[:] + [1], message.format('/'.join(map(str, tree[:] + [1])))))\n\n                    if isinstance(size_mask_obj, dict):\n                        if len(size_mask_obj) == 1:\n                            for index_key, index_value in size_mask_obj.items():\n                                if index_key not in supported_functions:\n                                    message = 'Cidr sizeMask should be Int, Ref, or Select for {0}'\n                                    matches.append(RuleMatch(\n                                        tree[:] + [2], message.format('/'.join(map(str, tree[:] + [2])))))\n                                if index_key == 'Ref':\n                                    size_mask_parameters.append(index_value)\n                    elif not isinstance(size_mask_obj, six.integer_types):\n                        message = 'Cidr sizeMask should be a int for {0}'\n                        matches.append(RuleMatch(\n                            tree[:] + [2], message.format('/'.join(map(str, tree[:] + [2])))))\n\n                else:\n                    message = 'Cidr should be a list of 2 or 3 elements for {0}'\n                    matches.append(RuleMatch(\n                        tree, message.format('/'.join(map(str, tree)))))\n            else:\n                message = 'Cidr should be a list of 2 or 3 elements for {0}'\n                matches.append(RuleMatch(\n                    tree, message.format('/'.join(map(str, tree)))))\n\n        for count_parameter in set(count_parameters):\n            matches.extend(self.check_parameter_count(cfn, count_parameter))\n        for size_mask_parameter in set(size_mask_parameters):\n            matches.extend(self.check_parameter_size_mask(cfn, size_mask_parameter))\n\n        return matches\n", "path": "src/cfnlint/rules/functions/Cidr.py"}]}