[READ-ONLY] Mirror of https://github.com/mrgnw/scripts.
0

Configure Feed

Select the types of activity you want to include in your feed.

scripts / cf-tunnel-dns
1.5 kB 62 lines
1#!/usr/bin/env -S uv run --script 2# /// script 3# requires-python = ">=3.14" 4# dependencies = ["pyyaml"] 5# /// 6 7import subprocess 8import sys 9from pathlib import Path 10from concurrent.futures import ThreadPoolExecutor, as_completed 11import yaml 12 13CONFIG = Path.home() / ".cloudflared" / "config.yml" 14 15def register(tunnel: str, hostname: str) -> tuple[str, bool, str]: 16 result = subprocess.run( 17 ["cloudflared", "tunnel", "route", "dns", tunnel, hostname], 18 capture_output=True, 19 text=True, 20 ) 21 combined = result.stdout + result.stderr 22 ok = result.returncode == 0 or "already exists" in combined.lower() 23 return hostname, ok, combined.strip() 24 25def main(): 26 config = yaml.safe_load(CONFIG.read_text()) 27 tunnel = config["tunnel"] 28 29 hostnames = [ 30 rule["hostname"] 31 for rule in config.get("ingress", []) 32 if "hostname" in rule 33 ] 34 35 if not hostnames: 36 print("No hostnames found in config.yml") 37 return 38 39 print(f"Tunnel: {tunnel}") 40 print(f"Syncing {len(hostnames)} DNS routes:\n") 41 42 ok = [] 43 failed = [] 44 45 with ThreadPoolExecutor(max_workers=10) as pool: 46 futures = {pool.submit(register, tunnel, h): h for h in hostnames} 47 for future in as_completed(futures): 48 hostname, success, output = future.result() 49 if success: 50 print(f" ✓ {hostname}") 51 ok.append(hostname) 52 else: 53 print(f" ✗ {hostname}") 54 print(f" {output}") 55 failed.append(hostname) 56 57 print(f"\n{len(ok)} ok, {len(failed)} failed") 58 if failed: 59 sys.exit(1) 60 61if __name__ == "__main__": 62 main()