some fixes

This commit is contained in:
2026-08-07 10:04:31 +02:00
parent 6dd541b798
commit c7e575ff9b
12 changed files with 65 additions and 14 deletions
+15 -1
View File
@@ -1,3 +1,9 @@
"""Cloudflare DNS-Update-Modul.
Erwartet Subdomain-Teile relativ zur Zone (z.B. "sub1" oder "*.home"),
keine FQDNs (z.B. NICHT "sub1.example.org").
"""
import logging
import requests
@@ -20,12 +26,20 @@ def _headers(api_token: str):
def _find_record_id(zone_id: str, api_token: str, name: str):
url = f"{API_BASE}/zones/{zone_id}/dns_records"
resp = requests.get(url, headers=_headers(api_token), params={"type": "A", "name": name}, timeout=15)
resp = requests.get(
url, headers=_headers(api_token), params={"type": "A", "name": name}, timeout=15
)
resp.raise_for_status()
data = resp.json()
results = data.get("result", [])
if not results:
return None
if len(results) > 1:
log.warning(
"Mehrere A-Records fuer '%s' gefunden (%d), nur erster wird aktualisiert.",
name,
len(results),
)
return results[0]["id"]
+1 -1
View File
@@ -1,6 +1,6 @@
import logging
import os
import sys
import logging
logging.basicConfig(
level=os.environ.get("LOG_LEVEL", "INFO"),
+3 -2
View File
@@ -11,8 +11,9 @@ class FritzBoxError(Exception):
pass
def get_external_ip(host: str, port: int, user: str, password: str, retries: int = 3,
backoff_seconds=(2, 5, 10)) -> str:
def get_external_ip(
host: str, port: int, user: str, password: str, retries: int = 3, backoff_seconds=(2, 5, 10)
) -> str:
last_exc = None
for attempt in range(1, retries + 1):
try:
+1 -1
View File
@@ -16,7 +16,7 @@ def ping(ping_url: str, status: str = "success", message: str = ""):
body = message or status
try:
requests.post(url, data=body.encode("utf-8"), timeout=10)
requests.post(url, data=body.encode("utf-8"), timeout=5)
log.debug("Healthcheck-Ping gesendet (%s): %s", status, message)
except requests.RequestException as exc:
log.warning("Healthcheck-Ping fehlgeschlagen: %s", exc)
+10 -4
View File
@@ -1,18 +1,20 @@
import concurrent.futures
import logging
import threading
from apscheduler.schedulers.background import BackgroundScheduler
from flask import Flask
from app import cloudflare, freedns, healthcheck, state
from app.config import config
from app.fritzbox import FritzBoxError, get_external_ip
from app import state, cloudflare, freedns, healthcheck
log = logging.getLogger("main")
app = Flask(__name__)
_lock = threading.Lock()
_executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
def run_cycle(trigger: str = "unknown"):
@@ -32,7 +34,9 @@ def run_cycle(trigger: str = "unknown"):
last_ip = state.load(config.state_path)
if current_ip == last_ip:
if last_ip is None:
log.info("Erstlauf - IP wird gesetzt: %s", current_ip)
elif current_ip == last_ip:
log.info("IP unveraendert (%s) - kein DNS-Update noetig.", current_ip)
if trigger == "poll":
healthcheck.ping(
@@ -78,7 +82,7 @@ def run_cycle(trigger: str = "unknown"):
@app.route("/webhook/update", methods=["GET"])
def webhook_update():
threading.Thread(target=run_cycle, kwargs={"trigger": "webhook"}, daemon=True).start()
_executor.submit(run_cycle, trigger="webhook")
return {"status": "triggered"}, 202
@@ -104,7 +108,9 @@ def main():
scheduler.start()
log.info("Fallback-Polling gestartet (alle %d Minuten).", config.poll_interval_minutes)
log.info("Webhook-Server startet auf Port %d (GET /webhook/update, kein Auth).", config.webhook_port)
log.info(
"Webhook-Server startet auf Port %d (GET /webhook/update, kein Auth).", config.webhook_port
)
app.run(host="0.0.0.0", port=config.webhook_port)
+1 -1
View File
@@ -10,7 +10,7 @@ def load(state_path: str):
log.info("Keine vorherige State-Datei gefunden (%s) - Erstlauf.", state_path)
return None
try:
with open(state_path, "r") as f:
with open(state_path) as f:
data = json.load(f)
return data.get("last_ip")
except (json.JSONDecodeError, OSError) as exc: