Files
climperor/_cf_add_cname.py
T

63 lines
2.3 KiB
Python

"""Add the missing CNAME for dota2.refining.dev -> climperor-relations.pages.dev.
Cloudflare Pages bound the custom domain but did not auto-create the zone
CNAME, so SSL validation is stuck at 'CNAME record not set'. This adds it
(proxied so CF issues SSL + serves from the edge). Idempotent: skips if present.
"""
from __future__ import annotations
import json
import os
import urllib.error
import urllib.request
ZONE = "refining.dev"
DOMAIN = "dota2.refining.dev"
TARGET = "climperor-relations.pages.dev"
def cf(method: str, path: str, email: str, key: str, body: dict | None = None) -> dict:
url = "https://api.cloudflare.com/client/v4" + path
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(url, data=data, method=method, headers={
"X-Auth-Email": email, "X-Auth-Key": key, "Content-Type": "application/json",
})
try:
with urllib.request.urlopen(req) as r:
return json.loads(r.read().decode())
except urllib.error.HTTPError as e:
return json.loads(e.read().decode())
def main() -> None:
email = os.environ.get("CLOUDFLARE_EMAIL") or os.environ.get("KEYZOO_ASSET_META_USERNAME")
key = os.environ.get("CLOUDFLARE_API_KEY") or os.environ.get("KEYZOO_ASSET_SECRET_GLOBAL_API_KEY")
zd = cf("GET", f"/zones?name={ZONE}", email, key)
zr = zd.get("result") or []
if not zr:
raise SystemExit(f"zone {ZONE} not found")
zid = zr[0]["id"]
print(f"zone {ZONE}: {zid}")
recs = cf("GET", f"/zones/{zid}/dns_records?name={DOMAIN}", email, key)
existing = [r for r in (recs.get("result") or []) if r.get("type") == "CNAME"]
if existing:
for r in existing:
print(f"CNAME already exists: {r.get('name')} -> {r.get('content')} (proxied={r.get('proxied')})")
return
print(f"adding CNAME {DOMAIN} -> {TARGET} (proxied=true)")
d = cf("POST", f"/zones/{zid}/dns_records", email, key, body={
"type": "CNAME", "name": DOMAIN, "content": TARGET, "proxied": True, "comment": "climperor-relations Pages",
})
if d.get("success"):
r = d.get("result", {})
print(f"created: {r.get('type')} {r.get('name')} -> {r.get('content')} (proxied={r.get('proxied')})")
else:
print(f"FAILED: {d.get('errors')}")
if __name__ == "__main__":
main()