ProxmoxVED/tools/pve/prx-add-ips.sh
2025-08-29 11:41:08 +02:00

188 lines
5.0 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# -----------------------------------------------------------------
# Proxmox Add-IPs (LXC + VMs → Tags)
# -----------------------------------------------------------------
# © 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT
# -----------------------------------------------------------------
APP="Proxmox Add-IPs"
FILE_PATH="/usr/local/bin/prx-add-ips"
CONF_DIR="/opt/prx-add-ips"
CONF_FILE="$CONF_DIR/prx-add-ips.conf"
set -Eeuo pipefail
# --- Farben (optional) ---
YW="\033[33m"
GN="\033[1;92m"
RD="\033[01;31m"
CL="\033[m"
msg() { [[ "${USE_COLOR:-true}" == "true" ]] && echo -e "$@" || echo -e "$(echo "$@" | sed -E 's/\x1B\[[0-9;]*[JKmsu]//g')"; }
msg_info() { msg "${YW}$1${CL}"; }
msg_ok() { msg "${GN}$1${CL}"; }
msg_error() { msg "${RD}$1${CL}"; }
# -----------------------------------------------------------------
# Installation
# -----------------------------------------------------------------
if [[ -f "$FILE_PATH" ]]; then
msg_info "$APP already installed at $FILE_PATH"
exit 0
fi
msg_info "Installing dependencies"
apt-get update -qq
apt-get install -y jq ipcalc net-tools >/dev/null
msg_ok "Dependencies installed"
mkdir -p "$CONF_DIR"
# -----------------------------------------------------------------
# Config
# -----------------------------------------------------------------
if [[ ! -f "$CONF_FILE" ]]; then
cat <<EOF >"$CONF_FILE"
# prx-add-ips.conf configuration for Proxmox Add-IPs
# Allowed CIDRs
CIDR_LIST=(
192.168.0.0/16
10.0.0.0/8
172.16.0.0/12
)
# Main loop interval in seconds
LOOP_INTERVAL=60
# Use colored output? (true/false)
USE_COLOR=true
EOF
msg_ok "Default config written to $CONF_FILE"
else
msg_info "Config $CONF_FILE already exists"
fi
# -----------------------------------------------------------------
# Main Script
# -----------------------------------------------------------------
cat <<"EOF" >"$FILE_PATH"
#!/usr/bin/env bash
set -Eeuo pipefail
CONFIG_FILE="/opt/prx-add-ips/prx-add-ips.conf"
[[ -f "$CONFIG_FILE" ]] && source "$CONFIG_FILE"
YW="\033[33m"; GN="\033[1;92m"; RD="\033[01;31m"; CL="\033[m"
msg() { [[ "${USE_COLOR:-true}" == "true" ]] && echo -e "$@" || echo -e "$(echo "$@" | sed -E 's/\x1B\[[0-9;]*[JKmsu]//g')"; }
msg_info() { msg "${YW}$1${CL}"; }
msg_ok() { msg "${GN}$1${CL}"; }
msg_error(){ msg "${RD}$1${CL}"; }
is_valid_ipv4() {
local ip=$1
[[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1
for part in ${ip//./ }; do
((part >= 0 && part <= 255)) || return 1
done
return 0
}
ip_in_cidrs() {
local ip="$1"
for cidr in "${CIDR_LIST[@]}"; do
ipcalc -nb "$cidr" "$ip" &>/dev/null && return 0
done
return 1
}
set_tags() {
local vmid="$1" kind="$2"; shift 2
local ips=("$@")
# aktuelle Tags holen
local existing_tags=()
mapfile -t existing_tags < <($kind config "$vmid" | awk '/tags:/{$1=""; print}' | tr ';' '\n')
local existing_ips=()
local non_ip_tags=()
for t in "${existing_tags[@]}"; do
if is_valid_ipv4 "$t"; then
existing_ips+=("$t")
else
non_ip_tags+=("$t")
fi
done
local new_tags=("${non_ip_tags[@]}" "${ips[@]}")
new_tags=($(printf "%s\n" "${new_tags[@]}" | sort -u))
if [[ "$(printf "%s\n" "${existing_ips[@]}" | sort -u)" != "$(printf "%s\n" "${ips[@]}" | sort -u)" ]]; then
msg_info "$kind $vmid → updating tags to ${new_tags[*]}"
$kind set "$vmid" -tags "$(IFS=';'; echo "${new_tags[*]}")"
else
msg_info "$kind $vmid → no IP change"
fi
}
update_lxc_iptags() {
for vmid in $(pct list | awk 'NR>1 {print $1}'); do
local ips=()
for ip in $(lxc-info -n "$vmid" -iH 2>/dev/null); do
is_valid_ipv4 "$ip" && ip_in_cidrs "$ip" && ips+=("$ip")
done
[[ ${#ips[@]} -gt 0 ]] && set_tags "$vmid" pct "${ips[@]}"
done
}
update_vm_iptags() {
for vmid in $(qm list | awk 'NR>1 {print $1}'); do
if qm agent "$vmid" ping &>/dev/null; then
local ips=()
mapfile -t ips < <(qm agent "$vmid" network-get-interfaces \
| jq -r '.[]?."ip-addresses"[]?."ip-address" | select(test("^[0-9]+\\."))')
local filtered=()
for ip in "${ips[@]}"; do
is_valid_ipv4 "$ip" && ip_in_cidrs "$ip" && filtered+=("$ip")
done
[[ ${#filtered[@]} -gt 0 ]] && set_tags "$vmid" qm "${filtered[@]}"
fi
done
}
while true; do
update_lxc_iptags
update_vm_iptags
sleep "${LOOP_INTERVAL:-60}"
done
EOF
chmod +x "$FILE_PATH"
msg_ok "Main script installed to $FILE_PATH"
# -----------------------------------------------------------------
# Systemd Service
# -----------------------------------------------------------------
SERVICE="/etc/systemd/system/prx-add-ips.service"
if [[ ! -f "$SERVICE" ]]; then
cat <<EOF >"$SERVICE"
[Unit]
Description=Proxmox Add-IPs (LXC + VM)
After=network.target
[Service]
Type=simple
ExecStart=$FILE_PATH
Restart=always
[Install]
WantedBy=multi-user.target
EOF
msg_ok "Service created"
fi
systemctl daemon-reload
systemctl enable -q --now prx-add-ips.service
msg_ok "$APP service started"