import requests import ssh_client import config BASE = "https://api.hostinger.com/api/dns/v1/zones" def _headers(): cfg = config.load() return { "Authorization": f"Bearer {cfg['hostinger_api_key']}", "Content-Type": "application/json", } def _domain(): return config.load()["domain"] def get_records(): """Try Hostinger API first (via VPS to avoid Cloudflare), fall back to dig.""" cfg = config.load() key = cfg.get("hostinger_api_key", "") domain = cfg["domain"] # Try API via VPS try: cmd = ( f"curl -s -w '\\nHTTP_CODE:%{{http_code}}' " f"-H 'Authorization: Bearer {key}' " f"-H 'Content-Type: application/json' " f"'https://api.hostinger.com/api/dns/v1/zones/{domain}' 2>&1" ) result = ssh_client.run(cmd, timeout=15) output = result["stdout"] if "HTTP_CODE:200" in output: import json body = output.rsplit("\nHTTP_CODE:", 1)[0] return json.loads(body) except Exception: pass # Try direct from local try: r = requests.get(f"{BASE}/{domain}", headers=_headers(), timeout=15) if r.status_code == 200: return r.json() except Exception: pass # Fallback: use dig to show current DNS records result = ssh_client.run( f"echo '=== A Records ===' && dig +short A {domain} && " f"echo '=== CNAME ===' && dig +short CNAME {domain} && " f"echo '=== MX ===' && dig +short MX {domain} && " f"echo '=== TXT ===' && dig +short TXT {domain} && " f"echo '=== NS ===' && dig +short NS {domain} && " f"echo '=== Subdomains ===' && " f"for sub in repo git app files lists mail www; do " f" ip=$(dig +short A $sub.{domain}); " f" [ -n \"$ip\" ] && echo \"$sub.{domain} -> $ip\"; " f"done", timeout=15, ) return {"source": "dig (API unavailable)", "records": result["stdout"]} def add_a_record(name, ip, ttl=14400): cfg = config.load() key = cfg.get("hostinger_api_key", "") domain = cfg["domain"] payload = f'{{"records":[{{"name":"{name}","type":"A","content":"{ip}","ttl":{ttl}}}],"overwrite":false}}' result = ssh_client.run( f"curl -s -w '\\nHTTP_CODE:%{{http_code}}' -X PUT " f"-H 'Authorization: Bearer {key}' " f"-H 'Content-Type: application/json' " f"-d '{payload}' " f"'https://api.hostinger.com/api/dns/v1/zones/{domain}' 2>&1", timeout=15, ) return {"response": result["stdout"]} def add_txt_record(name, value, ttl=14400): cfg = config.load() key = cfg.get("hostinger_api_key", "") domain = cfg["domain"] payload = f'{{"records":[{{"name":"{name}","type":"TXT","content":"{value}","ttl":{ttl}}}],"overwrite":false}}' result = ssh_client.run( f"curl -s -w '\\nHTTP_CODE:%{{http_code}}' -X PUT " f"-H 'Authorization: Bearer {key}' " f"-H 'Content-Type: application/json' " f"-d '{payload}' " f"'https://api.hostinger.com/api/dns/v1/zones/{domain}' 2>&1", timeout=15, ) return {"response": result["stdout"]} def delete_record(record_id): cfg = config.load() key = cfg.get("hostinger_api_key", "") domain = cfg["domain"] result = ssh_client.run( f"curl -s -w '\\nHTTP_CODE:%{{http_code}}' -X DELETE " f"-H 'Authorization: Bearer {key}' " f"'https://api.hostinger.com/api/dns/v1/zones/{domain}/records/{record_id}' 2>&1", timeout=15, ) return {"response": result["stdout"]}