diff --git a/doc/scripts/scan-sbom.sh b/doc/scripts/scan-sbom.sh index 4eed972..c17be66 100755 --- a/doc/scripts/scan-sbom.sh +++ b/doc/scripts/scan-sbom.sh @@ -139,6 +139,10 @@ python3 - "$RESULTS" "$CHARTMAP" "$SEVERITY" "$TOTAL" "$(ts)" "$SUMMARY_TSV" <<' import sys results, chartmap, sev, total, tstamp, tsv_out = sys.argv[1:7] total=int(total) +# 표시 심각도 = 실제 스캔한 SEVERITY 만 (순위 내림차순). MED/LOW 는 스캔 안 하면 항상 0이므로 제외. +RANK=["CRITICAL","HIGH","MEDIUM","LOW"]; IDX={"CRITICAL":1,"HIGH":2,"MEDIUM":3,"LOW":4} +scanned=[s.strip().upper() for s in sev.split(",") if s.strip()] +shown=[s for s in RANK if s in scanned] or ["CRITICAL","HIGH"] cm={} try: for l in open(chartmap): @@ -152,29 +156,31 @@ for l in open(results): img=p[0] if p[5]=="OK" or img not in best or best[img][5]!="OK": best[img]=p rows=list(best.values()) -def key(r): - try: return (-int(r[1]),-int(r[2])) - except: return (1,0) -rows.sort(key=key) +def cnt(r,s): + try: return int(r[IDX[s]]) + except: return 0 +rows.sort(key=lambda r: tuple(-cnt(r,s) for s in shown)) ok=[r for r in rows if r[5]=="OK"]; err=[r for r in rows if r[5]!="OK"] -tc=sum(int(r[1]) for r in ok); th=sum(int(r[2]) for r in ok) +totals={s:sum(cnt(r,s) for r in ok) for s in shown} secs=[int(r[6]) for r in rows if len(r)>=7 and r[6].isdigit()] +# TSV: chart, image, , status, sec (CRITICAL 은 첫 카운트 열 = col3) with open(tsv_out,"w") as f: for r in rows: - f.write(f"{cm.get(r[0],'')}\t{r[0]}\t{r[1]}\t{r[2]}\t{r[3]}\t{r[4]}\t{r[5]}\t{r[6] if len(r)>=7 else ''}\n") + cols=[cm.get(r[0],""), r[0]] + [str(cnt(r,s)) for s in shown] + [r[5], r[6] if len(r)>=7 else ""] + f.write("\t".join(cols)+"\n") print("# Trivy SBOM 취약점 요약\n") print(f"- 생성: {tstamp}") print(f"- 총 소요: **{total//60}분 {total%60}초** (SBOM {len(rows)}개)") print(f"- 성공/실패: **{len(ok)} / {len(err)}**") print(f"- 집계 심각도: `{sev}`") -print(f"- 취약점 합계: **CRITICAL {tc}**, **HIGH {th}**") +print("- 취약점 합계: " + ", ".join(f"**{s} {totals[s]}**" for s in shown)) if secs: print(f"- SBOM당 스캔시간: 최소 {min(secs)}s / 최대 {max(secs)}s / 평균 {sum(secs)//len(secs)}s") print() -print("| Chart | Image | CRIT | HIGH | MED | LOW | Status | Sec |") -print("|---|---|---:|---:|---:|---:|---|---:|") +print("| Chart | Image | " + " | ".join(shown) + " | Status | Sec |") +print("|---|---|" + "---:|"*len(shown) + "---|---:|") for r in rows: - sec=r[6] if len(r)>=7 else "-" - print(f"| {cm.get(r[0],'')} | `{r[0]}` | {r[1]} | {r[2]} | {r[3]} | {r[4]} | {r[5]} | {sec} |") + cells=" | ".join(str(cnt(r,s)) for s in shown) + print(f"| {cm.get(r[0],'')} | `{r[0]}` | {cells} | {r[5]} | {r[6] if len(r)>=7 else '-'} |") PY {