We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Supression skip comments for CloudFormation templates
Suppression does not appear to work for CloudFormation templates. For example with the following group, adding skip commitfor `CKV_AWS_24` to not get a warning from SSH port open.  

```
  #checkov:skip=CKV_AWS_24:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Folding@home spot instance security group
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref SSHLocation
      SecurityGroupEgress:
        - IpProtocol: udp
          FromPort: 53
          ToPort: 53
          CidrIp: 0.0.0.0/0
        - IpProtocol: udp
          FromPort: 123
          ToPort: 123
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
```
Please implement supression for CloudFormation templates also.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `checkov/cloudformation/runner.py`
Content:
```
1 import logging
2 import operator
3 import os
4 from functools import reduce
5 
6 from checkov.cloudformation.checks.resource.registry import resource_registry
7 from checkov.cloudformation.parser import parse
8 from checkov.common.output.record import Record
9 from checkov.common.output.report import Report
10 from checkov.common.runners.base_runner import BaseRunner
11 from checkov.runner_filter import RunnerFilter
12 
13 CF_POSSIBLE_ENDINGS = [".yml", ".yaml", ".json", ".template"]
14 
15 
16 class Runner(BaseRunner):
17     check_type = "cloudformation"
18 
19     def run(self, root_folder, external_checks_dir=None, files=None, runner_filter=RunnerFilter()):
20         report = Report(self.check_type)
21         definitions = {}
22         definitions_raw = {}
23         parsing_errors = {}
24         files_list = []
25         if external_checks_dir:
26             for directory in external_checks_dir:
27                 resource_registry.load_external_checks(directory)
28 
29         if files:
30             for file in files:
31                 (definitions[file], definitions_raw[file]) = parse(file)
32 
33         if root_folder:
34             for root, d_names, f_names in os.walk(root_folder):
35                 for file in f_names:
36                     file_ending = os.path.splitext(file)[1]
37                     if file_ending in CF_POSSIBLE_ENDINGS:
38                         files_list.append(os.path.join(root, file))
39 
40             for file in files_list:
41                 relative_file_path = f'/{os.path.relpath(file, os.path.commonprefix((root_folder, file)))}'
42                 (definitions[relative_file_path], definitions_raw[relative_file_path]) = parse(file)
43 
44         # Filter out empty files that have not been parsed successfully, and filter out non-CF template files
45         definitions = {k: v for k, v in definitions.items() if v and v.__contains__("Resources")}
46         definitions_raw = {k: v for k, v in definitions_raw.items() if k in definitions.keys()}
47 
48         for cf_file in definitions.keys():
49             if not 'Resources' in definitions[cf_file].keys():
50                 continue
51             logging.debug("Template Dump for {}: {}".format(cf_file, definitions[cf_file], indent=2))
52 
53             # Get Parameter Defaults - Locate Refs in Template
54             refs = []
55             refs.extend(self._search_deep_keys('Ref', definitions[cf_file], []))
56 
57             for ref in refs:
58                 refname = ref.pop()
59                 ref.pop()  # Get rid of the 'Ref' dict key
60 
61                 if 'Parameters' in definitions[cf_file].keys() and refname in definitions[cf_file][
62                     'Parameters'].keys():
63                     # TODO refactor into evaluations
64                     if 'Default' in definitions[cf_file]['Parameters'][refname].keys():
65                         logging.debug(
66                             "Replacing Ref {} in file {} with default parameter value: {}".format(refname, cf_file,
67                                                                                                   definitions[
68                                                                                                       cf_file][
69                                                                                                       'Parameters'][
70                                                                                                       refname][
71                                                                                                       'Default']))
72                         _set_in_dict(definitions[cf_file], ref,
73                                      definitions[cf_file]['Parameters'][refname]['Default'])
74 
75                         ## TODO - Add Variable Eval Message for Output
76                         # Output in Checkov looks like this:
77                         # Variable versioning (of /.) evaluated to value "True" in expression: enabled = ${var.versioning}
78 
79             for resource_name, resource in definitions[cf_file]['Resources'].items():
80                 if resource_name == '__startline__' or resource_name == '__endline__':
81                     continue
82                 resource_id = f"{resource['Type']}.{resource_name}"
83 
84                 ## TODO - Evaluate skipped_checks
85                 skipped_checks = {}
86 
87                 results = resource_registry.scan(cf_file, {resource_name: resource}, skipped_checks,runner_filter)
88                 # TODO refactor into context parsing
89                 find_lines_result_list = list(find_lines(resource, '__startline__'))
90                 if len(find_lines_result_list) >= 1:
91                     start_line = min(find_lines_result_list)
92                     end_line = max(list(find_lines(resource, '__endline__')))
93 
94                     entity_lines_range = [start_line, end_line - 1]
95 
96                     entity_code_lines = definitions_raw[cf_file][start_line - 1: end_line - 1]
97 
98                     # TODO - Variable Eval Message!
99                     variable_evaluations = {}
100 
101                     for check, check_result in results.items():
102                         ### TODO - Need to get entity_code_lines and entity_lines_range
103                         record = Record(check_id=check.id, check_name=check.name, check_result=check_result,
104                                         code_block=entity_code_lines, file_path=cf_file,
105                                         file_line_range=entity_lines_range,
106                                         resource=resource_id, evaluations=variable_evaluations,
107                                         check_class=check.__class__.__module__)
108                         report.add_record(record=record)
109         return report
110 
111     def _search_deep_keys(self, search_text, cfn_dict, path):
112         """Search deep for keys and get their values"""
113         keys = []
114         if isinstance(cfn_dict, dict):
115             for key in cfn_dict:
116                 pathprop = path[:]
117                 pathprop.append(key)
118                 if key == search_text:
119                     pathprop.append(cfn_dict[key])
120                     keys.append(pathprop)
121                     # pop the last element off for nesting of found elements for
122                     # dict and list checks
123                     pathprop = pathprop[:-1]
124                 if isinstance(cfn_dict[key], dict):
125                     keys.extend(self._search_deep_keys(search_text, cfn_dict[key], pathprop))
126                 elif isinstance(cfn_dict[key], list):
127                     for index, item in enumerate(cfn_dict[key]):
128                         pathproparr = pathprop[:]
129                         pathproparr.append(index)
130                         keys.extend(self._search_deep_keys(search_text, item, pathproparr))
131         elif isinstance(cfn_dict, list):
132             for index, item in enumerate(cfn_dict):
133                 pathprop = path[:]
134                 pathprop.append(index)
135                 keys.extend(self._search_deep_keys(search_text, item, pathprop))
136 
137         return keys
138 
139 
140 def _get_from_dict(data_dict, map_list):
141     return reduce(operator.getitem, map_list, data_dict)
142 
143 
144 def _set_in_dict(data_dict, map_list, value):
145     _get_from_dict(data_dict, map_list[:-1])[map_list[-1]] = value
146 
147 
148 def find_lines(node, kv):
149     if isinstance(node, list):
150         for i in node:
151             for x in find_lines(i, kv):
152                 yield x
153     elif isinstance(node, dict):
154         if kv in node:
155             yield node[kv]
156         for j in node.values():
157             for x in find_lines(j, kv):
158                 yield x
159
```
--- 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/checkov/cloudformation/runner.py b/checkov/cloudformation/runner.py
--- a/checkov/cloudformation/runner.py
+++ b/checkov/cloudformation/runner.py
@@ -1,6 +1,7 @@
 import logging
 import operator
 import os
