Refactor: Generalisierung der Konfiguration und atomares Schreiben der Zonefiles
This commit is contained in:
54
sync.py
54
sync.py
@@ -18,16 +18,16 @@ if not NETBOX_URL or not TOKEN:
|
||||
sys.exit(1)
|
||||
|
||||
# Optionale Konfiguration mit Defaults
|
||||
ZONE_NAME = os.getenv("ZONE_NAME", "klenzel.net")
|
||||
REVERSE_ZONE_NAME = os.getenv("REVERSE_ZONE_NAME", "172.in-addr.arpa")
|
||||
ZONE_NAME = os.getenv("ZONE_NAME", "example.com")
|
||||
REVERSE_ZONE_NAME = os.getenv("REVERSE_ZONE_NAME", "1.168.192.in-addr.arpa")
|
||||
REFRESH_INTERVAL = int(os.getenv("REFRESH_INTERVAL", "600"))
|
||||
OUTPUT_FILE_FWD = os.getenv("OUTPUT_FILE_FWD", "/zones/db.klenzel.net")
|
||||
OUTPUT_FILE_REV = os.getenv("OUTPUT_FILE_REV", "/zones/db.reverse.arpa")
|
||||
OUTPUT_FILE_FWD = os.getenv("OUTPUT_FILE_FWD", "/zones/db.fwd")
|
||||
OUTPUT_FILE_REV = os.getenv("OUTPUT_FILE_REV", "/zones/db.rev")
|
||||
DEFAULT_TTL = os.getenv("DEFAULT_TTL", "3600")
|
||||
|
||||
# Fallback Konfiguration (wenn KEIN NS in NetBox gefunden wird)
|
||||
FALLBACK_NS_HOSTNAME = os.getenv("FALLBACK_NS_HOSTNAME", "fks-01-cl-cdns")
|
||||
FALLBACK_NS_IP = os.getenv("FALLBACK_NS_IP", "172.25.16.152")
|
||||
FALLBACK_NS_HOSTNAME = os.getenv("FALLBACK_NS_HOSTNAME", "ns1")
|
||||
FALLBACK_NS_IP = os.getenv("FALLBACK_NS_IP", "127.0.0.1")
|
||||
|
||||
HEADERS = {'Authorization': f'Token {TOKEN}', 'Accept': 'application/json'}
|
||||
|
||||
@@ -113,6 +113,28 @@ def get_ns_config(plugin_records, all_records):
|
||||
|
||||
return primary_ns, extra_header_lines
|
||||
|
||||
def write_atomic(filepath, content):
|
||||
"""Schreibt Datei atomar: Erst in .tmp, dann move/replace."""
|
||||
tmp_path = filepath + ".tmp"
|
||||
try:
|
||||
# Verzeichnis sicherstellen
|
||||
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||
|
||||
with open(tmp_path, "w") as f:
|
||||
f.write(content)
|
||||
f.flush()
|
||||
os.fsync(f.fileno())
|
||||
os.replace(tmp_path, filepath)
|
||||
return True
|
||||
except Exception as e:
|
||||
log(f"ERROR beim Schreiben von {filepath}: {e}")
|
||||
if os.path.exists(tmp_path):
|
||||
try:
|
||||
os.remove(tmp_path)
|
||||
except:
|
||||
pass
|
||||
raise e
|
||||
|
||||
def generate_zone_file_fwd(ipam_data, plugin_records):
|
||||
"""Erstellt die Forward-Zone"""
|
||||
|
||||
@@ -152,11 +174,10 @@ def generate_zone_file_fwd(ipam_data, plugin_records):
|
||||
header.extend(extra_headers)
|
||||
header.append("")
|
||||
|
||||
with open(OUTPUT_FILE_FWD, "w") as f:
|
||||
f.write("\n".join(header))
|
||||
f.write("\n; --- Records ---\n")
|
||||
f.write("\n".join(all_records))
|
||||
f.write("\n")
|
||||
content = "\n".join(header) + "\n; --- Records ---
|
||||
" + "\n".join(all_records) + "\n"
|
||||
|
||||
write_atomic(OUTPUT_FILE_FWD, content)
|
||||
log(f"SUCCESS: Forward Zone geschrieben ({len(all_records)} Records).")
|
||||
|
||||
def generate_zone_file_rev(ipam_data, plugin_records):
|
||||
@@ -198,11 +219,10 @@ def generate_zone_file_rev(ipam_data, plugin_records):
|
||||
|
||||
header.append("")
|
||||
|
||||
with open(OUTPUT_FILE_REV, "w") as f:
|
||||
f.write("\n".join(header))
|
||||
f.write("\n; --- PTR Records ---\n")
|
||||
f.write("\n".join(ptr_records))
|
||||
f.write("\n")
|
||||
content = "\n".join(header) + "\n; --- PTR Records ---
|
||||
" + "\n".join(ptr_records) + "\n"
|
||||
|
||||
write_atomic(OUTPUT_FILE_REV, content)
|
||||
log(f"SUCCESS: Reverse Zone geschrieben ({len(ptr_records)} Records).")
|
||||
|
||||
if __name__ == "__main__":
|
||||
@@ -229,4 +249,4 @@ if __name__ == "__main__":
|
||||
log(f"CRITICAL ERROR: Sync abgebrochen! Behalte alte Zone-Files. Grund: {e}")
|
||||
|
||||
log(f"Schlafe {REFRESH_INTERVAL} Sekunden...")
|
||||
time.sleep(REFRESH_INTERVAL)
|
||||
time.sleep(REFRESH_INTERVAL)
|
||||
Reference in New Issue
Block a user