Add Proxmox inventory scripts and n8n sync workflow
- proxmox-inventory.sh: text inventory (RAM/CPU/Swap/Disk/IP/Gateway/Subnetz) - proxmox-inventory-json.sh: JSON variant with n8n webhook push, --vmids filter, --dry-run - n8n workflow: automated fact-sync between Proxmox and Outline docs, auto-creates pages for new VMIDs, ntfy summary notification - credentials (Outline/NTFY bearer tokens) intentionally excluded, see README
This commit is contained in:
@@ -0,0 +1,277 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# proxmox-inventory-json.sh
|
||||
# ---------------------------
|
||||
# Baut dasselbe Inventar wie proxmox-inventory.sh / inventory.sh, aber als
|
||||
# JSON, und sendet es per curl an einen n8n-Webhook. Das bestehende
|
||||
# Text-Script bleibt unverändert für manuelle Ausführung nutzbar.
|
||||
#
|
||||
# Voraussetzung: "jq" muss installiert sein.
|
||||
# apt install -y jq
|
||||
#
|
||||
# Nutzung:
|
||||
# chmod +x proxmox-inventory-json.sh
|
||||
# ./proxmox-inventory-json.sh # baut JSON + sendet an n8n (alle VMIDs)
|
||||
# ./proxmox-inventory-json.sh --dry-run # baut JSON, zeigt es nur an, sendet NICHT
|
||||
# ./proxmox-inventory-json.sh --print-only > inventory.json # nur JSON in Datei
|
||||
# ./proxmox-inventory-json.sh --vmids=101,102,138 # nur diese VMIDs verarbeiten (schnell zum Testen)
|
||||
#
|
||||
# Alternativ dauerhaft in der VMID_FILTER-Variable unten eintragen, z.B. VMID_FILTER="101,102,138".
|
||||
# Leer lassen ("") um wie gewohnt ALLE Container/VMs zu verarbeiten.
|
||||
# --vmids= überschreibt die Variable, falls beides gesetzt ist.
|
||||
#
|
||||
# Geplant ausführen (Cron, z. B. täglich 06:00 Uhr):
|
||||
# crontab -e
|
||||
# 0 6 * * * /root/proxmox-inventory-json.sh >> /var/log/proxmox-inventory.log 2>&1
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# KONFIGURATION - hier eure n8n-Webhook-URL eintragen
|
||||
# ---------------------------------------------------------------------------
|
||||
N8N_WEBHOOK_URL="https://n8n.example.com/webhook/REPLACE_ME"
|
||||
|
||||
# Komma-getrennte Liste von VMIDs, die verarbeitet werden sollen, z.B. "101,102,138"
|
||||
# Leer lassen ("") um wie gewohnt ALLE Container/VMs zu verarbeiten.
|
||||
VMID_FILTER=""
|
||||
|
||||
DRY_RUN=false
|
||||
PRINT_ONLY=false
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) DRY_RUN=true ;;
|
||||
--print-only) PRINT_ONLY=true ;;
|
||||
--vmids=*) VMID_FILTER="${arg#--vmids=}" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Prüft, ob eine VMID laut Filter verarbeitet werden soll.
|
||||
# Ohne Filter (VMID_FILTER leer) wird alles verarbeitet.
|
||||
should_process() {
|
||||
local vmid="$1"
|
||||
[ -z "$VMID_FILTER" ] && return 0
|
||||
case ",${VMID_FILTER}," in
|
||||
*",${vmid},"*) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "'jq' ist nicht installiert - versuche automatische Installation..." >&2
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
apt-get update -qq && apt-get install -y -qq jq
|
||||
fi
|
||||
command -v jq >/dev/null 2>&1 || { echo "FEHLER: 'jq' konnte nicht automatisch installiert werden. Bitte manuell ausführen: apt install -y jq" >&2; exit 1; }
|
||||
echo "'jq' erfolgreich installiert." >&2
|
||||
fi
|
||||
|
||||
cidr_to_netmask() {
|
||||
local cidr="$1"
|
||||
if ! [[ "$cidr" =~ ^[0-9]+$ ]] || [ "$cidr" -lt 0 ] || [ "$cidr" -gt 32 ]; then
|
||||
echo ""
|
||||
return
|
||||
fi
|
||||
local mask=0
|
||||
if [ "$cidr" -gt 0 ]; then
|
||||
mask=$(( 0xffffffff ^ ((1 << (32 - cidr)) - 1) ))
|
||||
fi
|
||||
printf "%d.%d.%d.%d" \
|
||||
"$(( (mask >> 24) & 255 ))" \
|
||||
"$(( (mask >> 16) & 255 ))" \
|
||||
"$(( (mask >> 8) & 255 ))" \
|
||||
"$(( mask & 255 ))"
|
||||
}
|
||||
|
||||
TMP_LXC=$(mktemp)
|
||||
TMP_VM=$(mktemp)
|
||||
trap 'rm -f "$TMP_LXC" "$TMP_VM"' EXIT
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# LXC Container
|
||||
# ---------------------------------------------------------------------------
|
||||
for VMID in $(pct list | awk 'NR>1 {print $1}'); do
|
||||
should_process "$VMID" || continue
|
||||
NAME=$(pct list | awk -v id="$VMID" '$1==id{print $NF}')
|
||||
STATUS=$(pct status "$VMID" 2>/dev/null | awk '{print $2}')
|
||||
CONFIG=$(pct config "$VMID" 2>/dev/null || true)
|
||||
HOSTNAME_CFG=$(echo "$CONFIG" | grep -E '^hostname:' | cut -d' ' -f2- || echo "")
|
||||
CORES=$(echo "$CONFIG" | grep -E '^cores:' | cut -d' ' -f2- || echo "")
|
||||
MEMORY=$(echo "$CONFIG" | grep -E '^memory:' | cut -d' ' -f2- || echo "")
|
||||
SWAP=$(echo "$CONFIG" | grep -E '^swap:' | cut -d' ' -f2- || echo "")
|
||||
DISK=$(echo "$CONFIG" | grep -E '^rootfs:' | grep -oP 'size=\K[^,]+' || echo "")
|
||||
STORAGE_POOL=$(echo "$CONFIG" | grep -E '^rootfs:' | cut -d' ' -f2- | cut -d: -f1 || echo "")
|
||||
|
||||
NET0_LINE=$(echo "$CONFIG" | grep -E '^net0:' || true)
|
||||
CFG_GW=$(echo "$NET0_LINE" | grep -oP 'gw=\K[0-9.]+' || echo "")
|
||||
CFG_CIDR=$(echo "$NET0_LINE" | grep -oP 'ip=[0-9.]+/\K[0-9]+' || echo "")
|
||||
MAC=$(echo "$NET0_LINE" | grep -oP 'hwaddr=\K[0-9A-Fa-f:]+' || echo "")
|
||||
|
||||
IP=""
|
||||
LIVE_GW=""
|
||||
LIVE_CIDR=""
|
||||
if [ "$STATUS" = "running" ]; then
|
||||
IP=$(pct exec "$VMID" -- ip -4 -o addr show scope global 2>/dev/null | head -1 | awk '{print $4}' | cut -d/ -f1 || echo "")
|
||||
LIVE_CIDR=$(pct exec "$VMID" -- ip -4 -o addr show scope global 2>/dev/null | head -1 | awk '{print $4}' | cut -d/ -f2 || echo "")
|
||||
LIVE_GW=$(pct exec "$VMID" -- ip -4 route show default 2>/dev/null | awk '{print $3}' | head -1 || echo "")
|
||||
fi
|
||||
|
||||
GW="${LIVE_GW:-$CFG_GW}"
|
||||
CIDR="${LIVE_CIDR:-$CFG_CIDR}"
|
||||
NETMASK=""
|
||||
[ -n "$CIDR" ] && NETMASK=$(cidr_to_netmask "$CIDR")
|
||||
|
||||
jq -n \
|
||||
--argjson vmid "$VMID" \
|
||||
--arg type "lxc" \
|
||||
--arg hostname "${HOSTNAME_CFG:-$NAME}" \
|
||||
--arg status "$STATUS" \
|
||||
--arg node "$(hostname)" \
|
||||
--arg cores "${CORES:-null}" \
|
||||
--arg memory_mb "${MEMORY:-null}" \
|
||||
--arg swap_mb "${SWAP:-null}" \
|
||||
--arg disk "$DISK" \
|
||||
--arg storage_pool "$STORAGE_POOL" \
|
||||
--arg ip "$IP" \
|
||||
--arg gateway "$GW" \
|
||||
--arg netmask "$NETMASK" \
|
||||
--arg mac "$MAC" \
|
||||
'{
|
||||
vmid: $vmid,
|
||||
type: $type,
|
||||
hostname: $hostname,
|
||||
status: $status,
|
||||
proxmox_node: $node,
|
||||
cores: (if $cores == "null" then null else ($cores|tonumber) end),
|
||||
memory_mb: (if $memory_mb == "null" then null else ($memory_mb|tonumber) end),
|
||||
swap_mb: (if $swap_mb == "null" then null else ($swap_mb|tonumber) end),
|
||||
disk: $disk,
|
||||
storage_pool: $storage_pool,
|
||||
ip: $ip,
|
||||
gateway: $gateway,
|
||||
netmask: $netmask,
|
||||
mac: $mac
|
||||
}' >> "$TMP_LXC"
|
||||
done
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# VMs
|
||||
# ---------------------------------------------------------------------------
|
||||
for VMID in $(qm list | awk 'NR>1 {print $1}'); do
|
||||
should_process "$VMID" || continue
|
||||
NAME=$(qm list | awk -v id="$VMID" '$1==id{print $2}')
|
||||
STATUS=$(qm status "$VMID" 2>/dev/null | awk '{print $2}')
|
||||
CONFIG=$(qm config "$VMID" 2>/dev/null || true)
|
||||
CORES=$(echo "$CONFIG" | grep -E '^cores:' | cut -d' ' -f2- || echo "")
|
||||
MEMORY=$(echo "$CONFIG" | grep -E '^memory:' | cut -d' ' -f2- || echo "")
|
||||
|
||||
DISKS_JSON="[]"
|
||||
DISKS_RAW=$(echo "$CONFIG" | grep -E '^(scsi|sata|virtio|ide)[0-9]+:' || true)
|
||||
if [ -n "$DISKS_RAW" ]; then
|
||||
DISKS_TMP=$(mktemp)
|
||||
echo "$DISKS_RAW" | while IFS= read -r LINE; do
|
||||
DEV=$(echo "$LINE" | cut -d: -f1)
|
||||
SIZE=$(echo "$LINE" | grep -oP 'size=\K[^,]+' || echo "")
|
||||
jq -n --arg device "$DEV" --arg size "$SIZE" '{device:$device, size:$size}'
|
||||
done > "$DISKS_TMP"
|
||||
DISKS_JSON=$(jq -s '.' "$DISKS_TMP")
|
||||
rm -f "$DISKS_TMP"
|
||||
fi
|
||||
|
||||
IPCONFIG_LINE=$(echo "$CONFIG" | grep -E '^ipconfig0:' || true)
|
||||
CFG_GW=$(echo "$IPCONFIG_LINE" | grep -oP 'gw=\K[0-9.]+' || echo "")
|
||||
CFG_CIDR=$(echo "$IPCONFIG_LINE" | grep -oP 'ip=[0-9.]+/\K[0-9]+' || echo "")
|
||||
|
||||
IP=""
|
||||
LIVE_CIDR=""
|
||||
if [ "$STATUS" = "running" ]; then
|
||||
AGENT_JSON=$(qm guest cmd "$VMID" network-get-interfaces 2>/dev/null || echo "")
|
||||
if [ -n "$AGENT_JSON" ]; then
|
||||
IP=$(echo "$AGENT_JSON" | grep -o '"ip-address":"[^"]*"' | grep -v '127.0.0.1' | cut -d'"' -f4 | head -1 || echo "")
|
||||
LIVE_CIDR=$(echo "$AGENT_JSON" | grep -oP '"prefix":\K[0-9]+' | head -1 || echo "")
|
||||
fi
|
||||
fi
|
||||
|
||||
GW="${CFG_GW:-}"
|
||||
CIDR="${LIVE_CIDR:-$CFG_CIDR}"
|
||||
NETMASK=""
|
||||
[ -n "$CIDR" ] && NETMASK=$(cidr_to_netmask "$CIDR")
|
||||
|
||||
jq -n \
|
||||
--argjson vmid "$VMID" \
|
||||
--arg type "vm" \
|
||||
--arg hostname "$NAME" \
|
||||
--arg status "$STATUS" \
|
||||
--arg node "$(hostname)" \
|
||||
--arg cores "${CORES:-null}" \
|
||||
--arg memory_mb "${MEMORY:-null}" \
|
||||
--argjson disks "$DISKS_JSON" \
|
||||
--arg ip "$IP" \
|
||||
--arg gateway "$GW" \
|
||||
--arg netmask "$NETMASK" \
|
||||
'{
|
||||
vmid: $vmid,
|
||||
type: $type,
|
||||
hostname: $hostname,
|
||||
status: $status,
|
||||
proxmox_node: $node,
|
||||
cores: (if $cores == "null" then null else ($cores|tonumber) end),
|
||||
memory_mb: (if $memory_mb == "null" then null else ($memory_mb|tonumber) end),
|
||||
disks: $disks,
|
||||
ip: $ip,
|
||||
gateway: $gateway,
|
||||
netmask: $netmask
|
||||
}' >> "$TMP_VM"
|
||||
done
|
||||
|
||||
CONTAINERS_JSON=$(jq -s '.' "$TMP_LXC")
|
||||
VMS_JSON=$(jq -s '.' "$TMP_VM")
|
||||
|
||||
# Prüfen, ob per --vmids/VMID_FILTER angeforderte VMIDs in Proxmox nicht existieren
|
||||
MISSING_JSON="[]"
|
||||
if [ -n "$VMID_FILTER" ]; then
|
||||
ALL_KNOWN_VMIDS=$( (pct list | awk 'NR>1{print $1}'; qm list | awk 'NR>1{print $1}') | sort -u)
|
||||
MISSING_TMP=$(mktemp)
|
||||
IFS=',' read -ra REQUESTED_VMIDS <<< "$VMID_FILTER"
|
||||
for rid in "${REQUESTED_VMIDS[@]}"; do
|
||||
if ! echo "$ALL_KNOWN_VMIDS" | grep -qx "$rid"; then
|
||||
jq -n --arg vmid "$rid" '{vmid: ($vmid|tonumber), reason: "VMID in Proxmox nicht gefunden (weder pct noch qm list)"}' >> "$MISSING_TMP"
|
||||
fi
|
||||
done
|
||||
if [ -s "$MISSING_TMP" ]; then
|
||||
MISSING_JSON=$(jq -s '.' "$MISSING_TMP")
|
||||
fi
|
||||
rm -f "$MISSING_TMP"
|
||||
fi
|
||||
|
||||
PAYLOAD=$(jq -n \
|
||||
--arg host "$(hostname)" \
|
||||
--arg ts "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
|
||||
--argjson containers "$CONTAINERS_JSON" \
|
||||
--argjson vms "$VMS_JSON" \
|
||||
--argjson missing "$MISSING_JSON" \
|
||||
'{proxmox_host: $host, generated_at: $ts, containers: $containers, vms: $vms, missing_vmids: $missing}')
|
||||
|
||||
if [ "$PRINT_ONLY" = true ]; then
|
||||
echo "$PAYLOAD"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "$PAYLOAD" | jq '.' >&2
|
||||
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo "Dry-Run: es wurde NICHTS an n8n gesendet." >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
HTTP_CODE=$(curl -s -o /tmp/n8n-response.json -w "%{http_code}" \
|
||||
-X POST "$N8N_WEBHOOK_URL" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data "$PAYLOAD")
|
||||
|
||||
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
|
||||
echo "OK: an n8n gesendet (HTTP $HTTP_CODE)" >&2
|
||||
else
|
||||
echo "FEHLER: n8n antwortete mit HTTP $HTTP_CODE" >&2
|
||||
cat /tmp/n8n-response.json >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,179 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# proxmox-inventory.sh
|
||||
#
|
||||
# Liest alle LXC-Container und VMs auf diesem Proxmox-Host aus und gibt
|
||||
# eine strukturierte Übersicht aus (VMID, Name, Status, Ressourcen, Netzwerk
|
||||
# inkl. Subnetzmaske und Gateway).
|
||||
#
|
||||
# Ausführen als root auf dem Proxmox-Host:
|
||||
# chmod +x proxmox-inventory.sh
|
||||
# ./proxmox-inventory.sh
|
||||
#
|
||||
# Die Ausgabe kannst du 1:1 kopieren und zurückgeben, um die Outline-Doku
|
||||
# aktualisieren zu lassen. Optional: Ausgabe in Datei umleiten:
|
||||
# ./proxmox-inventory.sh > inventory.txt
|
||||
#
|
||||
set -euo pipefail
|
||||
separator() { printf '%s\n' "----------------------------------------------------------------------"; }
|
||||
|
||||
# Wandelt eine CIDR-Prefixlänge (z. B. 24) in eine Subnetzmaske (255.255.255.0) um.
|
||||
cidr_to_netmask() {
|
||||
local cidr="$1"
|
||||
if ! [[ "$cidr" =~ ^[0-9]+$ ]] || [ "$cidr" -lt 0 ] || [ "$cidr" -gt 32 ]; then
|
||||
echo "-"
|
||||
return
|
||||
fi
|
||||
local mask=0
|
||||
if [ "$cidr" -gt 0 ]; then
|
||||
mask=$(( 0xffffffff ^ ((1 << (32 - cidr)) - 1) ))
|
||||
else
|
||||
mask=0
|
||||
fi
|
||||
printf "%d.%d.%d.%d\n" \
|
||||
"$(( (mask >> 24) & 255 ))" \
|
||||
"$(( (mask >> 16) & 255 ))" \
|
||||
"$(( (mask >> 8) & 255 ))" \
|
||||
"$(( mask & 255 ))"
|
||||
}
|
||||
|
||||
echo "########################################"
|
||||
echo "# Proxmox Inventar - $(hostname) - $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "########################################"
|
||||
echo
|
||||
# ---------------------------------------------------------------------------
|
||||
# LXC Container
|
||||
# ---------------------------------------------------------------------------
|
||||
echo "=========================================="
|
||||
echo " LXC CONTAINER"
|
||||
echo "=========================================="
|
||||
echo
|
||||
|
||||
for VMID in $(pct list | awk 'NR>1 {print $1}'); do
|
||||
separator
|
||||
echo "VMID: $VMID"
|
||||
pct list | awk -v id="$VMID" '$1==id {print "Status: " $2; print "Name (pct list): " $3}'
|
||||
|
||||
CONFIG=$(pct config "$VMID" 2>/dev/null || true)
|
||||
HOSTNAME=$(echo "$CONFIG" | grep -E '^hostname:' | cut -d' ' -f2- || echo "-")
|
||||
CORES=$(echo "$CONFIG" | grep -E '^cores:' | cut -d' ' -f2- || echo "-")
|
||||
MEMORY=$(echo "$CONFIG" | grep -E '^memory:' | cut -d' ' -f2- || echo "-")
|
||||
SWAP=$(echo "$CONFIG" | grep -E '^swap:' | cut -d' ' -f2- || echo "-")
|
||||
ROOTFS=$(echo "$CONFIG" | grep -E '^rootfs:' | cut -d' ' -f2- || echo "-")
|
||||
echo "Hostname (config): $HOSTNAME"
|
||||
echo "Cores: $CORES"
|
||||
echo "Memory (MB): $MEMORY"
|
||||
echo "Swap (MB): $SWAP"
|
||||
echo "Rootfs/Storage: $ROOTFS"
|
||||
|
||||
echo "Netzwerk-Konfiguration:"
|
||||
echo "$CONFIG" | grep -E '^net[0-9]+:' | while read -r LINE; do
|
||||
echo " $LINE"
|
||||
done
|
||||
|
||||
# Gateway und CIDR-Prefix aus der net0-Zeile der Config extrahieren (statische Konfiguration)
|
||||
NET0_LINE=$(echo "$CONFIG" | grep -E '^net0:' || true)
|
||||
CFG_GW=$(echo "$NET0_LINE" | grep -oP 'gw=\K[0-9.]+' || echo "")
|
||||
CFG_CIDR=$(echo "$NET0_LINE" | grep -oP 'ip=[0-9.]+/\K[0-9]+' || echo "")
|
||||
|
||||
# Tatsächlich zugewiesene IP + Prefix (falls Container läuft und Tools installiert sind)
|
||||
LIVE_GW=""
|
||||
LIVE_CIDR=""
|
||||
if pct status "$VMID" 2>/dev/null | grep -q running; then
|
||||
IP=$(pct exec "$VMID" -- ip -4 -o addr show scope global 2>/dev/null | awk '{print $4}' | paste -sd ', ' || echo "n/a")
|
||||
echo "Live-IP(s): $IP"
|
||||
LIVE_CIDR=$(pct exec "$VMID" -- ip -4 -o addr show scope global 2>/dev/null | head -1 | awk '{print $4}' | cut -d/ -f2 || echo "")
|
||||
LIVE_GW=$(pct exec "$VMID" -- ip -4 route show default 2>/dev/null | awk '{print $3}' | head -1 || echo "")
|
||||
else
|
||||
echo "Live-IP(s): (Container gestoppt)"
|
||||
fi
|
||||
|
||||
# Gateway: bevorzugt live ermittelt, sonst aus Config
|
||||
GW="${LIVE_GW:-${CFG_GW:-"-"}}"
|
||||
[ -z "$GW" ] && GW="-"
|
||||
echo "Gateway: $GW"
|
||||
|
||||
# Subnetzmaske: bevorzugt live ermittelter Prefix, sonst Config-Prefix
|
||||
CIDR="${LIVE_CIDR:-${CFG_CIDR:-""}}"
|
||||
if [ -n "$CIDR" ]; then
|
||||
NETMASK=$(cidr_to_netmask "$CIDR")
|
||||
echo "Subnetzmaske: $NETMASK (/$CIDR)"
|
||||
else
|
||||
echo "Subnetzmaske: -"
|
||||
fi
|
||||
|
||||
echo
|
||||
done
|
||||
|
||||
echo
|
||||
echo "=========================================="
|
||||
echo " VIRTUELLE MASCHINEN (QEMU/KVM)"
|
||||
echo "=========================================="
|
||||
echo
|
||||
|
||||
for VMID in $(qm list | awk 'NR>1 {print $1}'); do
|
||||
separator
|
||||
echo "VMID: $VMID"
|
||||
qm list | awk -v id="$VMID" '$1==id {print "Name (qm list): " $2; print "Status: " $3}'
|
||||
|
||||
CONFIG=$(qm config "$VMID" 2>/dev/null || true)
|
||||
CORES=$(echo "$CONFIG" | grep -E '^cores:' | cut -d' ' -f2- || echo "-")
|
||||
SOCKETS=$(echo "$CONFIG"| grep -E '^sockets:'| cut -d' ' -f2- || echo "-")
|
||||
MEMORY=$(echo "$CONFIG" | grep -E '^memory:' | cut -d' ' -f2- || echo "-")
|
||||
echo "Cores: $CORES"
|
||||
echo "Sockets: $SOCKETS"
|
||||
echo "Memory (MB): $MEMORY"
|
||||
echo "Disks:"
|
||||
echo "$CONFIG" | grep -E '^(scsi|sata|virtio|ide)[0-9]+:' | while read -r LINE; do
|
||||
echo " $LINE"
|
||||
done
|
||||
echo "Netzwerk-Konfiguration:"
|
||||
echo "$CONFIG" | grep -E '^net[0-9]+:' | while read -r LINE; do
|
||||
echo " $LINE"
|
||||
done
|
||||
|
||||
# Cloud-Init-Netzwerkdaten (falls vorhanden): ipconfig0: ip=X.X.X.X/24,gw=Y.Y.Y.Y
|
||||
IPCONFIG_LINE=$(echo "$CONFIG" | grep -E '^ipconfig0:' || true)
|
||||
CFG_GW=$(echo "$IPCONFIG_LINE" | grep -oP 'gw=\K[0-9.]+' || echo "")
|
||||
CFG_CIDR=$(echo "$IPCONFIG_LINE" | grep -oP 'ip=[0-9.]+/\K[0-9]+' || echo "")
|
||||
|
||||
LIVE_CIDR=""
|
||||
# QEMU-Guest-Agent IP/Prefix, falls installiert & VM läuft
|
||||
if qm status "$VMID" 2>/dev/null | grep -q running; then
|
||||
AGENT_JSON=$(qm guest cmd "$VMID" network-get-interfaces 2>/dev/null || echo "")
|
||||
IP=$(echo "$AGENT_JSON" \
|
||||
| grep -o '"ip-address":"[^"]*"' \
|
||||
| grep -v '127.0.0.1' \
|
||||
| cut -d'"' -f4 \
|
||||
| paste -sd ', ' || echo "")
|
||||
if [ -n "$IP" ]; then
|
||||
echo "Live-IP(s) via Guest-Agent: $IP"
|
||||
# Prefix der ersten nicht-lokalen Adresse ermitteln
|
||||
LIVE_CIDR=$(echo "$AGENT_JSON" | grep -oP '"prefix":\K[0-9]+' | head -1 || echo "")
|
||||
else
|
||||
echo "Live-IP(s) via Guest-Agent: n/a (kein Guest-Agent?)"
|
||||
fi
|
||||
else
|
||||
echo "Live-IP(s): (VM gestoppt)"
|
||||
fi
|
||||
|
||||
# Gateway: nur über Cloud-Init-Config ermittelbar (Guest-Agent liefert kein Gateway)
|
||||
GW="${CFG_GW:-"-"}"
|
||||
[ -z "$GW" ] && GW="-"
|
||||
echo "Gateway: $GW"
|
||||
|
||||
CIDR="${LIVE_CIDR:-${CFG_CIDR:-""}}"
|
||||
if [ -n "$CIDR" ]; then
|
||||
NETMASK=$(cidr_to_netmask "$CIDR")
|
||||
echo "Subnetzmaske: $NETMASK (/$CIDR)"
|
||||
else
|
||||
echo "Subnetzmaske: - (nicht ermittelbar ohne Cloud-Init-Config oder Guest-Agent-Prefix)"
|
||||
fi
|
||||
|
||||
echo
|
||||
done
|
||||
|
||||
echo
|
||||
echo "########################################"
|
||||
echo "# Ende der Ausgabe"
|
||||
echo "########################################"
|
||||
Reference in New Issue
Block a user