my-homelab-configs/scripts/homelab-map

133 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
INVENTORY_FILE="${HOMELAB_INVENTORY_FILE:-${REPO_ROOT}/homelab.yml}"
FORMAT="${1:-text}"
inventory() {
local path="$1"
local fallback="$2"
if command -v ruby >/dev/null 2>&1 && [ -f "$INVENTORY_FILE" ]; then
value="$(
ruby -ryaml -e '
data = YAML.load_file(ARGV[0])
value = ARGV[1].split(".").reduce(data) { |memo, key| memo.respond_to?(:[]) ? memo[key] : nil }
puts value if value.is_a?(String) || value.is_a?(Integer)
' "$INVENTORY_FILE" "$path" 2>/dev/null || true
)"
if [ -n "$value" ]; then
printf '%s\n' "$value"
return 0
fi
fi
printf '%s\n' "$fallback"
}
domain="$(inventory domain.base lab2025.duckdns.org)"
debian="$(inventory hosts.debian.lan_ip 192.168.100.73)"
debian_ts="$(inventory hosts.debian.tailscale_ip 100.85.138.30)"
rpi="$(inventory hosts.rpi4.lan_ip 192.168.100.89)"
oci="$(inventory hosts.oci_edge.public_ip 132.145.170.74)"
oci_ts="$(inventory hosts.oci_edge.tailscale_ip 100.118.255.19)"
pimox="$(inventory hosts.opi5_pimox.lan_ip 192.168.100.80)"
traefik="$(inventory network.metallb.traefik_ip 192.168.100.240)"
registry="$(inventory services.local_registry.endpoint 192.168.100.73:30500)"
gitea_http="$(inventory services.gitea.http_port 3000)"
gitea_ssh="$(inventory services.gitea.ssh_port 32222)"
pihole_web="$(inventory services.rpi_dns.pihole_web_port 8081)"
kuma="$(inventory services.rpi_dns.uptime_kuma_port 3001)"
if [ "$FORMAT" = "--dot" ] || [ "$FORMAT" = "dot" ]; then
cat <<EOF
digraph homelab {
rankdir=LR;
"Internet" -> "OCI edge ${oci}";
"OCI edge ${oci}" -> "Traefik ${traefik}";
"OCI edge ${oci}" -> "Debian Tailscale ${debian_ts}";
"Debian ${debian}" -> "Gitea :${gitea_http}/git";
"Debian ${debian}" -> "Local registry ${registry}";
"Debian ${debian}" -> "Kubernetes control plane";
"Debian ${debian}" -> "Pimox ${pimox}";
"Pimox ${pimox}" -> "Worker VMs";
"Worker VMs" -> "Kubernetes apps";
"Kubernetes apps" -> "Traefik ${traefik}";
"Gitea :${gitea_http}/git" -> "Argo CD";
"Argo CD" -> "Kubernetes apps";
"Clients" -> "Pi-hole ${rpi}:53";
"Pi-hole ${rpi}:53" -> "Unbound";
"Pi-hole ${rpi}:53" -> "Public DNS fallback";
"Uptime Kuma ${rpi}:${kuma}" -> "Public URLs";
"Uptime Kuma ${rpi}:${kuma}" -> "LAN services";
}
EOF
exit 0
fi
cat <<EOF
Homelab dependency map
======================
Public entry
Internet
-> ${domain}
-> OCI edge ${oci} / tailscale ${oci_ts}
-> Traefik LoadBalancer ${traefik}
-> Kubernetes ingress routes
-> website, demos, Heimdall, observability, Argo CD, arr routes
Git and automation
Debian ${debian}
-> Gitea HTTP :${gitea_http}/git and SSH :${gitea_ssh}
-> Gitea Actions runner
-> local registry ${registry}
-> jeannie orchestration
Gitea repository
-> Argo CD applications
-> Kubernetes manifests under apps/
-> edge/provisioning/cluster/platform Terraform stacks
Cluster foundation
Debian ${debian}
-> kubeadm control plane
-> container registry
-> provisioning HTTP/TFTP
Orange Pi Pimox ${pimox}
-> worker VM template
-> worker VM clones
-> Kubernetes worker capacity
DNS and always-on health
Clients and lab hosts
-> RPi4 Pi-hole ${rpi}:53
-> Unbound resolver
-> public fallback DNS if Unbound is unhealthy
RPi4
-> Pi-hole web ${rpi}:${pihole_web}
-> Uptime Kuma ${rpi}:${kuma}
-> monitors public URLs, LAN services, DNS, Traefik, Gitea, arr
Observability and operations
Prometheus stack
-> nodes, pods, Traefik, website probes, Gitea/Pi-hole scrape coverage
-> homelab-alerts
-> Grafana dashboards
jeannie status
-> host/bootstrap checks
-> local services
-> RPi DNS and Kuma
-> Pimox and Kubernetes
-> platform/apps
-> edge/public URLs
Security learning loop
security-lab namespace
-> isolated OWASP practice targets
-> ZAP/nuclei/trivy/lynis helper commands
-> report-only findings before manual fixes
Use './jeannie map --dot' to emit a Graphviz DOT version.
EOF