1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#!/usr/bin/env bash
set -euo pipefail
if [ "$#" -lt 1 ]; then
echo "Usage: $0 doca-*-vuln.csv [more.csv ...]" >&2
exit 1
fi
python3 - "$@" <<'PY'
import csv
import os
import re
import sys
FILENAME_RE = re.compile(
r"^doca-(?P<container>.+)-(?P<version>\d+\.\d+\.\d+)-(?P<host>host|dpu)-vuln\.csv$"
)
META_COLUMNS = ["doca_version", "doca_host", "doca_container"]
def parse_metadata(path):
base = os.path.basename(path)
match = FILENAME_RE.match(base)
if not match:
raise ValueError(
f"Filename does not match expected pattern: {base}\n"
f"Expected: doca-(container)-(version)-(host)-vuln.csv"
)
return {
"doca_version": match.group("version"),
"doca_host": match.group("host"),
"doca_container": match.group("container"),
}
def is_critical(row):
fields_to_check = [
"nvd_severity",
"severity",
"osv_severity",
]
for field in fields_to_check:
value = row.get(field, "")
if value and "CRITICAL" in value.upper():
return True
if value and "HIGH" in value.upper():
return True
return False
def main(paths):
writer = None
output_header = None
for path in paths:
metadata = parse_metadata(path)
with open(path, "r", encoding="utf-8", newline="") as f:
reader = csv.DictReader(f)
if reader.fieldnames is None:
continue
if writer is None:
original_header = reader.fieldnames
output_header = META_COLUMNS + original_header
writer = csv.DictWriter(
sys.stdout,
fieldnames=output_header,
extrasaction="ignore",
)
writer.writeheader()
for row in reader:
if not is_critical(row):
continue
output_row = {}
output_row.update(metadata)
output_row.update(row)
writer.writerow(output_row)
if __name__ == "__main__":
main(sys.argv[1:])
PY
|