diff --git a/README.md b/README.md index db1e237..6d49f92 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +It bothered me that if I want to run this utility as a cron job every 5 minutes, I would be deleting my entry every 5 minutes. So I modified the code to first check if it even needs to do any updates before it goes and deletes the existing entry. +This fork also adds a "quiet" config option that if set to "true", will cause nothing to print unless something goes wrong. Useful for those not wanting to fill up a log/mail file that's capturing the prints from their cron jobs. Not the best way to do it as that "quiet" setting gets sent with all your API requests, but it doesn't seem to be affecting whether Porkbun accepts my API requests to have the extra field tacked on there. +--- +# README.MD from porkbundomains/porkbun-dynamic-dns-python:main +--- # porkbun-dynamic-dns-python [deprecated] Please note, this module is now in deprecated status. It is provided as-is as an example of how to use the Porkbun API manage DNS records, but is no longer maintained. Our unofficial recommendation would be to look into ddclient, which now supports calls to our API. diff --git a/config.json.example b/config.json.example index 2936205..08c501b 100644 --- a/config.json.example +++ b/config.json.example @@ -1,4 +1,5 @@ { "endpoint":"https://api-ipv4.porkbun.com/api/json/v3", "apikey": "", - "secretapikey": "" + "secretapikey": "", + "quiet": "false" } \ No newline at end of file diff --git a/porkbun-ddns.py b/porkbun-ddns.py index 90974d8..5fbd9cc 100755 --- a/porkbun-ddns.py +++ b/porkbun-ddns.py @@ -1,36 +1,43 @@ import json import requests -import re import sys +def printIfAllowed(content): #print the status of a json query if it is not a success or if quiet mode is not enabled + if ("error" in content.lower()) or canPrint: + print(content) + def getRecords(domain): #grab all the records so we know which ones to delete to make room for our record. Also checks to make sure we've got the right domain allRecords=json.loads(requests.post(apiConfig["endpoint"] + '/dns/retrieve/' + domain, data = json.dumps(apiConfig)).text) if allRecords["status"]=="ERROR": - print('Error getting domain. Check to make sure you specified the correct domain, and that API access has been switched on for this domain.'); - sys.exit(); + # No reason to feed into printIfAllowed, it will always print + print('Error getting domain. Check to make sure you specified the correct domain, and that API access has been switched on for this domain.') + sys.exit() return(allRecords) def getMyIP(): ping = json.loads(requests.post(apiConfig["endpoint"] + '/ping/', data = json.dumps(apiConfig)).text) return(ping["yourIp"]) -def deleteRecord(): +def replaceInvalidRecords(): for i in getRecords(rootDomain)["records"]: if i["name"]==fqdn and (i["type"] == 'A' or i["type"] == 'ALIAS' or i["type"] == 'CNAME'): - print("Deleting existing " + i["type"] + " Record") - deleteRecord = json.loads(requests.post(apiConfig["endpoint"] + '/dns/delete/' + rootDomain + '/' + i["id"], data = json.dumps(apiConfig)).text) + if myIP != i["content"]: + printIfAllowed("Deleting existing " + i["type"] + " Record") + printIfAllowed( "DELETE: " + (json.loads(requests.post(apiConfig["endpoint"] + '/dns/delete/' + rootDomain + '/' + i["id"], data = json.dumps(apiConfig)).text)["status"]) ) + printIfAllowed( "CREATE: " + (createRecord()["status"]) ) def createRecord(): createObj=apiConfig.copy() createObj.update({'name': subDomain, 'type': 'A', 'content': myIP, 'ttl': 300}) endpoint = apiConfig["endpoint"] + '/dns/create/' + rootDomain - print("Creating record: " + fqdn + " with answer of " + myIP) + printIfAllowed("Creating record: " + fqdn + " with answer of " + myIP) create = json.loads(requests.post(apiConfig["endpoint"] + '/dns/create/'+ rootDomain, data = json.dumps(createObj)).text) return(create) if len(sys.argv)>2: #at least the config and root domain is specified apiConfig = json.load(open(sys.argv[1])) #load the config file into a variable rootDomain=sys.argv[2].lower() + canPrint=not apiConfig["quiet"].lower=="true" if len(sys.argv)>3 and sys.argv[3]!='-i': #check if a subdomain was specified as the third argument subDomain=sys.argv[3].lower() @@ -46,8 +53,8 @@ if len(sys.argv)>2: #at least the config and root domain is specified else: myIP=getMyIP() #otherwise use the detected exterior IP address - deleteRecord() - print(createRecord()["status"]) + replaceInvalidRecords() else: + # No reason to feed into printIfAllowed, it will always print print("Porkbun Dynamic DNS client, Python Edition\n\nError: not enough arguments. Examples:\npython porkbun-ddns.py /path/to/config.json example.com\npython porkbun-ddns.py /path/to/config.json example.com www\npython porkbun-ddns.py /path/to/config.json example.com '*'\npython porkbun-ddns.py /path/to/config.json example.com -i 10.0.0.1\n") \ No newline at end of file