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)``.
|
Each row is ``(image, container, total, fixable, unfixable)``.
|
||||||
"""
|
"""
|
||||||
lines = ["Other containers:"]
|
lines = ["Other containers with findings:", ""]
|
||||||
for image, container, total, fixable, unfixable in rows:
|
for image, container, total, fixable, unfixable in rows:
|
||||||
label = container or image
|
label = f"{image} [{container}]" if container else image
|
||||||
lines.append(f"- {label}: {fixable}/{total}")
|
lines.append(f"* {label}: {fixable}/{total} (fixable/total)")
|
||||||
lines.append(f"Total: {sum(row[2] for row in rows)} in {len(rows)}")
|
lines += ["", f"Total: {sum(row[2] for row in rows)} CVE(s) in {len(rows)} container(s)"]
|
||||||
return "\n".join(lines)
|
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(
|
def build_missing_body(
|
||||||
missing: list[str], not_scanned: list[str] | None = None
|
missing: list[str], not_scanned: list[str] | None = None
|
||||||
) -> str:
|
) -> str:
|
||||||
@@ -1365,12 +1391,23 @@ def send_notifications(
|
|||||||
rows.append((target.image, container, total, fixable, unfixable))
|
rows.append((target.image, container, total, fixable, unfixable))
|
||||||
|
|
||||||
if rows:
|
if rows:
|
||||||
send_notification_parts(
|
bodies = build_other_containers_bodies(rows)
|
||||||
settings,
|
for index, body in enumerate(bodies, 1):
|
||||||
stats,
|
if len(bodies) == 1:
|
||||||
f"{settings.apprise_title_prefix}: other containers",
|
title = f"{settings.apprise_title_prefix}: other containers"
|
||||||
build_other_containers_body(rows),
|
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(
|
def resolve_container_images(
|
||||||
|
|||||||
+7
-5
@@ -496,15 +496,17 @@ class ReportTests(unittest.TestCase):
|
|||||||
self.assertIn("Total: 1/1 (fixable/total)", body)
|
self.assertIn("Total: 1/1 (fixable/total)", body)
|
||||||
|
|
||||||
def test_build_other_containers_body_has_counts_per_container(self) -> None:
|
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),
|
("nginx:1.27", "web-worker", 3, 2, 1),
|
||||||
("redis:7", "cache", 4, 0, 4),
|
("redis:7", "cache", 4, 0, 4),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
self.assertIn("- web-worker: 2/3", body)
|
body = bodies[0]
|
||||||
self.assertIn("- cache: 0/4", body)
|
self.assertIn("Other containers with findings", body)
|
||||||
self.assertIn("Total: 7 in 2", 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:
|
def test_build_missing_body_separates_missing_and_unscanned(self) -> None:
|
||||||
body = scan.build_missing_body(["gone"], ["web"])
|
body = scan.build_missing_body(["gone"], ["web"])
|
||||||
@@ -668,7 +670,7 @@ printf '%s\\n' "$*" >> "$APPRISE_LOG"
|
|||||||
self.assertIn("Container: web", notification)
|
self.assertIn("Container: web", notification)
|
||||||
self.assertIn("CVE-2026-0001", notification)
|
self.assertIn("CVE-2026-0001", notification)
|
||||||
self.assertIn("Vulnerability scan: other containers", 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)
|
self.assertIn("1/1 (fixable/total)", notification)
|
||||||
# The important container must not also appear in the summary.
|
# The important container must not also appear in the summary.
|
||||||
self.assertNotIn("testphp-php [web]", notification)
|
self.assertNotIn("testphp-php [web]", notification)
|
||||||
|
|||||||
Reference in new issue
Block a user