From 26fcc3859fc753138058e37067347a176b342bcf Mon Sep 17 00:00:00 2001 From: Firq Date: Sun, 27 Nov 2022 18:59:47 +0100 Subject: [PATCH 1/2] Wrote new version of script, please test before merging --- .gitignore | 4 +- cloudflare-dns-new.py | 96 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 cloudflare-dns-new.py diff --git a/.gitignore b/.gitignore index 8f38060..2388456 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ - +# Default ignores venv/ +.idea/ +.vscode/ diff --git a/cloudflare-dns-new.py b/cloudflare-dns-new.py new file mode 100644 index 0000000..c2e0b93 --- /dev/null +++ b/cloudflare-dns-new.py @@ -0,0 +1,96 @@ +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 = self._cloudflare.zones.dns_records.get(self.zone_id) + + dns_names = {'A' : [], 'AAAA' : []} + for dnsrecord in dns_records: + if log: + print(f"DNS Name: {dnsrecord['name']} | ID: {dnsrecord['id']} | Type : {dnsrecord['type']} | IP: {dnsrecord['content']}") + dns_names[dnsrecord['type']].append(dnsrecord["name"]) + + self.DNSNAMES = copy.deepcopy(dns_names) + + 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: + fullname = f"{name}.{self.HOSTNAME}" + print(fullname) + + for x in self.DNSNAMES: + if x['name'] == fullname: + dns_record_id = x['id'] + print(dns_record_id) + + if fullname in self.DNSNAMES[dnstype]: + new_dnsrecord = {"name": fullname, "type": "AAAA", "content": self.IPNEW} + print(f"Sending request {new_dnsrecord}") + r = self._cloudflare.zones.dns_records.patch(self.zone_id, dns_record_id, data=new_dnsrecord) + print(r) + + +if __name__ == '__main__': + dnsupdate = DNSUpdater(sys.argv) + dnsupdate.get_zones() + dnsupdate.update_records() \ No newline at end of file From 27bb82767bfb19c76178711412c43568ec2175c3 Mon Sep 17 00:00:00 2001 From: Neshura Date: Mon, 28 Nov 2022 20:25:42 +0100 Subject: [PATCH 2/2] Various bugfixes and changes 1: Script had AAAA hardcoded, this would've changed all records to AAAA. 2: Script was not saving the DNS Records ids, only their names this would've made it impossible to actually edit the DNS Record 3: Lowered the amount of printing going on, removed irrelevant information such as zoneid from the print statements, also removed most printing during the update phase --- cloudflare-dns-new.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/cloudflare-dns-new.py b/cloudflare-dns-new.py index c2e0b93..46da1cc 100644 --- a/cloudflare-dns-new.py +++ b/cloudflare-dns-new.py @@ -46,15 +46,19 @@ class DNSUpdater: print(f"Zone ID: {zone['id']} | Zone Name: {zone['name']}") def get_dns_records(self, log=False): - dns_records = self._cloudflare.zones.dns_records.get(self.zone_id) + dns_records_all = self._cloudflare.zones.dns_records.get(self.zone_id) - dns_names = {'A' : [], 'AAAA' : []} - for dnsrecord in dns_records: - if log: - print(f"DNS Name: {dnsrecord['name']} | ID: {dnsrecord['id']} | Type : {dnsrecord['type']} | IP: {dnsrecord['content']}") - dns_names[dnsrecord['type']].append(dnsrecord["name"]) + 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.DNSNAMES = copy.deepcopy(dns_names) + self.DNSRECORDS = copy.deepcopy(dns_records_to_update) def update_records(self): if self.IPVER == 'skip': @@ -76,18 +80,15 @@ class DNSUpdater: print(names_replace) for name in names_replace: fullname = f"{name}.{self.HOSTNAME}" - print(fullname) - for x in self.DNSNAMES: - if x['name'] == fullname: - dns_record_id = x['id'] - print(dns_record_id) - - if fullname in self.DNSNAMES[dnstype]: - new_dnsrecord = {"name": fullname, "type": "AAAA", "content": self.IPNEW} - print(f"Sending request {new_dnsrecord}") - r = self._cloudflare.zones.dns_records.patch(self.zone_id, dns_record_id, data=new_dnsrecord) - print(r) + 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__':