working ddns updater
parent
d8fea630f3
commit
afea3d0c05
135
main.py
135
main.py
|
@ -6,6 +6,14 @@ import sched
|
|||
from pathlib import Path
|
||||
|
||||
|
||||
def make_headers(key: str):
|
||||
headers = {
|
||||
"Authorization": f"Bearer {key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
return headers
|
||||
|
||||
|
||||
class Env:
|
||||
def __init__(self, username, api_key):
|
||||
self.username = username
|
||||
|
@ -13,17 +21,71 @@ class Env:
|
|||
|
||||
|
||||
class Zone:
|
||||
def __init__(self, zone_name, env, records):
|
||||
self.zone_name = zone_name
|
||||
def __init__(self, env, records):
|
||||
self.env = env
|
||||
self.records = records
|
||||
self.zone_id = None
|
||||
self.zone_name = None
|
||||
|
||||
def fetch_zone_id(self):
|
||||
if self.zone_name is None:
|
||||
print("Zone name is none! Must set at least zone name or zone id!")
|
||||
exit(1)
|
||||
|
||||
r = requests.get(f"https://api.cloudflare.com/client/v4/zones", headers=make_headers(self.env.api_key))
|
||||
if r.status_code == 200:
|
||||
data = json.loads(r.text)
|
||||
results = data["result"]
|
||||
for result in results:
|
||||
if result["name"] == self.zone_name:
|
||||
self.zone_id = result["id"]
|
||||
return
|
||||
print("Failed to find zone id, does this zone exist?")
|
||||
return
|
||||
print(f"Error has occurred, status code: {r.status_code}")
|
||||
print(r.text)
|
||||
|
||||
def update_record(self, address, record):
|
||||
print(f"record {record['name']} has address {record['content']} but requires updating!")
|
||||
r = requests.patch(f"https://api.cloudflare.com/client/v4/zones/{self.zone_id}/dns_records/{record['id']}",
|
||||
headers=make_headers(self.env.api_key), data=json.dumps({
|
||||
"content": address,
|
||||
"name": record['name'],
|
||||
"type": record['type'],
|
||||
"comment": record['comment'],
|
||||
"ttl": record['ttl'],
|
||||
"tags": record['tags'],
|
||||
"proxied": record['proxied']
|
||||
}))
|
||||
if r.status_code:
|
||||
print(f"record {record['name']} has been updated to {address}")
|
||||
else:
|
||||
print(f"Failed to update record {record['name']}")
|
||||
print(r.text)
|
||||
|
||||
def update_records(self, address):
|
||||
r = requests.get(f"https://api.cloudflare.com/client/v4/zones/{self.zone_id}/dns_records?type=A",
|
||||
headers=make_headers(self.env.api_key))
|
||||
if r.status_code != 200:
|
||||
return None
|
||||
record_data = json.loads(r.text)["result"]
|
||||
for record in record_data:
|
||||
if record["name"] not in self.records:
|
||||
continue
|
||||
if record["content"] == address:
|
||||
continue
|
||||
self.update_record(address, record)
|
||||
|
||||
|
||||
class Zones:
|
||||
def __init__(self, ip_provider, r_zones):
|
||||
def __init__(self, ip_provider, zones):
|
||||
self.ip_provider = ip_provider
|
||||
self.zones = r_zones
|
||||
self.zones = zones
|
||||
|
||||
def fetch_ip(self):
|
||||
r = requests.get(self.ip_provider)
|
||||
print(f"Fetching IP Address with '{self.ip_provider}' returned '{r.text}'")
|
||||
return r.text
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
|
@ -52,9 +114,14 @@ def get_conf(conf_path, envs):
|
|||
zones = []
|
||||
for zone in json_env["zones"]:
|
||||
sites = []
|
||||
for site in zone["sites"]:
|
||||
for site in zone["records"]:
|
||||
sites.append(site)
|
||||
zones.append(Zone(zone["zone"], envs[zone["username"]], sites))
|
||||
zn = Zone(envs[zone["username"]], sites)
|
||||
if "zone" in zone:
|
||||
zn.zone_name = zone["zone"]
|
||||
if "id" in zone:
|
||||
zn.zone_id = zone["id"]
|
||||
zones.append(zn)
|
||||
return Zones(json_env["ip_provider"], zones)
|
||||
|
||||
|
||||
|
@ -96,51 +163,29 @@ def run_install():
|
|||
print(f"Warning {sites_path} already exists, skipping!")
|
||||
|
||||
|
||||
def fetch_ip(provider):
|
||||
print(f"Fetching IP Address with '{provider}'")
|
||||
r = requests.get(provider)
|
||||
return r.text
|
||||
def run(scheduler, args, zones):
|
||||
scheduler.enter(args.time, 1, run, (scheduler, args, zones))
|
||||
address = zones.fetch_ip()
|
||||
|
||||
|
||||
def fetch_zone_id(zone_name, key):
|
||||
headers = {
|
||||
"Authorization": f"Bearer {key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
r = requests.get(f"https://api.cloudflare.com/client/v4/zones", headers=headers)
|
||||
if r.status_code == 200:
|
||||
data = json.loads(r.text)
|
||||
results = data["result"]
|
||||
for result in results:
|
||||
if result["name"] == zone_name:
|
||||
return result["id"]
|
||||
print("Failed to find zone id, does this zone exist?")
|
||||
return None
|
||||
print(f"Error has occurred, status code: {r.status_code}")
|
||||
print(r.text)
|
||||
return None
|
||||
|
||||
|
||||
def run(scheduler, r_args, r_envs, r_zones):
|
||||
scheduler.enter(r_args.time, 1, run, (scheduler, r_args, r_envs, r_zones))
|
||||
address = fetch_ip(r_zones.ip_provider)
|
||||
|
||||
for zone in r_zones.zones:
|
||||
user = zone.env
|
||||
for zone in zones.zones:
|
||||
if zone.zone_id is None:
|
||||
zone.zone_id = fetch_zone_id(zone.zone_name, user.api_key)
|
||||
zone.fetch_zone_id()
|
||||
print(f"Fetched zone {zone.zone_name} with id {zone.zone_id}")
|
||||
zone.update_records(address)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def main():
|
||||
args = parse_arguments()
|
||||
|
||||
if args.install:
|
||||
run_install()
|
||||
else:
|
||||
m_user_envs = get_env(args.env)
|
||||
m_zones = get_conf(args.config, m_user_envs)
|
||||
for v_zone in m_zones.zones:
|
||||
print(fetch_zone_id(v_zone.zone_name, v_zone.env.api_key))
|
||||
#runner = sched.scheduler(time.time, time.sleep)
|
||||
#runner.enter(args.time, 1, run, (runner, args, user_envs, zones))
|
||||
#runner.run()
|
||||
user_envs = get_env(args.env)
|
||||
zones = get_conf(args.config, user_envs)
|
||||
runner = sched.scheduler(time.time, time.sleep)
|
||||
run(runner, args, zones)
|
||||
runner.run()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
Loading…
Reference in New Issue