Skip to content

Instantly share code, notes, and snippets.

@robweber
Last active January 13, 2024 13:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robweber/3e83c29b38a60bf896e20d2924e424f7 to your computer and use it in GitHub Desktop.
Save robweber/3e83c29b38a60bf896e20d2924e424f7 to your computer and use it in GitHub Desktop.
Use the GoDaddy API to update a DNS record when external IP changes
"""update_godaddy_dns.py
Updates a GoDaddy DNS record with a new external IP address using the GoDaddy API
Run in debug mode (-D) to check the IP but not update DNS records
https://developer.godaddy.com/doc/endpoint/domains
Requires:
configargparse
requests
"""
import configargparse
import json
import requests
import sys
class GoDaddyRecord:
"""
Represents a single GoDaddy DNS record
Includes functions to both retrieve and update the record's data
"""
GODADDY_API = "https://api.godaddy.com/v1/domains"
key = None
secret = None
url = None
def __init__(self, key, secret, domain, type, name):
self.key = key
self.secret = secret
self.url = f"{self.GODADDY_API}/{domain}/records/{type}/{name}"
def __generate_headers(self):
return {"Authorization": f"sso-key {self.key}:{self.secret}",
"Content-type": "application/json"}
def get_record(self):
"""
Get the DNS record listed from GoDaddy
https://developer.godaddy.com/doc/endpoint/domains#/v1/recordGet
:returns: The current data value of this record as a string
"""
response = requests.get(self.url, headers=self.__generate_headers())
if(response.status_code == 200):
result = response.json()
if('data' not in result[0]):
# the request was not successful
raise Exception(f"{result['message']}")
else:
raise Exception("Error contacting api.godaddy.com")
return result[0]['data']
def update_record(self, updated_data, ttl=3600):
"""
Update the DNS record listed with GoDaddy
https://developer.godaddy.com/doc/endpoint/domains#/v1/recordReplaceTypeName
:param updated_data: new data record
:param ttl: the time to live, default is 3600
"""
response = requests.put(self.url, data=json.dumps([{"data": updated_data, "ttl": ttl}]),
headers=self.__generate_headers())
if(response.status_code != 200):
raise Exception(f"Error updating record {response.json()}")
def get_external_ip():
"""
try and get the external IP from ipify.org
raise an error if no response found
:returns: the external IP as a string
"""
result = None
response = requests.get('https://api.ipify.org?format=json')
if(response.status_code == 200):
result = response.json()
else:
raise Exception("Ipify not available")
return result['ip']
def main():
# create the godaddy api object
record = GoDaddyRecord(args.key, args.secret, args.domain, args.type, args.name)
# get the current external ip and the godaddy record ip
current_ip = get_external_ip()
godaddy_ip = record.get_record()
print(f"Current IP: {current_ip}")
print(f"GoDaddy IP: {godaddy_ip}")
if(current_ip != godaddy_ip):
if(not args.debug):
print("Data does not match, updating DNS")
record.update_record(current_ip)
else:
# exit with a warning state
sys.exit(2)
parser = configargparse.ArgumentParser(description='GoDaddy DNS Update')
parser.add_argument('-c', '--config', is_config_file=True,
help="Path to the config file, notifications will be sent if given")
parser.add_argument('-k', '--key', required=True, type=str,
help="GoDaddy API Key")
parser.add_argument('-s', '--secret', required=True, type=str,
help="GoDaddy API Secret")
parser.add_argument('-d', '--domain', required=True, type=str,
help="The domain to update")
parser.add_argument('-t', '--type', default='A', type=str,
help="The DNS record type to update, %(default)s is the default type")
parser.add_argument('-N', '--name', default="@", type=str,
help="The name of the DNS record, %(default)s is the default")
parser.add_argument('-D', '--debug', action='store_true',
help="Run the script in debug mode, prevents updating of record")
args = parser.parse_args()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment