klankdns/klankdns.py

122 lines
3.8 KiB
Python
Raw Normal View History

2025-08-14 20:28:11 +02:00
#!/usr/bin/env python3
import re
import json
import urllib
import tomllib
import urllib.parse
import urllib.request
from pathlib import Path
#contents = urllib.request.urlopen("http://example.com/foo/bar").read()
# 5 curl -X POST -L https://api.porkbun.com/api/json/v3/dns/retrieveByNameType/klank.school/A/www --data '{"secretapikey":""}'
class API():
def __init__(self):
with (Path(__file__).parent / 'klankdns.secret.toml').open('rb') as f:
toml = tomllib.load(f)
self.key = toml['klankdns']['key']
self.secret = toml['klankdns']['secret']
self.base = toml['klankdns']['base']
self.entries = toml['klankdns']['entries']
self.public_ip = self.get_public_ip()
def get_public_ip(self):
req = urllib.request.Request("https://ipinfo.io/ip")
with urllib.request.urlopen(req) as response:
result = response.read().decode('utf-8')
if not re.match(r'[\d]+\.[\d]+\.[\d]+\.[\d]+', result):
raise Exception("ipinfo returned bullshit!!")
print(f"Got public IP: {result}")
return result
def post(self, url, data = None):
url = urllib.parse.urljoin(self.base, url)
fulldata = {
"secretapikey": self.secret,
"apikey": self.key,
**(data or {})
}
print(fulldata)
req = urllib.request.Request(url)
req.add_header('Content-Type', 'application/json')
try:
with urllib.request.urlopen(req, json.dumps(fulldata).encode('utf_8')) as response:
result = response.read().decode('utf-8')
except urllib.error.HTTPError as err:
print(err.read().decode('utf-8'))
raise err
return result
def get_by_name(self, name):
return self.post(urllib.parse.urljoin("dns/retrieveByNameType/", name))
def check(self):
for entry in self.entries:
result = self.get_by_name(entry)
print(f"{entry} : {result}")
def get_current_ip(self, entry):
return json.loads(self.get_by_name(entry))['records'][0]['content']
def update(self):
for entry in self.entries:
dat = json.loads(self.get_by_name(entry))
if dat["status"] != "SUCCESS":
raise Exception("???")
if len(dat["records"]) > 1:
raise Exception("???")
if len(dat["records"]) == 0:
print(f"Creating {entry}")
result = self.post(
# TODO this is spaghettt
f := urllib.parse.urljoin("dns/create/", entry.split('/')[0]),
{
"name": entry.split('/')[2],
"type": entry.split('/')[1],
"content": self.public_ip,
"ttl": "600"
}
)
print(f"{entry} : {result}")
if json.loads(result)["status"] != "SUCCESS":
raise Exception("???")
if len(dat["records"]) == 1:
if dat["records"][0]["content"] == self.public_ip:
print(f"Not updating {entry}")
else:
print(f"updating {entry}")
result = self.post(
f := urllib.parse.urljoin("dns/editByNameType/", entry),
{
"content": self.public_ip,
"ttl": 600,
}
)
print(f"{entry} : {result}")
if json.loads(result)["status"] != "SUCCESS":
raise Exception("???")
if __name__ == '__main__':
api = API()
api.update()
#api.check()