Repository: bridgecrewio/checkov

Issue:
Checkov fail to parse Kubernetes annotations when Suppressing comments are in file
**Describe the issue**
Checkov fail to parse Kubernetes annotations when Suppressing comments in file

**Examples**
Please share an example code sample (in the IaC of your choice) + the expected outcomes.

**Exception Trace**
Here is the output of the run

```python
root@7a94243e1c98:/# checkov -d /app/kubernetes --external-checks-dir /policies/kubernetes --framework kubernetes
2023-04-27 10:33:13,911 [MainThread  ] [ERROR]  Exception traceback:
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/checkov/main.py", line 462, in run
    self.scan_reports = runner_registry.run(
                        ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/checkov/common/runners/runner_registry.py", line 102, in run
    self.runners[0].run(root_folder, external_checks_dir=external_checks_dir, files=files,
  File "/usr/local/lib/python3.11/site-packages/checkov/kubernetes/runner.py", line 102, in run
    self.context = build_definitions_context(self.definitions, self.definitions_raw)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/checkov/kubernetes/kubernetes_utils.py", line 174, in build_definitions_context
    skipped_checks = get_skipped_checks(resource)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/checkov/kubernetes/kubernetes_utils.py", line 102, in get_skipped_checks
    logging.debug(f"Parse of Annotation Failed for {metadata['annotations'][key]}: {entity_conf}")
                                                    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^
TypeError: list indices must be integers or slices, not str
Traceback (most recent call last):
  File "/usr/local/bin/checkov", line 9, in <module>
    sys.exit(Checkov().run())
             ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/checkov/main.py", line 462, in run
    self.scan_reports = runner_registry.run(
                        ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/checkov/common/runners/runner_registry.py", line 102, in run
    self.runners[0].run(root_folder, external_checks_dir=external_checks_dir, files=files,
  File "/usr/local/lib/python3.11/site-packages/checkov/kubernetes/runner.py", line 102, in run
    self.context = build_definitions_context(self.definitions, self.definitions_raw)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/checkov/kubernetes/kubernetes_utils.py", line 174, in build_definitions_context
    skipped_checks = get_skipped_checks(resource)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/checkov/kubernetes/kubernetes_utils.py", line 102, in get_skipped_checks
    logging.debug(f"Parse of Annotation Failed for {metadata['annotations'][key]}: {entity_conf}")
                                                    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^
TypeError: list indices must be integers or slices, not str
```

Here is the file I want to check:
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    hasdadsah: haha
  annotations:
    checkov.io/skip1: DUMMY_K8S_001=I have not set CPU limits as I want BestEffort QoS
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80
```

And here is the policy:
```yaml
metadata:
  name: "Dummy Check Kubernetes"
  id: "DUMMY_K8S_001"
  category: "GENERAL_SECURITY"
scope:
  provider: kubernetes
definition:
  cond_type: "attribute"
  resource_types: "all"
  attribute: "metadata.labels.hasdadsah"
  operator: "not_exists"
