Add homelab scorecard command

This commit is contained in:
juvdiaz 2026-06-29 17:53:43 -06:00
parent 7281143253
commit dcfab54e06
5 changed files with 96 additions and 1 deletions

View File

@ -273,6 +273,7 @@ Run a read-only health snapshot from the Debian server with:
./jeannie capacity ./jeannie capacity
./jeannie recover-plan ./jeannie recover-plan
./jeannie recover-power --dry-run ./jeannie recover-power --dry-run
./jeannie scorecard
./jeannie gitops-status ./jeannie gitops-status
./jeannie cert-check ./jeannie cert-check
./jeannie release-snapshot ./jeannie release-snapshot
@ -317,6 +318,10 @@ edge verification.
Debian runtime, Gitea, RPi DNS, Pimox workers, Kubernetes, GitOps/apps, and Debian runtime, Gitea, RPi DNS, Pimox workers, Kubernetes, GitOps/apps, and
edge/public checks. Use `recover-power --dry-run` to preview the sequence. edge/public checks. Use `recover-power --dry-run` to preview the sequence.
`scorecard` rolls up backup readiness, GitOps health, DNS/RPi health, cluster
health, edge health, capacity pressure, security posture, public certificates,
inventory, and docs freshness into a compact pass/warn/fail report.
`gitops-status` prints a focused Argo CD view: application sync and health, `gitops-status` prints a focused Argo CD view: application sync and health,
out-of-sync or degraded apps, repository secret presence, recent Argo CD events, out-of-sync or degraded apps, repository secret presence, recent Argo CD events,
and recent repo-server/application-controller errors. and recent repo-server/application-controller errors.

View File

@ -273,6 +273,7 @@ Run a read-only health snapshot from the Debian server with:
./{{ main_script }} capacity ./{{ main_script }} capacity
./{{ main_script }} recover-plan ./{{ main_script }} recover-plan
./{{ main_script }} recover-power --dry-run ./{{ main_script }} recover-power --dry-run
./{{ main_script }} scorecard
./{{ main_script }} gitops-status ./{{ main_script }} gitops-status
./{{ main_script }} cert-check ./{{ main_script }} cert-check
./{{ main_script }} release-snapshot ./{{ main_script }} release-snapshot
@ -317,6 +318,10 @@ edge verification.
Debian runtime, Gitea, RPi DNS, Pimox workers, Kubernetes, GitOps/apps, and Debian runtime, Gitea, RPi DNS, Pimox workers, Kubernetes, GitOps/apps, and
edge/public checks. Use `recover-power --dry-run` to preview the sequence. edge/public checks. Use `recover-power --dry-run` to preview the sequence.
`scorecard` rolls up backup readiness, GitOps health, DNS/RPi health, cluster
health, edge health, capacity pressure, security posture, public certificates,
inventory, and docs freshness into a compact pass/warn/fail report.
`gitops-status` prints a focused Argo CD view: application sync and health, `gitops-status` prints a focused Argo CD view: application sync and health,
out-of-sync or degraded apps, repository secret presence, recent Argo CD events, out-of-sync or degraded apps, repository secret presence, recent Argo CD events,
and recent repo-server/application-controller errors. and recent repo-server/application-controller errors.

View File

@ -66,6 +66,11 @@ verification.
: Run the post-outage recovery sequence in dependency order: Debian runtime, : Run the post-outage recovery sequence in dependency order: Debian runtime,
Gitea, RPi DNS, Pimox workers, Kubernetes, GitOps/apps, and edge/public checks. Gitea, RPi DNS, Pimox workers, Kubernetes, GitOps/apps, and edge/public checks.
`scorecard`
: Roll up backup readiness, GitOps health, DNS/RPi health, cluster health, edge
health, capacity pressure, security posture, public certificates, inventory, and
docs freshness into a compact pass/warn/fail report.
`gitops-status` `gitops-status`
: Print a focused Argo CD status view with application sync/health, out-of-sync : Print a focused Argo CD status view with application sync/health, out-of-sync
or degraded apps, repository secret presence, recent events, and recent or degraded apps, repository secret presence, recent events, and recent

10
jeannie
View File

