Add ingress route inventory check
This commit is contained in:
parent
b1855d4928
commit
479be7fc47
|
|
@ -280,6 +280,7 @@ Run a read-only health snapshot from the Debian server with:
|
|||
./jeannie resource-budget
|
||||
./jeannie artifact-cache status
|
||||
./jeannie golden-ledger check
|
||||
./jeannie route-inventory
|
||||
./jeannie workers list
|
||||
./jeannie change-journal list
|
||||
./jeannie map
|
||||
|
|
@ -343,6 +344,10 @@ cache. Use `artifact-cache instructions` for client configuration snippets.
|
|||
reviewable record of template VMID, storage, OS release, Kubernetes pins,
|
||||
runtime versions, and build metadata for Pimox worker golden images.
|
||||
|
||||
`route-inventory` reports Kubernetes ingress hosts, paths, backend services,
|
||||
TLS coverage, and visible Uptime Kuma monitor coverage so stale routes and
|
||||
missing monitors are easier to spot.
|
||||
|
||||
`workers` provides named Kubernetes/Pimox worker lifecycle operations:
|
||||
`list`, `start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`.
|
||||
Use `recreate-plan <index>` before replacing one broken Pimox worker so the
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ Run a read-only health snapshot from the Debian server with:
|
|||
./{{ main_script }} resource-budget
|
||||
./{{ main_script }} artifact-cache status
|
||||
./{{ main_script }} golden-ledger check
|
||||
./{{ main_script }} route-inventory
|
||||
./{{ main_script }} workers list
|
||||
./{{ main_script }} change-journal list
|
||||
./{{ main_script }} map
|
||||
|
|
@ -343,6 +344,10 @@ cache. Use `artifact-cache instructions` for client configuration snippets.
|
|||
reviewable record of template VMID, storage, OS release, Kubernetes pins,
|
||||
runtime versions, and build metadata for Pimox worker golden images.
|
||||
|
||||
`route-inventory` reports Kubernetes ingress hosts, paths, backend services,
|
||||
TLS coverage, and visible Uptime Kuma monitor coverage so stale routes and
|
||||
missing monitors are easier to spot.
|
||||
|
||||
`workers` provides named Kubernetes/Pimox worker lifecycle operations:
|
||||
`list`, `start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`.
|
||||
Use `recreate-plan <index>` before replacing one broken Pimox worker so the
|
||||
|
|
|
|||
|
|
@ -97,6 +97,10 @@ Docker Hub pull-through image caching.
|
|||
`golden-ledger {show|check}`
|
||||
: Show or validate the Pimox golden image version ledger.
|
||||
|
||||
`route-inventory`
|
||||
: Report Kubernetes ingress hosts, paths, backend services, TLS coverage, and
|
||||
visible Uptime Kuma monitor coverage.
|
||||
|
||||
`workers <command>`
|
||||
: Manage Kubernetes/Pimox worker lifecycle operations. Commands include `list`,
|
||||
`start`, `stop`, `drain`, `uncordon`, `recreate-plan`, and `rebalance`.
|
||||
|
|
|
|||
10
jeannie
10
jeannie
|
|
@ -6011,6 +6011,11 @@ golden_ledger() {
|
|||
"${REPO_ROOT}/scripts/golden-ledger" "${@:2}"
|
||||
}
|
||||
|
||||
route_inventory() {
|
||||
require_debian_server "route-inventory"
|
||||
"${REPO_ROOT}/scripts/route-inventory"
|
||||
}
|
||||
|
||||
workers_manage() {
|
||||
require_debian_server "workers"
|
||||
"${REPO_ROOT}/scripts/workers" "${@:2}"
|
||||
|
|
@ -6085,6 +6090,9 @@ case "${1:-}" in
|
|||
golden-ledger)
|
||||
golden_ledger "$@"
|
||||
;;
|
||||
route-inventory)
|
||||
route_inventory
|
||||
;;
|
||||
workers)
|
||||
workers_manage "$@"
|
||||
;;
|
||||
|
|
@ -6242,7 +6250,7 @@ case "${1:-}" in
|
|||
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|gitops-status|cert-check|release-snapshot|backup-status|synthetic-checks|resource-budget|artifact-cache {status|up|down|instructions}|golden-ledger {show|check}|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|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
|
||||
;;
|
||||
esac
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
KUBECONFIG_PATH="${KUBECONFIG:-${LAB_KUBECONFIG_PATH:-/home/jv/.kube/config}}"
|
||||
KUMA_MONITORS_FILE="${LAB_UPTIME_KUMA_MONITORS_FILE:-infra/rpi-services/uptime-kuma-monitors.json}"
|
||||
INGRESS_JSON=""
|
||||
|
||||
cleanup() {
|
||||
if [ -n "$INGRESS_JSON" ] && [ -f "$INGRESS_JSON" ]; then
|
||||
rm -f "$INGRESS_JSON"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
section() {
|
||||
printf '\n== %s ==\n' "$1"
|
||||
}
|
||||
|
||||
if ! command -v kubectl >/dev/null 2>&1 || [ ! -s "$KUBECONFIG_PATH" ]; then
|
||||
echo "kubectl and kubeconfig are required for route-inventory." >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! kubectl --kubeconfig "$KUBECONFIG_PATH" get --raw=/readyz >/dev/null 2>&1; then
|
||||
echo "Kubernetes API is unavailable." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
section "Ingress Routes"
|
||||
INGRESS_JSON="$(mktemp "${TMPDIR:-/tmp}/homelab-ingress.XXXXXX.json")"
|
||||
kubectl --kubeconfig "$KUBECONFIG_PATH" get ingress -A -o json >"$INGRESS_JSON"
|
||||
python3 - "$INGRESS_JSON" "$KUMA_MONITORS_FILE" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
||||
ingress_file, monitors_file = sys.argv[1:3]
|
||||
with open(ingress_file, encoding="utf-8") as handle:
|
||||
doc = json.load(handle)
|
||||
monitors = []
|
||||
try:
|
||||
with open(monitors_file, encoding="utf-8") as handle:
|
||||
data = json.load(handle)
|
||||
for item in data if isinstance(data, list) else data.get("monitors", []):
|
||||
url = item.get("url") or item.get("hostname") or ""
|
||||
monitors.append(url)
|
||||
except (OSError, json.JSONDecodeError):
|
||||
pass
|
||||
|
||||
print(f"{'NAMESPACE':20} {'NAME':28} {'HOST':36} {'PATH':16} {'SERVICE':28} {'TLS':6} {'KUMA':6}")
|
||||
missing = []
|
||||
for ingress in doc.get("items", []):
|
||||
ns = ingress["metadata"]["namespace"]
|
||||
name = ingress["metadata"]["name"]
|
||||
tls_hosts = {
|
||||
host
|
||||
for tls in ingress.get("spec", {}).get("tls", [])
|
||||
for host in tls.get("hosts", [])
|
||||
}
|
||||
for rule in ingress.get("spec", {}).get("rules", []):
|
||||
host = rule.get("host", "")
|
||||
paths = rule.get("http", {}).get("paths", [])
|
||||
if not paths:
|
||||
paths = [{"path": "/", "backend": {}}]
|
||||
for path in paths:
|
||||
backend = path.get("backend", {}).get("service", {})
|
||||
service = backend.get("name", "")
|
||||
port = backend.get("port", {}).get("number") or backend.get("port", {}).get("name") or ""
|
||||
route_path = path.get("path", "/")
|
||||
tls = "yes" if host in tls_hosts else "no"
|
||||
kuma = "yes" if any(host and host in monitor for monitor in monitors) else "no"
|
||||
print(f"{ns:20} {name:28} {host:36} {route_path:16} {(service + ':' + str(port)):28} {tls:6} {kuma:6}")
|
||||
if kuma == "no":
|
||||
missing.append(f"{host}{route_path}")
|
||||
|
||||
if missing:
|
||||
print("\nRoutes missing visible Uptime Kuma monitor coverage:")
|
||||
for route in sorted(set(missing)):
|
||||
print(f" {route}")
|
||||
PY
|
||||
|
||||
section "Services Behind Ingress"
|
||||
kubectl --kubeconfig "$KUBECONFIG_PATH" get svc -A \
|
||||
-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,PORTS:.spec.ports[*].port' |
|
||||
sed -n '1,120p'
|
||||
Loading…
Reference in New Issue