```

**Desktop (please complete the following information):**
 - Docker - Debian based on image python:3.11.1-buster
 - Checkov Version 2.3.199
 - 
**Additional context**
The policy works fine when no Suppression comment is added to the subject



Discussion:
hey @paulozava thanks for reaching out.

Looks like we don't support custom policies to be suppressed 😄 Currently the policy/check ID has to contain either `CKV_K8S` or `CKV2_K8S` otherwise it comes to this error. I will fix it and it should be released on Sunday/Monday.

Resolving patch:
diff --git a/checkov/kubernetes/kubernetes_utils.py b/checkov/kubernetes/kubernetes_utils.py
--- a/checkov/kubernetes/kubernetes_utils.py
+++ b/checkov/kubernetes/kubernetes_utils.py
@@ -84,23 +84,19 @@ def get_skipped_checks(entity_conf: dict[str, Any]) -> list[_SkippedCheck]:
             for key in annotation:
                 skipped_item: "_SkippedCheck" = {}
                 if "checkov.io/skip" in key or "bridgecrew.io/skip" in key:
-                    if "CKV_K8S" in annotation[key] or "BC_K8S" in annotation[key] or "CKV2_K8S" in annotation[key]:
-                        if "=" in annotation[key]:
-                            (skipped_item["id"], skipped_item["suppress_comment"]) = annotation[key].split("=")
-                        else:
-                            skipped_item["id"] = annotation[key]
-                            skipped_item["suppress_comment"] = "No comment provided"
-
-                        # No matter which ID was used to skip, save the pair of IDs in the appropriate fields
-                        if bc_id_mapping and skipped_item["id"] in bc_id_mapping:
-                            skipped_item["bc_id"] = skipped_item["id"]
-                            skipped_item["id"] = bc_id_mapping[skipped_item["id"]]
-                        elif metadata_integration.check_metadata:
-                            skipped_item["bc_id"] = metadata_integration.get_bc_id(skipped_item["id"])
-                        skipped.append(skipped_item)
+                    if "=" in annotation[key]:
+                        (skipped_item["id"], skipped_item["suppress_comment"]) = annotation[key].split("=")
                     else:
-                        logging.debug(f"Parse of Annotation Failed for {metadata['annotations'][key]}: {entity_conf}")
-                        continue
+                        skipped_item["id"] = annotation[key]
+                        skipped_item["suppress_comment"] = "No comment provided"
+
+                    # No matter which ID was used to skip, save the pair of IDs in the appropriate fields
+                    if bc_id_mapping and skipped_item["id"] in bc_id_mapping:
+                        skipped_item["bc_id"] = skipped_item["id"]
+                        skipped_item["id"] = bc_id_mapping[skipped_item["id"]]
+                    elif metadata_integration.check_metadata:
+                        skipped_item["bc_id"] = metadata_integration.get_bc_id(skipped_item["id"])
+                    skipped.append(skipped_item)
     return skipped
 
 


Test patch:
diff --git a/tests/kubernetes/test_kubernetes_utils.py b/tests/kubernetes/test_kubernetes_utils.py
new file mode 100644
--- /dev/null
+++ b/tests/kubernetes/test_kubernetes_utils.py
@@ -0,0 +1,58 @@
+from operator import itemgetter
+
+from checkov.kubernetes.kubernetes_utils import get_skipped_checks
+
+
+def test_get_skipped_checks():
+    # given
+    manifest = {
+        "apiVersion": "v1",
+        "kind": "Pod",
+        "metadata": {
+            "name": "nginx",
+            "labels": {"test": "test", "__startline__": 6, "__endline__": 7},
+            "annotations": {
+                "checkov.io/skip1": "CKV_K8S_11=I have not set CPU limits as I want BestEffort QoS",
+                "checkov.io/skip2": "CKV2_CUSTOM_1=I have not set CPU limits as I want BestEffort QoS",
+                "checkov.io/skip3": "CKV_K8S_14",
+                "checkov.io/skip4": "CUSTOM_1",
+                "__startline__": 8,
+                "__endline__": 12,
+            },
+            "__startline__": 4,
+            "__endline__": 12,
+        },
+        "spec": {
+            "containers": [
+                {
+                    "name": "nginx",
+                    "image": "nginx:1.14.2",
+                    "ports": [{"containerPort": 80, "__startline__": 17, "__endline__": 17}],
+                    "__startline__": 14,
+                    "__endline__": 17,
+                }
+            ],
+            "__startline__": 13,
+            "__endline__": 17,
+        },
+        "__startline__": 1,
+        "__endline__": 17,
+    }
+
+    # when
+    skipped = get_skipped_checks(entity_conf=manifest)
+
+    # then
+    # remove 'bc_id' if present
+    for skip in skipped:
+        skip.pop("bc_id", None)
+
+    assert sorted(skipped, key=itemgetter("id")) == sorted(
+        [
+            {"id": "CKV_K8S_11", "suppress_comment": "I have not set CPU limits as I want BestEffort QoS"},
+            {"id": "CKV2_CUSTOM_1", "suppress_comment": "I have not set CPU limits as I want BestEffort QoS"},
+            {"id": "CKV_K8S_14", "suppress_comment": "No comment provided"},
+            {"id": "CUSTOM_1", "suppress_comment": "No comment provided"},
+        ],
+        key=itemgetter("id"),
+    )