Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kubernetes): Improve k8s perf #5083

Merged
merged 4 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion checkov/common/output/ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def _prioritize_findings(self, records: list[Record]) -> list[Record]:
if 0 < OPENAI_MAX_FINDINGS < len(records):
# the higher severities should be preferred
sorted_records = sorted(
records, key=lambda record: record.severity.level if record.severity else 0, reverse=True
records, key=lambda record: record.severity.level if record.severity else 0, reverse=True # type:ignore[has-type]
)

# to protect the user, just take the last x findings
Expand Down
6 changes: 3 additions & 3 deletions checkov/common/output/baseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ def add_findings_from_report(self, report: Report) -> None:
for check in report.failed_checks:
try:
existing = next(
x for x in self.path_failed_checks_map[check.file_path] if x["resource"] == check.resource
x for x in self.path_failed_checks_map[check.file_path] if x["resource"] == check.resource # type:ignore[has-type]
)
except StopIteration:
existing = {"resource": check.resource, "check_ids": []}
existing = {"resource": check.resource, "check_ids": []} # type:ignore[has-type]
self.path_failed_checks_map[check.file_path].append(existing)
existing["check_ids"].append(check.check_id)
existing["check_ids"].sort() # Sort the check IDs to be nicer to the eye
Expand Down Expand Up @@ -84,7 +84,7 @@ def compare_and_reduce_reports(self, scan_reports: list[Report]) -> None:

def _is_check_in_baseline(self, check: Record) -> bool:
failed_check_id = check.check_id
failed_check_resource = check.resource
failed_check_resource = check.resource # type:ignore[has-type]
for baseline_failed_check in self.failed_checks:
for finding in baseline_failed_check["findings"]:
if finding["resource"] == failed_check_resource and failed_check_id in finding["check_ids"]:
Expand Down
2 changes: 2 additions & 0 deletions checkov/common/output/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os
import re
from functools import lru_cache
from pathlib import Path
from typing import Union, List, Tuple, Optional, Dict, Any

Expand Down Expand Up @@ -90,6 +91,7 @@ def __init__(
self.definition_context_file_path = definition_context_file_path

@staticmethod
@lru_cache(maxsize=None)
def _determine_repo_file_path(file_path: Union[str, "os.PathLike[str]"]) -> str:
# matches file paths given in the BC platform and should always be a unix path
repo_file_path = Path(file_path)
Expand Down
23 changes: 13 additions & 10 deletions checkov/kubernetes/kubernetes_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import logging
import os
from copy import deepcopy
from typing import Dict, Any, TYPE_CHECKING

import dpath

from checkov.common.models.enums import CheckResult
from checkov.common.util.consts import LINE_FIELD_NAMES, START_LINE, END_LINE
from checkov.runner_filter import RunnerFilter
from checkov.common.bridgecrew.integration_features.features.policy_metadata_integration import integration as metadata_integration
from checkov.common.models.consts import YAML_COMMENT_MARK
Expand All @@ -19,6 +19,7 @@
if TYPE_CHECKING:
from checkov.common.typing import _SkippedCheck, _CheckResult, _EntityContext

EXCLUDED_FILE_NAMES = {"package.json", "package-lock.json"}
K8_POSSIBLE_ENDINGS = {".yaml", ".yml", ".json"}
DEFAULT_NESTED_RESOURCE_TYPE = "Pod"
SUPPORTED_POD_CONTAINERS_TYPES = {"Deployment", "DeploymentConfig", "DaemonSet", "Job", "ReplicaSet", "ReplicationController", "StatefulSet"}
Expand All @@ -39,7 +40,7 @@ def get_folder_definitions(
file_ending = os.path.splitext(file)[1]
if file_ending in K8_POSSIBLE_ENDINGS:
full_path = os.path.join(root, file)
if "/." not in full_path and file not in ['package.json', 'package-lock.json']:
if "/." not in full_path and file not in EXCLUDED_FILE_NAMES:
# skip temp directories
files_list.append(full_path)
return get_files_definitions(files_list)
Expand Down Expand Up @@ -121,12 +122,12 @@ def build_definitions_context(
definitions: dict[str, list[dict[str, Any]]], definitions_raw: dict[str, list[tuple[int, str]]]
) -> dict[str, dict[str, Any]]:
definitions_context: Dict[str, Dict[str, Any]] = {}
definitions = deepcopy(definitions)
# iterate on the files
for file_path, resources in definitions.items():

for resource in resources:
if resource.get("kind") == "List":
# this could be inefficient, if more than one 'List' object exists in the same file
resources = resources[:]
resources.extend(item for item in resource.get("items", []) if item)
resources.remove(resource)

Expand All @@ -137,8 +138,8 @@ def build_definitions_context(
resource_id = get_resource_id(resource)
if not resource_id:
continue
start_line = resource["__startline__"]
end_line = min(resource["__endline__"], len(definitions_raw[file_path]))
start_line = resource[START_LINE]
end_line = min(resource[END_LINE], len(definitions_raw[file_path]))
first_line_index = 0
# skip empty lines
while not str.strip(definitions_raw[file_path][first_line_index][1]):
Expand Down Expand Up @@ -212,7 +213,7 @@ def get_resource_id(resource: dict[str, Any] | None) -> str | None:
name = metadata.get("name")
if name:
return f'{resource_type}.{namespace}.{name}'
labels = deepcopy(metadata.get("labels"))
labels = metadata.get("labels")
if labels:
return build_resource_id_from_labels(resource_type, namespace, labels, resource)
return None
Expand All @@ -222,9 +223,11 @@ def build_resource_id_from_labels(resource_type: str,
namespace: str,
labels: dict[str, str],
resource: dict[str, Any]) -> str:
labels.pop('__startline__', None)
labels.pop('__endline__', None)
labels_list = [f"{k}-{v}" for k, v in labels.items()]
labels_list = [
f"{label}-{value}"
for label, value in labels.items()
if label not in LINE_FIELD_NAMES
]
labels_string = ".".join(labels_list) if labels_list else "default"
parent_resource = resource.get(PARENT_RESOURCE_KEY_NAME)
if parent_resource:
Expand Down