Add address change logging to ddns script

This commit is contained in:
Thomas Kleinendorst 2024-04-10 18:33:26 +02:00
parent d1cf27d277
commit 6409f8c31c
3 changed files with 32 additions and 37 deletions

View file

@ -24,7 +24,11 @@ def get_public_IP():
def resolve_name(domain):
logging.info(f'Resolving {domain}...')
result = dns.resolver.resolve(domain, 'A')
try:
result = dns.resolver.resolve(domain, 'A')
except dns.resolver.NXDOMAIN:
logging.error(f'No DNS record exists for {domain}, configure it first before using this ddns script. Exiting...')
exit(1)
resolved_address = result[0].address
logging.info(f'Resolved {domain} to: {resolved_address}.')
@ -32,26 +36,26 @@ def resolve_name(domain):
def get_zone_id(domain):
response = requests.get(f'https://api.cloudflare.com/client/v4/zones?name={domain}', headers=cloudflare_request_headers)
if response.status_code != 200:
raise Exception('Something went wrong requesting the zone of the domain on Cloudflare...')
zone_id = response.json()['result'][0]['id']
return zone_id
def get_record_id(zoneId, record):
logging.debug('Getting record id...')
response = requests.get(f'https://api.cloudflare.com/client/v4/zones/{zoneId}/dns_records?name={record}', headers=cloudflare_request_headers)
if response.status_code != 200:
raise Exception('Something went wrong requesting the record id of the domain name on Cloudflare...')
return response.json()['result'][0]['id']
def change_record(subdomain, zoneId, recordId):
logging.info(f'Changing record for {subdomain} to point to {publicIP}...')
dns_change_response = requests.put(f'https://api.cloudflare.com/client/v4/zones/{zoneId}/dns_records/{recordId}',
dns_change_response = requests.put(f'https://api.cloudflare.com/client/v4/zones/{zoneId}/dns_records/{recordId}',
headers=cloudflare_request_headers,
json={
'content': publicIP,
@ -64,33 +68,43 @@ def change_record(subdomain, zoneId, recordId):
if dns_change_response.status_code != 200:
raise Exception('Something went wrong updating the dns record...')
logging.info('Succesfully updated the record ✅!')
parser = argparse.ArgumentParser()
parser.add_argument('subdomain')
parser.add_argument('-c', '--credential-file', dest='token')
parser.add_argument('-c', '--config-file', dest='config')
args = parser.parse_args()
subdomain = args.subdomain
cloudflare_token_path = args.token
config_file_path = args.config
fixedTopLevelDomain = 'kleinendorst.info'
fullDomainName = f'{subdomain}.{fixedTopLevelDomain}'
publicIP = get_public_IP()
if resolve_name(fullDomainName) == publicIP:
logging.info(f'Currently resolved name already matches the public ip ({publicIP}), exiting...')
exit(0)
config = configparser.ConfigParser()
config.read(cloudflare_token_path)
config.read(config_file_path)
cloudflare_api_credentials = config['credentials']['dns_cloudflare_token']
cloudflare_request_headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {cloudflare_api_credentials}'}
log_path = config.get('log_changes', 'log_path', fallback=None)
if log_path is not None:
log_path = config['log_changes']['log_path']
logging.info(f'Logging DNS name changes to {log_path} on IP updates.')
resolvedIP = resolve_name(fullDomainName)
publicIP = get_public_IP()
if resolvedIP == publicIP:
logging.info(f'Currently resolved name already matches the public ip ({publicIP}), exiting...')
exit(0)
zoneId = get_zone_id(fixedTopLevelDomain)
recordId = get_record_id(zoneId, fullDomainName)
change_record(subdomain, zoneId, recordId)
with open(log_path, 'a+') as log_file:
msg = f'Address for FQDN {fullDomainName} altered from: {resolvedIP} - {publicIP}.'
logging.info(f'Writing: "{msg}" to log file at {log_path}...')
log_file.write(msg + '\n')