Initial commit — SETEC LABS Manager (Setec_CDM)
Flask-based VPS management panel with SSH remote command execution. Includes E2E encrypted SSH tunnel (AES-256-GCM + Go agent), setup wizard, security hardening tools, DNS management, firewall configs, monitoring, backup, and .sec patch update system. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
110
setec-web/dns_client.py
Normal file
110
setec-web/dns_client.py
Normal file
@@ -0,0 +1,110 @@
|
||||
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"]}
|
||||
Reference in New Issue
Block a user