thanks llms!
This commit is contained in:
1 parent
cd587b9977
commit
beb2f544d9
2 files changed
+54
-15
No files matched your search
@@ -1008,14 +1008,40 @@ def build_other_containers_body(
|
||||
|
||||
Each row is ``(image, container, total, fixable, unfixable)``.
|
||||
"""
|
||||
lines = ["Other containers:"]
|
||||
lines = ["Other containers with findings:", ""]
|
||||
for image, container, total, fixable, unfixable in rows:
|
||||
label = container or image
|
||||
lines.append(f"- {label}: {fixable}/{total}")
|
||||
lines.append(f"Total: {sum(row[2] for row in rows)} in {len(rows)}")
|
||||
label = f"{image} [{container}]" if container else image
|
||||
lines.append(f"* {label}: {fixable}/{total} (fixable/total)")
|
||||
lines += ["", f"Total: {sum(row[2] for row in rows)} CVE(s) in {len(rows)} container(s)"]
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def _chunk_list(items: list[object], size: int) -> list[list[object]]:
|
||||
if size <= 0:
|
||||
return [items]
|
||||
return [items[i : i + size] for i in range(0, len(items), size)]
|
||||
|
||||
|
||||
def build_other_containers_bodies(
|
||||
rows: list[tuple[str, str, int, int, int]],
|
||||
) -> list[str]:
|
||||
"""Split the summary by container groups so each message stays small."""
|
||||
if not rows:
|
||||
return []
|
||||
bodies: list[str] = []
|
||||
for chunk in _chunk_list(rows, 12):
|
||||
lines = ["Other containers with findings:", ""]
|
||||
for image, container, total, fixable, unfixable in chunk:
|
||||
label = f"{image} [{container}]" if container else image
|
||||
lines.append(f"* {label}: {fixable}/{total} (fixable/total)")
|
||||
lines += ["", f"Total: {sum(row[2] for row in chunk)} CVE(s) in {len(chunk)} container(s)"]
|
||||
bodies.append("\n".join(lines))
|
||||
if len(bodies) > 1:
|
||||
overall = f"Total: {sum(row[2] for row in rows)} CVE(s) in {len(rows)} container(s)"
|
||||
bodies[-1] = bodies[-1] + "\n\n" + overall
|
||||
return bodies
|
||||
|
||||
|
||||
def build_missing_body(
|
||||
missing: list[str], not_scanned: list[str] | None = None
|
||||
) -> str:
|
||||
@@ -1365,12 +1391,23 @@ def send_notifications(
|
||||
rows.append((target.image, container, total, fixable, unfixable))
|
||||
|
||||
if rows:
|
||||
send_notification_parts(
|
||||
settings,
|
||||
stats,
|
||||
f"{settings.apprise_title_prefix}: other containers",
|
||||
build_other_containers_body(rows),
|
||||
)
|
||||
bodies = build_other_containers_bodies(rows)
|
||||
for index, body in enumerate(bodies, 1):
|
||||
if len(bodies) == 1:
|
||||
title = f"{settings.apprise_title_prefix}: other containers"
|
||||
else:
|
||||
title = f"{settings.apprise_title_prefix}: other containers [{index}/{len(bodies)}]"
|
||||
if len(title) > 200:
|
||||
original = f"{settings.apprise_title_prefix}: other containers"
|
||||
suffix = f" [{index}/{len(bodies)}]"
|
||||
title = original[: 200 - len(suffix) - 3] + "..." + suffix
|
||||
body_truncated = _truncate_text(body, notification_limit(settings))
|
||||
if notify(settings, title, body_truncated):
|
||||
continue
|
||||
body_truncated = _truncate_text(body, min(notification_limit(settings), 1100))
|
||||
if notify(settings, title, body_truncated):
|
||||
continue
|
||||
stats.notify_errors += 1
|
||||
|
||||
|
||||
def resolve_container_images(
|
||||
|
||||
+7
-5
@@ -496,15 +496,17 @@ class ReportTests(unittest.TestCase):
|
||||
self.assertIn("Total: 1/1 (fixable/total)", body)
|
||||
|
||||
def test_build_other_containers_body_has_counts_per_container(self) -> None:
|
||||
body = scan.build_other_containers_body(
|
||||
bodies = scan.build_other_containers_bodies(
|
||||
[
|
||||
("nginx:1.27", "web-worker", 3, 2, 1),
|
||||
("redis:7", "cache", 4, 0, 4),
|
||||
]
|
||||
)
|
||||
self.assertIn("- web-worker: 2/3", body)
|
||||
self.assertIn("- cache: 0/4", body)
|
||||
self.assertIn("Total: 7 in 2", body)
|
||||
body = bodies[0]
|
||||
self.assertIn("Other containers with findings", body)
|
||||
self.assertIn("nginx:1.27 [web-worker]: 2/3 (fixable/total)", body)
|
||||
self.assertIn("redis:7 [cache]: 0/4 (fixable/total)", body)
|
||||
self.assertIn("Total: 7 CVE(s) in 2 container(s)", body)
|
||||
|
||||
def test_build_missing_body_separates_missing_and_unscanned(self) -> None:
|
||||
body = scan.build_missing_body(["gone"], ["web"])
|
||||
@@ -668,7 +670,7 @@ printf '%s\\n' "$*" >> "$APPRISE_LOG"
|
||||
self.assertIn("Container: web", notification)
|
||||
self.assertIn("CVE-2026-0001", notification)
|
||||
self.assertIn("Vulnerability scan: other containers", notification)
|
||||
self.assertIn("cache: 1/1", notification)
|
||||
self.assertIn("redis:7 [cache]: 1/1 (fixable/total)", notification)
|
||||
self.assertIn("1/1 (fixable/total)", notification)
|
||||
# The important container must not also appear in the summary.
|
||||
self.assertNotIn("testphp-php [web]", notification)
|
||||
|
||||
Reference in new issue
Block a user