argus/src/bind/build/argus_dns_sync.sh
yuyr 1e5e91b193 dev_1.0.0_yuyr_2:重新提交 PR,增加 master/agent 以及系统集成测试 (#17)
Reviewed-on: #17
Reviewed-by: sundapeng <sundp@mail.zgclab.edu.cn>
Reviewed-by: xuxt <xuxt@zgclab.edu.cn>
2025-10-11 15:04:46 +08:00

107 lines
2.7 KiB
Bash
Raw 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
set -euo pipefail
WATCH_DIR="/private/argus/etc"
ZONE_DB="/private/argus/bind/db.argus.com"
LOCKFILE="/var/lock/argus_dns_sync.lock"
BACKUP_DIR="/private/argus/bind/.backup"
SLEEP_SECONDS=10
RELOAD_SCRIPT="/usr/local/bin/reload-bind9.sh" # 这里放你已有脚本的路径
mkdir -p "$(dirname "$LOCKFILE")" "$BACKUP_DIR"
BACKUP_UID="${ARGUS_BUILD_UID:-2133}"
BACKUP_GID="${ARGUS_BUILD_GID:-2015}"
chown -R "$BACKUP_UID:$BACKUP_GID" "$BACKUP_DIR" 2>/dev/null || true
is_ipv4() {
local ip="$1"
[[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1
IFS='.' read -r a b c d <<<"$ip"
for n in "$a" "$b" "$c" "$d"; do
(( n >= 0 && n <= 255 )) || return 1
done
return 0
}
get_current_ip() {
local name="$1"
sed -n -E "s/^${name}[[:space:]]+IN[[:space:]]+A[[:space:]]+([0-9.]+)[[:space:]]*$/\1/p" "$ZONE_DB" | head -n1
}
upsert_record() {
local name="$1"
local new_ip="$2"
local ts
ts="$(date +%Y%m%d-%H%M%S)"
local changed=0
cp -a "$ZONE_DB" "$BACKUP_DIR/db.argus.com.$ts.bak"
chown "$BACKUP_UID:$BACKUP_GID" "$BACKUP_DIR/db.argus.com.$ts.bak" 2>/dev/null || true
local cur_ip
cur_ip="$(get_current_ip "$name" || true)"
if [[ -z "$cur_ip" ]]; then
# Ensure the file ends with a newline before adding new record
if [[ -s "$ZONE_DB" ]] && [[ $(tail -c1 "$ZONE_DB" | wc -l) -eq 0 ]]; then
echo "" >> "$ZONE_DB"
fi
printf "%-20s IN A %s\n" "$name" "$new_ip" >> "$ZONE_DB"
echo "[ADD] ${name} -> ${new_ip}"
changed=1
elif [[ "$cur_ip" != "$new_ip" ]]; then
awk -v n="$name" -v ip="$new_ip" '
{
if ($1==n && $2=="IN" && $3=="A") {
printf "%-20s IN A %s\n", n, ip
} else {
print
}
}
' "$ZONE_DB" > "${ZONE_DB}.tmp" && mv "${ZONE_DB}.tmp" "$ZONE_DB"
echo "[UPDATE] ${name}: ${cur_ip} -> ${new_ip}"
changed=1
else
echo "[SKIP] ${name} unchanged (${new_ip})"
fi
if [[ $changed -eq 1 ]]; then
return 0
fi
return 1
}
while true; do
exec 9>"$LOCKFILE"
if flock -n 9; then
shopt -s nullglob
NEED_RELOAD=0
for f in "$WATCH_DIR"/*.argus.com; do
base="$(basename "$f")"
name="${base%.argus.com}"
ip="$(grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' "$f" | tail -n1 || true)"
if [[ -z "$ip" ]] || ! is_ipv4 "$ip"; then
echo "[WARN] $f 未找到有效 IPv4跳过"
continue
fi
if upsert_record "$name" "$ip"; then
NEED_RELOAD=1
fi
done
if [[ $NEED_RELOAD -eq 1 ]]; then
echo "[INFO] 检测到 db.argus.com 变更,执行 reload-bind9.sh"
bash "$RELOAD_SCRIPT"
fi
flock -u 9
else
echo "[INFO] 已有同步任务在运行,跳过本轮"
fi
sleep "$SLEEP_SECONDS"
done