Implement audit enrichments, TUI workflows, and production ISO scaffold
This commit is contained in:
60
scripts/fetch-vendor.sh
Executable file
60
scripts/fetch-vendor.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
# fetch-vendor.sh — download proprietary vendor utilities into iso/vendor.
|
||||
#
|
||||
# Usage:
|
||||
# STORCLI_URL=... STORCLI_SHA256=... \
|
||||
# SAS2IRCU_URL=... SAS2IRCU_SHA256=... \
|
||||
# SAS3IRCU_URL=... SAS3IRCU_SHA256=... \
|
||||
# MSTFLINT_URL=... MSTFLINT_SHA256=... \
|
||||
# sh scripts/fetch-vendor.sh
|
||||
|
||||
set -eu
|
||||
|
||||
ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
OUT_DIR="$ROOT_DIR/iso/vendor"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
need_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || { echo "ERROR: required command not found: $1" >&2; exit 1; }
|
||||
}
|
||||
|
||||
need_cmd wget
|
||||
need_cmd sha256sum
|
||||
|
||||
fetch_one() {
|
||||
name="$1"
|
||||
url="$2"
|
||||
sha="$3"
|
||||
|
||||
if [ -z "$url" ] || [ -z "$sha" ]; then
|
||||
echo "[vendor] skip $name (URL/SHA not provided)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
dst="$OUT_DIR/$name"
|
||||
tmp="$dst.tmp"
|
||||
|
||||
echo "[vendor] downloading $name"
|
||||
wget -O "$tmp" "$url"
|
||||
|
||||
got=$(sha256sum "$tmp" | awk '{print $1}')
|
||||
want=$(echo "$sha" | tr '[:upper:]' '[:lower:]')
|
||||
if [ "$got" != "$want" ]; then
|
||||
rm -f "$tmp"
|
||||
echo "ERROR: checksum mismatch for $name" >&2
|
||||
echo " got: $got" >&2
|
||||
echo " want: $want" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mv "$tmp" "$dst"
|
||||
chmod +x "$dst" || true
|
||||
echo "[vendor] ok: $name"
|
||||
}
|
||||
|
||||
fetch_one "storcli64" "${STORCLI_URL:-}" "${STORCLI_SHA256:-}"
|
||||
fetch_one "sas2ircu" "${SAS2IRCU_URL:-}" "${SAS2IRCU_SHA256:-}"
|
||||
fetch_one "sas3ircu" "${SAS3IRCU_URL:-}" "${SAS3IRCU_SHA256:-}"
|
||||
fetch_one "mstflint" "${MSTFLINT_URL:-}" "${MSTFLINT_SHA256:-}"
|
||||
|
||||
echo "[vendor] done. output dir: $OUT_DIR"
|
||||
81
scripts/test-local.sh
Executable file
81
scripts/test-local.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
# Local integration test for bee audit binary (plan step 1.12).
|
||||
# Runs audit on current machine and validates required JSON fields.
|
||||
|
||||
set -eu
|
||||
|
||||
ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
OUT_FILE="${1:-/tmp/bee-audit-local-$(date +%Y%m%d-%H%M%S).json}"
|
||||
|
||||
if [ "$(uname -s)" != "Linux" ]; then
|
||||
echo "ERROR: scripts/test-local.sh must run on Linux (current: $(uname -s))" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
echo "ERROR: go not found in PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[test-local] running audit -> $OUT_FILE"
|
||||
(
|
||||
cd "$ROOT_DIR/audit"
|
||||
go run ./cmd/audit --output "file:$OUT_FILE"
|
||||
)
|
||||
|
||||
if [ ! -s "$OUT_FILE" ]; then
|
||||
echo "ERROR: audit output file is missing or empty: $OUT_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python3 - "$OUT_FILE" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
path = sys.argv[1]
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
errors = []
|
||||
|
||||
def require_nonempty_string(v, name):
|
||||
if not isinstance(v, str) or not v.strip():
|
||||
errors.append(f"{name} must be a non-empty string")
|
||||
|
||||
require_nonempty_string(data.get("collected_at"), "collected_at")
|
||||
require_nonempty_string(data.get("source_type"), "source_type")
|
||||
require_nonempty_string(data.get("protocol"), "protocol")
|
||||
|
||||
hw = data.get("hardware")
|
||||
if not isinstance(hw, dict):
|
||||
errors.append("hardware must be an object")
|
||||
hw = {}
|
||||
|
||||
board = hw.get("board")
|
||||
if not isinstance(board, dict):
|
||||
errors.append("hardware.board must be an object")
|
||||
board = {}
|
||||
|
||||
require_nonempty_string(board.get("serial_number"), "hardware.board.serial_number")
|
||||
|
||||
cpus = hw.get("cpus")
|
||||
if not isinstance(cpus, list) or len(cpus) == 0:
|
||||
errors.append("hardware.cpus must be a non-empty array")
|
||||
|
||||
if errors:
|
||||
print("[test-local] validation FAILED")
|
||||
for e in errors:
|
||||
print(" -", e)
|
||||
sys.exit(1)
|
||||
|
||||
memory = hw.get("memory") if isinstance(hw.get("memory"), list) else []
|
||||
storage = hw.get("storage") if isinstance(hw.get("storage"), list) else []
|
||||
pcie = hw.get("pcie_devices") if isinstance(hw.get("pcie_devices"), list) else []
|
||||
psu = hw.get("power_supplies") if isinstance(hw.get("power_supplies"), list) else []
|
||||
|
||||
print("[test-local] validation OK")
|
||||
print(f"[test-local] board.serial_number={board.get('serial_number')}")
|
||||
print(f"[test-local] counts: cpus={len(cpus)} memory={len(memory)} storage={len(storage)} pcie={len(pcie)} psu={len(psu)}")
|
||||
PY
|
||||
|
||||
echo "[test-local] done"
|
||||
Reference in New Issue
Block a user