#!/usr/bin/env python3 """Remove temporary Wifi-Otantik hosts from otantikhub.com. Keep apex, portal, ld.""" from __future__ import annotations import json import os import sys import time import urllib.error import urllib.request TOKEN = os.environ.get("CF_TOKEN", "").strip() ACCOUNT = "67432c1959c4bc5272137831e5f2d4d9" TUNNEL = "3d6fc119-d147-4954-9015-fd75b8f43ed8" DROP_HOSTS = {"wifi.otantikhub.com", "business.otantikhub.com", "pay.otantikhub.com"} PROTECTED = {"otantikhub.com", "www.otantikhub.com", "portal.otantikhub.com", "ld.otantikhub.com"} def cf(method: str, path: str, body: dict | None = None, tries: int = 4): data = None if body is None else json.dumps(body).encode() last = None for i in range(tries): req = urllib.request.Request( "https://api.cloudflare.com/client/v4" + path, data=data, method=method, headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}, ) try: with urllib.request.urlopen(req, timeout=90) as resp: parsed = json.loads(resp.read().decode()) if not parsed.get("success"): print("API error", path, parsed.get("errors")) raise SystemExit(1) return parsed.get("result") except urllib.error.HTTPError as e: print("HTTP", e.code, path, e.read().decode("utf-8", "replace")[:1500]) raise SystemExit(1) except Exception as e: last = e print("retry", i + 1, method, path, type(e).__name__) time.sleep(2 + i * 2) print("failed", method, path, last) raise SystemExit(1) def main() -> None: if not TOKEN: raise SystemExit("missing CF_TOKEN") zones = cf("GET", "/zones?name=otantikhub.com") or [] if not zones: raise SystemExit("zone otantikhub.com not found") zone_id = zones[0]["id"] cfg = cf("GET", f"/accounts/{ACCOUNT}/cfd_tunnel/{TUNNEL}/configurations") or {} config = cfg.get("config") or {} ingress = list(config.get("ingress") or []) kept, catchall = [], None for rule in ingress: host = rule.get("hostname") if not host: catchall = rule continue if host in DROP_HOSTS: print("drop ingress", host) continue if host in PROTECTED: print("keep", host) kept.append(rule) if catchall is None: catchall = {"service": "http_status:404"} config["ingress"] = kept + [catchall] cf("PUT", f"/accounts/{ACCOUNT}/cfd_tunnel/{TUNNEL}/configurations", {"config": config}) print("tunnel ingress:", [r.get("hostname") or r.get("service") for r in config["ingress"]]) recs = cf("GET", f"/zones/{zone_id}/dns_records?per_page=200") or [] by_name = {r["name"]: r for r in recs} for host in sorted(DROP_HOSTS): rec = by_name.get(host) if rec: print("delete dns", host) cf("DELETE", f"/zones/{zone_id}/dns_records/{rec['id']}") else: print("dns already gone", host) print("DONE") if __name__ == "__main__": main()