@ -6022,6 +6022,11 @@ recover_power() {
"${REPO_ROOT}/scripts/recover-power" "${@:2}" "${REPO_ROOT}/scripts/recover-power" "${@:2}"
} }
scorecard() {
require_debian_server "scorecard"
"${REPO_ROOT}/scripts/scorecard"
}
workers_manage() { workers_manage() {
require_debian_server "workers" require_debian_server "workers"
"${REPO_ROOT}/scripts/workers" "${@:2}" "${REPO_ROOT}/scripts/workers" "${@:2}"
@ -6102,6 +6107,9 @@ case "${1:-}" in
recover-power) recover-power)
recover_power "$@" recover_power "$@"
;; ;;
scorecard)
scorecard
;;
workers) workers)
workers_manage "$@" workers_manage "$@"
;; ;;
@ -6259,7 +6267,7 @@ case "${1:-}" in
echo "Log: ${JEANNIE_LOG_FILE}" echo "Log: ${JEANNIE_LOG_FILE}"
;; ;;
*) *)
echo "Usage: $0 {up|plan [all|provisioning|cluster|platform|apps|edge]|rebuild-cluster|stop-cluster|start-cluster|status|capacity|recover-plan|recover-power [--dry-run]|gitops-status|cert-check|release-snapshot|backup-status|synthetic-checks|resource-budget|artifact-cache {status|up|down|instructions}|golden-ledger {show|check}|route-inventory|workers <list|start|stop|drain|uncordon|recreate-plan|rebalance>|change-journal {list|path}|map [--dot]|validate|access-audit|kubeconfig-readonly|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-restore|drill-gitea-restore|drill-pihole-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|doctor-preapply|inventory-check|state-backup|fix-debian-docker-root|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|security-scan|security-prepare|security-zap|security-k8s|security-host|security-trivy|security-secrets|security-nuclei|security-web|security-logs|security-runtime|security-attack-path|openwrt|nuke}" echo "Usage: $0 {up|plan [all|provisioning|cluster|platform|apps|edge]|rebuild-cluster|stop-cluster|start-cluster|status|capacity|recover-plan|recover-power [--dry-run]|scorecard|gitops-status|cert-check|release-snapshot|backup-status|synthetic-checks|resource-budget|artifact-cache {status|up|down|instructions}|golden-ledger {show|check}|route-inventory|workers <list|start|stop|drain|uncordon|recreate-plan|rebalance>|change-journal {list|path}|map [--dot]|validate|access-audit|kubeconfig-readonly|apps|website-translation-model|website-ollama-listen|ollama-setup|deploy-gitea|rpi-services|bootstrap-gitea-repo|backup-gitea|drill-restore|drill-gitea-restore|drill-pihole-restore|install-gitea-runner|move-prometheus-stack-workers|doctor-versions|doctor-edge|doctor-gitea|doctor-rpi|doctor-cluster|preflight|doctor-preapply|inventory-check|state-backup|fix-debian-docker-root|secrets-init|secrets-check|tailnet-policy-check|ai-index|ai-check|security-scan|security-prepare|security-zap|security-k8s|security-host|security-trivy|security-secrets|security-nuclei|security-web|security-logs|security-runtime|security-attack-path|openwrt|nuke}"
exit 1 exit 1
;; ;;
esac esac

72
scripts/scorecard Executable file
View File

@ -0,0 +1,72 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
failures=0
warnings=0
score() {
local label="$1"
local severity="$2"
shift 2
local output
local status
printf '%-28s ' "$label"
set +e
output="$("$@" 2>&1)"
status=$?
set -e
if [ "$status" -eq 0 ]; then
printf 'pass\n'
return 0
fi
if [ "$severity" = "fail" ]; then
failures=$((failures + 1))
printf 'fail'
else
warnings=$((warnings + 1))
printf 'warn'
fi
if [ -n "$output" ]; then
printf ' - %s' "$(printf '%s' "$output" | grep -v '^+' | head -n 1)"
fi
printf '\n'
}
docs_fresh() {
"${REPO_ROOT}/scripts/render-docs" --check >/dev/null
}
inventory_ok() {
"${REPO_ROOT}/scripts/validate-homelab-inventory" "${HOMELAB_INVENTORY_FILE:-${REPO_ROOT}/homelab.yml}" >/dev/null
}
security_static_ok() {
"${REPO_ROOT}/scripts/validate-tailnet-policy" >/dev/null
}
printf 'Homelab scorecard\n'
printf '=================\n\n'
score "Inventory" fail inventory_ok
score "Documentation freshness" warn docs_fresh
score "Backup readiness" fail "${REPO_ROOT}/scripts/backup-status"
score "GitOps health" warn "${REPO_ROOT}/scripts/gitops-status"
score "DNS and RPi health" fail "${REPO_ROOT}/jeannie" doctor-rpi
score "Cluster health" fail "${REPO_ROOT}/jeannie" doctor-cluster
score "Edge health" fail "${REPO_ROOT}/jeannie" doctor-edge
score "Capacity pressure" warn "${REPO_ROOT}/scripts/resource-budget"
score "Security posture" warn security_static_ok
score "Public certificates" warn "${REPO_ROOT}/scripts/cert-check"
printf '\nSummary: failures=%s warnings=%s\n' "$failures" "$warnings"
if [ "$failures" -gt 0 ]; then
printf 'Focus on the failed categories first, then clear warnings.\n'
exit 1
fi
if [ "$warnings" -gt 0 ]; then
printf 'No blocking failures, but warnings need cleanup.\n'
exit 0
fi
printf 'Scorecard passed.\n'