+import re
 from functools import reduce
 
 from checkov.cloudformation.checks.resource.registry import resource_registry
@@ -11,6 +12,7 @@
 from checkov.runner_filter import RunnerFilter
 
 CF_POSSIBLE_ENDINGS = [".yml", ".yaml", ".json", ".template"]
+COMMENT_REGEX = re.compile(r'(checkov:skip=) *([A-Z_\d]+)(:[^\n]+)?')
 
 
 class Runner(BaseRunner):
@@ -81,10 +83,6 @@
                     continue
                 resource_id = f"{resource['Type']}.{resource_name}"
 
-                ## TODO - Evaluate skipped_checks
-                skipped_checks = {}
-
-                results = resource_registry.scan(cf_file, {resource_name: resource}, skipped_checks,runner_filter)
                 # TODO refactor into context parsing
                 find_lines_result_list = list(find_lines(resource, '__startline__'))
                 if len(find_lines_result_list) >= 1:
@@ -98,6 +96,18 @@
                     # TODO - Variable Eval Message!
                     variable_evaluations = {}
 
+                    skipped_checks = []
+                    for line in entity_code_lines:
+                        skip_search = re.search(COMMENT_REGEX, str(line))
+                        if skip_search:
+                            skipped_checks.append(
+                                {
+                                    'id': skip_search.group(2),
+                                    'suppress_comment': skip_search.group(3)[1:] if skip_search.group(3) else "No comment provided"
+                                }
+                            )
+
+                    results = resource_registry.scan(cf_file, {resource_name: resource}, skipped_checks, runner_filter)
                     for check, check_result in results.items():
                         ### TODO - Need to get entity_code_lines and entity_lines_range
                         record = Record(check_id=check.id, check_name=check.name, check_result=check_result,

{"golden_diff": "diff --git a/checkov/cloudformation/runner.py b/checkov/cloudformation/runner.py\n--- a/checkov/cloudformation/runner.py\n+++ b/checkov/cloudformation/runner.py\n@@ -1,6 +1,7 @@\n import logging\n import operator\n import os\n+import re\n from functools import reduce\n \n from checkov.cloudformation.checks.resource.registry import resource_registry\n@@ -11,6 +12,7 @@\n from checkov.runner_filter import RunnerFilter\n \n CF_POSSIBLE_ENDINGS = [\".yml\", \".yaml\", \".json\", \".template\"]\n+COMMENT_REGEX = re.compile(r'(checkov:skip=) *([A-Z_\\d]+)(:[^\\n]+)?')\n \n \n class Runner(BaseRunner):\n@@ -81,10 +83,6 @@\n                     continue\n                 resource_id = f\"{resource['Type']}.{resource_name}\"\n \n-                ## TODO - Evaluate skipped_checks\n-                skipped_checks = {}\n-\n-                results = resource_registry.scan(cf_file, {resource_name: resource}, skipped_checks,runner_filter)\n                 # TODO refactor into context parsing\n                 find_lines_result_list = list(find_lines(resource, '__startline__'))\n                 if len(find_lines_result_list) >= 1:\n@@ -98,6 +96,18 @@\n                     # TODO - Variable Eval Message!\n                     variable_evaluations = {}\n \n+                    skipped_checks = []\n+                    for line in entity_code_lines:\n+                        skip_search = re.search(COMMENT_REGEX, str(line))\n+                        if skip_search:\n+                            skipped_checks.append(\n+                                {\n+                                    'id': skip_search.group(2),\n+                                    'suppress_comment': skip_search.group(3)[1:] if skip_search.group(3) else \"No comment provided\"\n+                                }\n+                            )\n+\n+                    results = resource_registry.scan(cf_file, {resource_name: resource}, skipped_checks, runner_filter)\n                     for check, check_result in results.items():\n                         ### TODO - Need to get entity_code_lines and entity_lines_range\n                         record = Record(check_id=check.id, check_name=check.name, check_result=check_result,\n", "issue": "Supression skip comments for CloudFormation templates\nSuppression does not appear to work for CloudFormation templates. For example with the following group, adding skip commitfor `CKV_AWS_24` to not get a warning from SSH port open.  \r\n\r\n```\r\n  #checkov:skip=CKV_AWS_24:\r\n  SecurityGroup:\r\n    Type: AWS::EC2::SecurityGroup\r\n    Properties:\r\n      GroupDescription: Folding@home spot instance security group\r\n      VpcId: !Ref VpcId\r\n      SecurityGroupIngress:\r\n        - IpProtocol: tcp\r\n          FromPort: 22\r\n          ToPort: 22\r\n          CidrIp: !Ref SSHLocation\r\n      SecurityGroupEgress:\r\n        - IpProtocol: udp\r\n          FromPort: 53\r\n          ToPort: 53\r\n          CidrIp: 0.0.0.0/0\r\n        - IpProtocol: udp\r\n          FromPort: 123\r\n          ToPort: 123\r\n          CidrIp: 0.0.0.0/0\r\n        - IpProtocol: tcp\r\n          FromPort: 80\r\n          ToPort: 80\r\n          CidrIp: 0.0.0.0/0\r\n        - IpProtocol: tcp\r\n          FromPort: 8080\r\n          ToPort: 8080\r\n          CidrIp: 0.0.0.0/0\r\n        - IpProtocol: tcp\r\n          FromPort: 443\r\n          ToPort: 443\r\n          CidrIp: 0.0.0.0/0\r\n```\r\nPlease implement supression for CloudFormation templates also.\n", "before_files": [{"content": "import logging\nimport operator\nimport os\nfrom functools import reduce\n\nfrom checkov.cloudformation.checks.resource.registry import resource_registry\nfrom checkov.cloudformation.parser import parse\nfrom checkov.common.output.record import Record\nfrom checkov.common.output.report import Report\nfrom checkov.common.runners.base_runner import BaseRunner\nfrom checkov.runner_filter import RunnerFilter\n\nCF_POSSIBLE_ENDINGS = [\".yml\", \".yaml\", \".json\", \".template\"]\n\n\nclass Runner(BaseRunner):\n    check_type = \"cloudformation\"\n\n    def run(self, root_folder, external_checks_dir=None, files=None, runner_filter=RunnerFilter()):\n        report = Report(self.check_type)\n        definitions = {}\n        definitions_raw = {}\n        parsing_errors = {}\n        files_list = []\n        if external_checks_dir:\n            for directory in external_checks_dir:\n                resource_registry.load_external_checks(directory)\n\n        if files:\n            for file in files:\n                (definitions[file], definitions_raw[file]) = parse(file)\n\n        if root_folder:\n            for root, d_names, f_names in os.walk(root_folder):\n                for file in f_names:\n                    file_ending = os.path.splitext(file)[1]\n                    if file_ending in CF_POSSIBLE_ENDINGS:\n                        files_list.append(os.path.join(root, file))\n\n            for file in files_list:\n                relative_file_path = f'/{os.path.relpath(file, os.path.commonprefix((root_folder, file)))}'\n                (definitions[relative_file_path], definitions_raw[relative_file_path]) = parse(file)\n\n        # Filter out empty files that have not been parsed successfully, and filter out non-CF template files\n        definitions = {k: v for k, v in definitions.items() if v and v.__contains__(\"Resources\")}\n        definitions_raw = {k: v for k, v in definitions_raw.items() if k in definitions.keys()}\n\n        for cf_file in definitions.keys():\n            if not 'Resources' in definitions[cf_file].keys():\n                continue\n            logging.debug(\"Template Dump for {}: {}\".format(cf_file, definitions[cf_file], indent=2))\n\n            # Get Parameter Defaults - Locate Refs in Template\n            refs = []\n            refs.extend(self._search_deep_keys('Ref', definitions[cf_file], []))\n\n            for ref in refs:\n                refname = ref.pop()\n                ref.pop()  # Get rid of the 'Ref' dict key\n\n                if 'Parameters' in definitions[cf_file].keys() and refname in definitions[cf_file][\n                    'Parameters'].keys():\n                    # TODO refactor into evaluations\n                    if 'Default' in definitions[cf_file]['Parameters'][refname].keys():\n                        logging.debug(\n                            \"Replacing Ref {} in file {} with default parameter value: {}\".format(refname, cf_file,\n                                                                                                  definitions[\n                                                                                                      cf_file][\n                                                                                                      'Parameters'][\n                                                                                                      refname][\n                                                                                                      'Default']))\n                        _set_in_dict(definitions[cf_file], ref,\n                                     definitions[cf_file]['Parameters'][refname]['Default'])\n\n                        ## TODO - Add Variable Eval Message for Output\n                        # Output in Checkov looks like this:\n                        # Variable versioning (of /.) evaluated to value \"True\" in expression: enabled = ${var.versioning}\n\n            for resource_name, resource in definitions[cf_file]['Resources'].items():\n                if resource_name == '__startline__' or resource_name == '__endline__':\n                    continue\n                resource_id = f\"{resource['Type']}.{resource_name}\"\n\n                ## TODO - Evaluate skipped_checks\n                skipped_checks = {}\n\n                results = resource_registry.scan(cf_file, {resource_name: resource}, skipped_checks,runner_filter)\n                # TODO refactor into context parsing\n                find_lines_result_list = list(find_lines(resource, '__startline__'))\n                if len(find_lines_result_list) >= 1:\n                    start_line = min(find_lines_result_list)\n                    end_line = max(list(find_lines(resource, '__endline__')))\n\n                    entity_lines_range = [start_line, end_line - 1]\n\n                    entity_code_lines = definitions_raw[cf_file][start_line - 1: end_line - 1]\n\n                    # TODO - Variable Eval Message!\n                    variable_evaluations = {}\n\n                    for check, check_result in results.items():\n                        ### TODO - Need to get entity_code_lines and entity_lines_range\n                        record = Record(check_id=check.id, check_name=check.name, check_result=check_result,\n                                        code_block=entity_code_lines, file_path=cf_file,\n                                        file_line_range=entity_lines_range,\n                                        resource=resource_id, evaluations=variable_evaluations,\n                                        check_class=check.__class__.__module__)\n                        report.add_record(record=record)\n        return report\n\n    def _search_deep_keys(self, search_text, cfn_dict, path):\n        \"\"\"Search deep for keys and get their values\"\"\"\n        keys = []\n        if isinstance(cfn_dict, dict):\n            for key in cfn_dict:\n                pathprop = path[:]\n                pathprop.append(key)\n                if key == search_text:\n                    pathprop.append(cfn_dict[key])\n                    keys.append(pathprop)\n                    # pop the last element off for nesting of found elements for\n                    # dict and list checks\n                    pathprop = pathprop[:-1]\n                if isinstance(cfn_dict[key], dict):\n                    keys.extend(self._search_deep_keys(search_text, cfn_dict[key], pathprop))\n                elif isinstance(cfn_dict[key], list):\n                    for index, item in enumerate(cfn_dict[key]):\n                        pathproparr = pathprop[:]\n                        pathproparr.append(index)\n                        keys.extend(self._search_deep_keys(search_text, item, pathproparr))\n        elif isinstance(cfn_dict, list):\n            for index, item in enumerate(cfn_dict):\n                pathprop = path[:]\n                pathprop.append(index)\n                keys.extend(self._search_deep_keys(search_text, item, pathprop))\n\n        return keys\n\n\ndef _get_from_dict(data_dict, map_list):\n    return reduce(operator.getitem, map_list, data_dict)\n\n\ndef _set_in_dict(data_dict, map_list, value):\n    _get_from_dict(data_dict, map_list[:-1])[map_list[-1]] = value\n\n\ndef find_lines(node, kv):\n    if isinstance(node, list):\n        for i in node:\n            for x in find_lines(i, kv):\n                yield x\n    elif isinstance(node, dict):\n        if kv in node:\n            yield node[kv]\n        for j in node.values():\n            for x in find_lines(j, kv):\n                yield x\n", "path": "checkov/cloudformation/runner.py"}], "after_files": [{"content": "import logging\nimport operator\nimport os\nimport re\nfrom functools import reduce\n\nfrom checkov.cloudformation.checks.resource.registry import resource_registry\nfrom checkov.cloudformation.parser import parse\nfrom checkov.common.output.record import Record\nfrom checkov.common.output.report import Report\nfrom checkov.common.runners.base_runner import BaseRunner\nfrom checkov.runner_filter import RunnerFilter\n\nCF_POSSIBLE_ENDINGS = [\".yml\", \".yaml\", \".json\", \".template\"]\nCOMMENT_REGEX = re.compile(r'(checkov:skip=) *([A-Z_\\d]+)(:[^\\n]+)?')\n\n\nclass Runner(BaseRunner):\n    check_type = \"cloudformation\"\n\n    def run(self, root_folder, external_checks_dir=None, files=None, runner_filter=RunnerFilter()):\n        report = Report(self.check_type)\n        definitions = {}\n        definitions_raw = {}\n        parsing_errors = {}\n        files_list = []\n        if external_checks_dir:\n            for directory in external_checks_dir:\n                resource_registry.load_external_checks(directory)\n\n        if files:\n            for file in files:\n                (definitions[file], definitions_raw[file]) = parse(file)\n\n        if root_folder:\n            for root, d_names, f_names in os.walk(root_folder):\n                for file in f_names:\n                    file_ending = os.path.splitext(file)[1]\n                    if file_ending in CF_POSSIBLE_ENDINGS:\n                        files_list.append(os.path.join(root, file))\n\n            for file in files_list:\n                relative_file_path = f'/{os.path.relpath(file, os.path.commonprefix((root_folder, file)))}'\n                (definitions[relative_file_path], definitions_raw[relative_file_path]) = parse(file)\n\n        # Filter out empty files that have not been parsed successfully, and filter out non-CF template files\n        definitions = {k: v for k, v in definitions.items() if v and v.__contains__(\"Resources\")}\n        definitions_raw = {k: v for k, v in definitions_raw.items() if k in definitions.keys()}\n\n        for cf_file in definitions.keys():\n            if not 'Resources' in definitions[cf_file].keys():\n                continue\n            logging.debug(\"Template Dump for {}: {}\".format(cf_file, definitions[cf_file], indent=2))\n\n            # Get Parameter Defaults - Locate Refs in Template\n            refs = []\n            refs.extend(self._search_deep_keys('Ref', definitions[cf_file], []))\n\n            for ref in refs:\n                refname = ref.pop()\n                ref.pop()  # Get rid of the 'Ref' dict key\n\n                if 'Parameters' in definitions[cf_file].keys() and refname in definitions[cf_file][\n                    'Parameters'].keys():\n                    # TODO refactor into evaluations\n                    if 'Default' in definitions[cf_file]['Parameters'][refname].keys():\n                        logging.debug(\n                            \"Replacing Ref {} in file {} with default parameter value: {}\".format(refname, cf_file,\n                                                                                                  definitions[\n                                                                                                      cf_file][\n                                                                                                      'Parameters'][\n                                                                                                      refname][\n                                                                                                      'Default']))\n                        _set_in_dict(definitions[cf_file], ref,\n                                     definitions[cf_file]['Parameters'][refname]['Default'])\n\n                        ## TODO - Add Variable Eval Message for Output\n                        # Output in Checkov looks like this:\n                        # Variable versioning (of /.) evaluated to value \"True\" in expression: enabled = ${var.versioning}\n\n            for resource_name, resource in definitions[cf_file]['Resources'].items():\n                if resource_name == '__startline__' or resource_name == '__endline__':\n                    continue\n                resource_id = f\"{resource['Type']}.{resource_name}\"\n\n                # TODO refactor into context parsing\n                find_lines_result_list = list(find_lines(resource, '__startline__'))\n                if len(find_lines_result_list) >= 1:\n                    start_line = min(find_lines_result_list)\n                    end_line = max(list(find_lines(resource, '__endline__')))\n\n                    entity_lines_range = [start_line, end_line - 1]\n\n                    entity_code_lines = definitions_raw[cf_file][start_line - 1: end_line - 1]\n\n                    # TODO - Variable Eval Message!\n                    variable_evaluations = {}\n\n                    skipped_checks = []\n                    for line in entity_code_lines:\n                        skip_search = re.search(COMMENT_REGEX, str(line))\n                        if skip_search:\n                            skipped_checks.append(\n                                {\n                                    'id': skip_search.group(2),\n                                    'suppress_comment': skip_search.group(3)[1:] if skip_search.group(3) else \"No comment provided\"\n                                }\n                            )\n\n                    results = resource_registry.scan(cf_file, {resource_name: resource}, skipped_checks, runner_filter)\n                    for check, check_result in results.items():\n                        ### TODO - Need to get entity_code_lines and entity_lines_range\n                        record = Record(check_id=check.id, check_name=check.name, check_result=check_result,\n                                        code_block=entity_code_lines, file_path=cf_file,\n                                        file_line_range=entity_lines_range,\n                                        resource=resource_id, evaluations=variable_evaluations,\n                                        check_class=check.__class__.__module__)\n                        report.add_record(record=record)\n        return report\n\n    def _search_deep_keys(self, search_text, cfn_dict, path):\n        \"\"\"Search deep for keys and get their values\"\"\"\n        keys = []\n        if isinstance(cfn_dict, dict):\n            for key in cfn_dict:\n                pathprop = path[:]\n                pathprop.append(key)\n                if key == search_text:\n                    pathprop.append(cfn_dict[key])\n                    keys.append(pathprop)\n                    # pop the last element off for nesting of found elements for\n                    # dict and list checks\n                    pathprop = pathprop[:-1]\n                if isinstance(cfn_dict[key], dict):\n                    keys.extend(self._search_deep_keys(search_text, cfn_dict[key], pathprop))\n                elif isinstance(cfn_dict[key], list):\n                    for index, item in enumerate(cfn_dict[key]):\n                        pathproparr = pathprop[:]\n                        pathproparr.append(index)\n                        keys.extend(self._search_deep_keys(search_text, item, pathproparr))\n        elif isinstance(cfn_dict, list):\n            for index, item in enumerate(cfn_dict):\n                pathprop = path[:]\n                pathprop.append(index)\n                keys.extend(self._search_deep_keys(search_text, item, pathprop))\n\n        return keys\n\n\ndef _get_from_dict(data_dict, map_list):\n    return reduce(operator.getitem, map_list, data_dict)\n\n\ndef _set_in_dict(data_dict, map_list, value):\n    _get_from_dict(data_dict, map_list[:-1])[map_list[-1]] = value\n\n\ndef find_lines(node, kv):\n    if isinstance(node, list):\n        for i in node:\n            for x in find_lines(i, kv):\n                yield x\n    elif isinstance(node, dict):\n        if kv in node:\n            yield node[kv]\n        for j in node.values():\n            for x in find_lines(j, kv):\n                yield x\n", "path": "checkov/cloudformation/runner.py"}]}