"""Tailscale Netzwerk-Status Tool.""" import json import subprocess TOOLS = [ { "type": "function", "function": { "name": "get_tailscale_status", "description": "Tailscale VPN Netzwerk-Status: Welche Geraete/Server sind online oder offline? Nutze bei 'ist Server X erreichbar', 'welche Geraete sind online', 'Netzwerk-Status', 'VPN'.", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "Optional: Name filtern (z.B. 'pve', 'gold', 'wordpress')", "default": ""} }, "required": [], }, }, }, ] def handle_get_tailscale_status(query="", **kw): try: out = subprocess.check_output( ["tailscale", "status", "--json"], text=True, timeout=10 ) except Exception as e: return f"Tailscale nicht verfuegbar: {e}" d = json.loads(out) peers = d.get("Peer", {}) devices = [] for key, p in peers.items(): name = p.get("HostName", "?") ip = p.get("TailscaleIPs", ["?"])[0] online = p.get("Online", False) last = p.get("LastSeen", "")[:10] devices.append({"name": name, "ip": ip, "online": online, "last": last}) if query: q = query.lower() devices = [d for d in devices if q in d["name"].lower() or q in d["ip"]] online = [d for d in devices if d["online"]] offline = [d for d in devices if not d["online"]] lines = [f"Tailscale: {len(online)} online, {len(offline)} offline (von {len(devices)} Geraeten)"] if online: lines.append(f"\n=== ONLINE ({len(online)}) ===") for d in sorted(online, key=lambda x: x["name"]): lines.append(f" {d['name']:28s} {d['ip']}") if offline: lines.append(f"\n=== OFFLINE ({len(offline)}) ===") for d in sorted(offline, key=lambda x: x["name"]): lines.append(f" {d['name']:28s} {d['ip']:18s} zuletzt: {d['last']}") return "\n".join(lines) HANDLERS = { "get_tailscale_status": handle_get_tailscale_status, }