import sys import ipaddress from configparser import ConfigParser import json import copy import CloudFlare class DNSUpdater: def __init__(self, args): # Parse config config = ConfigParser() config.read('config.ini') self.HOSTNAME = config['server']['HOSTNAME'] __TOKEN = config['cloudflare']['TOKEN'] # Parse args try: ipversion = args[1].lstrip('-') ipaddress_new = args[2] except IndexError: ipaddress_new = '' ipversion = 'skip' match ipversion: case '4': self.IPVER = 'ipv4' case '6': self.IPVER = 'ipv6' case 'skip': self.IPVER = ipversion case other: raise ValueError(f"Wrong IP Address version given: {ipversion}") self.IPNEW = ipaddress_new # Cloudflare class self._cloudflare = CloudFlare.CloudFlare(token=__TOKEN) with open('cloudflare.json', 'r') as file: self.dns_replacements = json.load(file) def get_zones(self): # Cloudflare get zones from API token zones = self._cloudflare.zones.get() for zone in zones: self.zone_id = zone['id'] self.zone_name = zone['name'] print(f"Zone ID: {zone['id']} | Zone Name: {zone['name']}") def get_dns_records(self, log=False): dns_records_all = self._cloudflare.zones.dns_records.get(self.zone_id) dns_records_to_update = {'A' : [], 'AAAA' : []} for dnsrecord in dns_records_all: if dnsrecord['type'] in ['A', 'AAAA']: if log: print(f"DNS Name: {dnsrecord['name']} | Type : {dnsrecord['type']} | IP: {dnsrecord['content']}") dns_records_to_update[dnsrecord['type']].append(dnsrecord) else: if log: print(f"| Unknow DNS | Type: {dnsrecord['type']} | Zone: {dnsrecord['name']}") self.DNSRECORDS = copy.deepcopy(dns_records_to_update) def update_records(self): if self.IPVER == 'skip': self.get_dns_records(log=True) return self.get_dns_records() ipinformation = { 'ipv4': [ipaddress.IPv4Address, 'A'], 'ipv6': [ipaddress.IPv6Address, 'AAAA'] } print(f"Updating IP of version {self.IPVER}") assert isinstance(ipaddress.ip_address(self.IPNEW), ipinformation[self.IPVER][0]), f'IP {self.IPNEW} is not a valid IPv6 address' dnstype = ipinformation[self.IPVER][1] names_replace = self.dns_replacements[dnstype] print(names_replace) for name in names_replace: if (name == "@"): fullname = self.HOSTNAME else: fullname = f"{name}.{self.HOSTNAME}" for record in self.DNSRECORDS[dnstype]: if record['name'] == fullname: new_dnsrecord = {"name": fullname, "type": dnstype, "content": self.IPNEW} print(f"Sending request {new_dnsrecord}") res = self._cloudflare.zones.dns_records.patch(self.zone_id, record['id'], data=new_dnsrecord) if res['content'] != new_dnsrecord['content']: print(res) if __name__ == '__main__': dnsupdate = DNSUpdater(sys.argv) dnsupdate.get_zones() dnsupdate.update_records()