Publish curated ITWorx_MCP_Hub source from 2aa63ba527a98b38b4d28f2a1bb85b1b1dbe7f6d
This commit is contained in:
1 parent
49627c7a7c
commit
378ae83d30
22 files changed
+4055
-81
No files matched your search
@@ -16,6 +16,7 @@ satisfying the release gate for that finding.
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import sys
|
||||
from datetime import date, timedelta
|
||||
@@ -28,6 +29,52 @@ if str(_ROOT_DIR) not in sys.path:
|
||||
from scripts.packlib import brussels_now, load_json # noqa: E402
|
||||
|
||||
|
||||
def _affected_image_digests(row: dict[str, object], images: dict[str, object]) -> dict[str, str]:
|
||||
"""Select current image bindings by scan tag, with a legacy full-inventory fallback."""
|
||||
if not images:
|
||||
raise ValueError("--image-digests must contain a non-empty images map")
|
||||
|
||||
if "affectedImages" not in row:
|
||||
services = list(images)
|
||||
else:
|
||||
affected_images = row.get("affectedImages")
|
||||
if (
|
||||
not isinstance(affected_images, list)
|
||||
or not affected_images
|
||||
or any(not isinstance(tag, str) or not tag.strip() for tag in affected_images)
|
||||
or len(set(affected_images)) != len(affected_images)
|
||||
):
|
||||
raise ValueError("scan affectedImages must be a non-empty list of unique image tags")
|
||||
|
||||
services_by_tag: dict[str, list[str]] = {}
|
||||
for service, entry in images.items():
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
tag = entry.get("tag")
|
||||
if isinstance(tag, str) and tag:
|
||||
services_by_tag.setdefault(tag, []).append(service)
|
||||
|
||||
services = []
|
||||
for tag in affected_images:
|
||||
matches = services_by_tag.get(tag, [])
|
||||
if len(matches) != 1:
|
||||
raise ValueError(
|
||||
f"scan image {tag} must resolve to exactly one current image service"
|
||||
)
|
||||
services.append(matches[0])
|
||||
|
||||
bindings: dict[str, str] = {}
|
||||
for service in services:
|
||||
entry = images.get(service)
|
||||
if not isinstance(entry, dict):
|
||||
raise ValueError(f"image evidence for {service} must be an object")
|
||||
digest = entry.get("digest") or entry.get("imageId")
|
||||
if not isinstance(digest, str) or not digest:
|
||||
raise ValueError(f"image evidence for {service} has no immutable digest or imageId")
|
||||
bindings[service] = digest
|
||||
return bindings
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--scan-summary", required=True, type=Path)
|
||||
@@ -46,25 +93,41 @@ def main() -> int:
|
||||
scan_date = scan.get("scannedAt", brussels_now())[:10]
|
||||
scanner = f"trivy {scan.get('trivyVersion', 'unknown')}"
|
||||
|
||||
affected_digests: dict[str, str] = {}
|
||||
image_inventory: dict[str, object] = {}
|
||||
if args.image_digests:
|
||||
digest_doc = load_json(args.image_digests)
|
||||
for service, entry in digest_doc.get("images", {}).items():
|
||||
digest = entry.get("digest") or entry.get("imageId")
|
||||
if digest:
|
||||
affected_digests[service] = digest
|
||||
raw_images = digest_doc.get("images", {})
|
||||
if isinstance(raw_images, dict):
|
||||
image_inventory = raw_images
|
||||
|
||||
today = date.fromisoformat(scan_date) if len(scan_date) == 10 else date.today()
|
||||
expiry = (today + timedelta(days=args.expiry_days)).isoformat()
|
||||
rescan = (today + timedelta(days=args.rescan_days)).isoformat()
|
||||
|
||||
versions_by_pair: dict[tuple[str, str], set[str]] = {}
|
||||
for row in scan.get("unresolvedCriticalOrHigh", []):
|
||||
for cve in row["cves"]:
|
||||
versions_by_pair.setdefault((row["package"], cve), set()).add(
|
||||
str(row.get("installedVersion"))
|
||||
)
|
||||
exceptions = []
|
||||
for row in scan.get("unresolvedCriticalOrHigh", []):
|
||||
package = row["package"]
|
||||
try:
|
||||
affected_digests = (
|
||||
_affected_image_digests(row, image_inventory) if args.image_digests else {}
|
||||
)
|
||||
except ValueError as exc:
|
||||
parser.error(str(exc))
|
||||
for cve in row["cves"]:
|
||||
version_suffix = ""
|
||||
if len(versions_by_pair[(package, cve)]) > 1:
|
||||
version_suffix = (
|
||||
"-" + hashlib.sha256(str(row.get("installedVersion")).encode()).hexdigest()[:12]
|
||||
)
|
||||
exceptions.append(
|
||||
{
|
||||
"id": f"{package}-{cve}",
|
||||
"id": f"{package}-{cve}{version_suffix}",
|
||||
"cve": cve,
|
||||
"package": package,
|
||||
"installedVersion": row.get("installedVersion"),
|
||||
|
||||
Reference in new issue
Block a user