From 9736a007f1cfddfdd96250db1426f38312d1ee6b Mon Sep 17 00:00:00 2001 From: meteo Date: Sun, 17 May 2026 21:06:17 +0200 Subject: [PATCH] first working release --- .env-sample | 4 +- README.md | 18 +++++++-- proxmox-to-sentri.sh | 90 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 97 insertions(+), 15 deletions(-) diff --git a/.env-sample b/.env-sample index 04012ec..e688968 100644 --- a/.env-sample +++ b/.env-sample @@ -1,3 +1,5 @@ PM_HOST="https://proxmox.example.com:8006" PM_USER="root@pam" -PM_PASS="super-secret-password" \ No newline at end of file +PM_PASS="super-secret-password" +SENTRI_URL="https://sentri.nl/api/v1/servers/" +SENTRI_TOKEN="your-api-token" \ No newline at end of file diff --git a/README.md b/README.md index b5d81e8..a7ba415 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ The script collects information such as: - VM descriptions/notes --- + # Requirements ## System Requirements The machine running this script must: @@ -38,22 +39,29 @@ sudo dnf install -y qemu-guest-agent sudo systemctl enable --now qemu-guest-agent ``` Then enable the QEMU Guest Agent in Proxmox: -``` +```bash qm set --agent enabled=1 ``` --- + # Installation Clone the repository and configure the environment file: -``` -cd /optgit clone https://gitea.mooij.me/meteo/proxmox-to-sentri.gitcd proxmox-to-sentricp .env-sample .envchmod 600 .envchmod 740 proxmox-to-sentri.sh +```bash +cd /opt +git clone https://gitea.mooij.me/meteo/proxmox-to-sentri.git +cd proxmox-to-sentri +cp .env-sample .env +chmod 600 .env +chmod 740 proxmox-to-sentri.sh ``` Optional: Create a global command: -``` +```bash ln -sf /opt/proxmox-to-sentri/proxmox-to-sentri.sh /usr/bin/proxmox-to-sentri ``` --- + # Configuration Edit the `.env` file and configure the Proxmox connection settings: ``` @@ -63,6 +71,7 @@ PM_PASS="your-password" ``` --- + # Running the Script Run the script directly: @@ -75,6 +84,7 @@ proxmox-to-sentri ``` --- + # Output Generated JSON files are written to: diff --git a/proxmox-to-sentri.sh b/proxmox-to-sentri.sh index f7c76c3..f1bc128 100755 --- a/proxmox-to-sentri.sh +++ b/proxmox-to-sentri.sh @@ -53,6 +53,12 @@ fi : "${PM_USER:?Missing PM_USER}" : "${PM_PASS:?Missing PM_PASS}" +# Sentri API configuration +: "${SENTRI_URL:?Missing SENTRI_URL}" +: "${SENTRI_TOKEN:?Missing SENTRI_TOKEN}" + +SERVERS_JSON="[]" + # Authenticate AUTH_RESPONSE=$(curl -sk \ --data-urlencode "username=${PM_USER}" \ @@ -80,12 +86,18 @@ echo "Collecting VMs..." VMS=$(api_get "/api2/json/cluster/resources?type=vm") -echo "$VMS" | jq -c '.data[]' | while read -r VM; do +while read -r VM; do VMID=$(echo "$VM" | jq -r '.vmid') NODE=$(echo "$VM" | jq -r '.node') NAME=$(echo "$VM" | jq -r '.name') - STATUS=$(echo "$VM" | jq -r '.status') + STATUS=$(echo "$VM" | jq -r ' + .status + | if . == "running" then "Running" + elif . == "stopped" then "Off" + else "Running" + end + ') CPU=$(echo "$VM" | jq -r '.maxcpu') MEMORY_MB=$(echo "$VM" | jq -r '.maxmem / 1024 / 1024 | floor') @@ -188,7 +200,28 @@ echo "$VMS" | jq -c '.data[]' | while read -r VM; do DISK_LOCATION=$(echo "$DISKCONF" | cut -d',' -f1) - SIZE=$(echo "$DISKCONF" | sed -n 's/.*size=\([^,]*\).*/\1/p') + SIZE=$(echo "$DISKCONF" | sed -n 's/.*size=\([^,]*\).*/\1/p' \ + | awk ' + function ceil(x) { return (x == int(x)) ? x : int(x)+1 } + + { + if ($0 ~ /G$/) { + gsub(/G/, "", $0) + printf "%d", ceil($0) + } + else if ($0 ~ /M$/) { + gsub(/M/, "", $0) + printf "%d", ceil($0 / 1024) + } + else if ($0 ~ /T$/) { + gsub(/T/, "", $0) + printf "%d", ceil($0 * 1024) + } + else { + printf "%d", $0 + } + } + ') DISKS_JSON=$(echo "$DISKS_JSON" | jq \ --arg name "$DISKKEY" \ @@ -212,26 +245,25 @@ echo "$VMS" | jq -c '.data[]' | while read -r VM; do ) # Build JSON + SERVER_JSON=$( jq -n \ --arg vmid "$MAC" \ --arg vmhost "$NAME" \ --arg power "$STATUS" \ - --arg hostname "$NAME" \ --arg os "$OS" \ --argjson cpu "$CPU" \ --argjson memory "$MEMORY_MB" \ --argjson snapshot "$SNAPSHOT_COUNT" \ --arg description "$DESCRIPTION" \ --argjson disks "$DISKS_JSON" \ - --argjson ipv4 "$(printf '%s\n' "${IPV4[@]}" | jq -R . | jq -s .)" \ - --argjson ipv6 "$(printf '%s\n' "${IPV6[@]}" | jq -R . | jq -s .)" \ + --argjson ipv4 "$(printf '%s\n' "${IPV4[@]:-}" | jq -R . | jq -s .)" \ + --argjson ipv6 "$(printf '%s\n' "${IPV6[@]:-}" | jq -R . | jq -s .)" \ --arg backup "$BACKUP_ENABLED" ' { "server_vm_id": $vmid, "server_vm_host_name": $vmhost, "server_power_state": $power, "server_state": "new", - "server_hostname": $hostname } + ( @@ -260,10 +292,48 @@ echo "$VMS" | jq -c '.data[]' | while read -r VM; do ), "server_description": $description } - ' > "${OUTPUT_DIR}/${VMID}.json" + ') -done + # Save per-VM JSON + echo "$SERVER_JSON" > "${OUTPUT_DIR}/${VMID}.json" + + # Add VM to combined payload + SERVERS_JSON=$(jq -n \ + --argjson old "$SERVERS_JSON" \ + --argjson server "$SERVER_JSON" \ + '$old + [$server]') + +done < <( + echo "$VMS" | jq -c '.data[]? // empty' +) + + +FINAL_PAYLOAD=$(jq -n \ + --argjson servers "$SERVERS_JSON" ' + { + "servers": $servers + } +') + +# Save combined payload +echo "$FINAL_PAYLOAD" | jq . > "${OUTPUT_DIR}/servers.json" +echo +echo "Uploading payload to Sentri..." + +RESPONSE=$(curl -sk \ + -X POST \ + -H "Authorization: Bearer ${SENTRI_TOKEN}" \ + -H "Content-Type: application/json" \ + --data "$FINAL_PAYLOAD" \ + "${SENTRI_URL}" +) + +echo +echo "Sentri API response:" +echo "$RESPONSE" | jq . || echo "$RESPONSE" +echo "Combined payload written to:" +echo "${OUTPUT_DIR}/servers.json" +echo "Individual server json files written to: ${OUTPUT_DIR}/" echo echo "Done." -echo "JSON files written to: ${OUTPUT_DIR}/" \ No newline at end of file