more changes
This commit is contained in:
1 parent
0fe06f2ba5
commit
be5d4dd97f
3 files changed
+152
-55
No files matched your search
@@ -1000,7 +1000,9 @@ def summary_table(
|
||||
"""Render image/container/severity counts as a monospaced markdown table."""
|
||||
headers = ["Image", "Container"] + [name[0] for name in severities]
|
||||
table_rows: list[list[str]] = []
|
||||
for image, container, counts, fixable_counts in rows:
|
||||
for image, container, counts, fixable_counts in sorted(
|
||||
rows, key=lambda row: (row[1].casefold(), row[0].casefold())
|
||||
):
|
||||
cells = [short_image(image), container or "-"]
|
||||
cells += [
|
||||
f"{fixable_counts.get(name, 0)}/{counts.get(name, 0)}"
|
||||
@@ -1061,28 +1063,6 @@ def build_important_body(
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def build_important_summary_body(
|
||||
container: str, target: ScanTarget, result: ScanResult, min_severity: str
|
||||
) -> str:
|
||||
"""Summary for an important container with no findings above threshold."""
|
||||
entries = cve_entries(result, severity_rank(min_severity))
|
||||
counts = severity_counts(entries)
|
||||
fixable_counts = {severity: 0 for severity in REPORTED_SEVERITIES}
|
||||
for entry in entries:
|
||||
if entry.fixable:
|
||||
fixable_counts[entry.severity] += 1
|
||||
|
||||
severities = visible_severities(severity_rank(min_severity))
|
||||
lines = [
|
||||
summary_table(
|
||||
[(target.image, container, counts, fixable_counts)], severities
|
||||
),
|
||||
"",
|
||||
"No CVEs at or above the notification threshold.",
|
||||
]
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def _chunk_list(items: list[object], size: int) -> list[list[object]]:
|
||||
if size <= 0:
|
||||
return [items]
|
||||
@@ -1093,7 +1073,7 @@ def build_other_containers_bodies(
|
||||
rows: list,
|
||||
rank: int,
|
||||
) -> list[str]:
|
||||
"""Split the summary by container groups so each message stays small."""
|
||||
"""Split the summary by image groups so each message stays small."""
|
||||
if not rows:
|
||||
return []
|
||||
severities = visible_severities(rank)
|
||||
@@ -1124,7 +1104,21 @@ def build_final_summary_body(
|
||||
severities = visible_severities(severity_rank(min_severity))
|
||||
table_rows: list[tuple[str, str, dict[str, int], dict[str, int]]] = []
|
||||
package_lines: list[str] = []
|
||||
# Merge important containers that share an image into one row/package line.
|
||||
by_image: dict[str, tuple[list[str], ScanTarget, ScanResult]] = {}
|
||||
for name, target, result in important_rows:
|
||||
if target.image in by_image:
|
||||
by_image[target.image][0].append(name)
|
||||
else:
|
||||
by_image[target.image] = ([name], target, result)
|
||||
groups = sorted(
|
||||
(
|
||||
(", ".join(sorted(names, key=str.casefold)), target, result)
|
||||
for names, target, result in by_image.values()
|
||||
),
|
||||
key=lambda group: (group[0].casefold(), group[1].image.casefold()),
|
||||
)
|
||||
for name, target, result in groups:
|
||||
entries = cve_entries(result, severity_rank(min_severity))
|
||||
counts = severity_counts(entries)
|
||||
fixable_counts = {severity: 0 for severity in REPORTED_SEVERITIES}
|
||||
@@ -1168,7 +1162,7 @@ def build_final_summary_body(
|
||||
lines += [
|
||||
"",
|
||||
f"Overall severity: {severity_text(overall_counts, overall_fixable_counts, severities)}",
|
||||
f"Overall: {overall_fixable}/{overall_total} fixable/total in {len(all_rows)} container(s)",
|
||||
f"Overall: {overall_fixable}/{overall_total} fixable/total in {len(all_rows)} image(s)",
|
||||
]
|
||||
return "\n".join(lines)
|
||||
|
||||
@@ -1451,7 +1445,11 @@ def build_container_rows(
|
||||
skip: set[str] | None = None,
|
||||
include_empty: bool = False,
|
||||
) -> list:
|
||||
"""Build ``(image, container, total, fixable, unfixable, counts, fixable_counts)`` rows."""
|
||||
"""Build ``(image, containers, total, fixable, unfixable, counts, fixable_counts)`` rows.
|
||||
|
||||
One row per image: containers that share the image are merged into a single
|
||||
row so its counts are not repeated.
|
||||
"""
|
||||
skip = skip or set()
|
||||
rows: list = []
|
||||
for target in targets:
|
||||
@@ -1467,12 +1465,17 @@ def build_container_rows(
|
||||
for entry in entries:
|
||||
if entry.fixable:
|
||||
fixable_counts[entry.severity] += 1
|
||||
for container in target.containers or [""]:
|
||||
if container and container in skip:
|
||||
if target.containers:
|
||||
containers = [name for name in target.containers if name not in skip]
|
||||
if not containers:
|
||||
continue
|
||||
rows.append(
|
||||
(target.image, container, total, fixable, unfixable, counts, fixable_counts)
|
||||
)
|
||||
container = ", ".join(sorted(containers, key=str.casefold))
|
||||
else:
|
||||
container = ""
|
||||
rows.append(
|
||||
(target.image, container, total, fixable, unfixable, counts, fixable_counts)
|
||||
)
|
||||
rows.sort(key=lambda row: (row[1].casefold(), row[0].casefold()))
|
||||
return rows
|
||||
|
||||
|
||||
@@ -1514,20 +1517,19 @@ def send_notifications(
|
||||
|
||||
important_rows.append((name, target, result))
|
||||
entries = cve_entries(result, settings.notify_rank)
|
||||
report_path = os.path.join(settings.report_dir, f"{report_slug(image)}.json")
|
||||
if entries:
|
||||
body = build_important_body(
|
||||
name, target, result, report_path, settings.notify_min_severity
|
||||
)
|
||||
else:
|
||||
if not entries:
|
||||
# No individual notification for clean containers; the final
|
||||
# summary table already lists them with 0/0 totals.
|
||||
log(
|
||||
"DEBUG",
|
||||
f"Important container {name} ({short_image(image)}) has no findings at or above "
|
||||
f"{settings.notify_min_severity}",
|
||||
)
|
||||
body = build_important_summary_body(
|
||||
name, target, result, settings.notify_min_severity
|
||||
)
|
||||
continue
|
||||
report_path = os.path.join(settings.report_dir, f"{report_slug(image)}.json")
|
||||
body = build_important_body(
|
||||
name, target, result, report_path, settings.notify_min_severity
|
||||
)
|
||||
title = f"{settings.apprise_title_prefix}: {name} ({short_image(image)})"
|
||||
log(
|
||||
"DEBUG",
|
||||
|
||||
Reference in new issue
Block a user