43 lines
1.5 KiB
Python
Executable File
43 lines
1.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import argparse
|
|
import json
|
|
import subprocess
|
|
|
|
import CloudFlare
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description='Cloudflare DNS update script')
|
|
parser.add_argument('-k', '--api-token-file', help='Cloudflare API token file')
|
|
parser.add_argument('zone', help='Cloudflare Zone')
|
|
parser.add_argument('record', help='Cloudflare record name')
|
|
parser.add_argument('iface', help='Network interface to grab IP from')
|
|
args = parser.parse_args()
|
|
|
|
cf_token = None
|
|
if args.api_token_file:
|
|
with open(args.api_token_file) as f:
|
|
cf_token = f.readline().strip()
|
|
|
|
cf = CloudFlare.CloudFlare(token=cf_token)
|
|
zones = cf.zones.get(params={'name': args.zone})
|
|
assert zones, f'Zone {args.zone} not found'
|
|
records = cf.zones.dns_records.get(zones[0]['id'], params={'name': args.record})
|
|
assert records, f'Record {args.record} not found in zone {args.zone}'
|
|
|
|
|
|
ip_info = json.loads(subprocess.check_output(
|
|
['ip', '-j', 'addr', 'show', 'dev', args.iface], encoding='utf8'))
|
|
for a_info in ip_info[0]['addr_info']:
|
|
if a_info['family'] == 'inet' and a_info['scope'] == 'global':
|
|
address = a_info['local']
|
|
break
|
|
else:
|
|
assert False, f'No usable IP address found on interface {args.iface}'
|
|
|
|
print(f'Updating {args.record} -> {address}')
|
|
cf.zones.dns_records.patch(
|
|
zones[0]['id'], records[0]['id'],
|
|
data={'type': 'A', 'name': args.record, 'content': address})
|
|
|
|
if __name__ == '__main__':
|
|
main() |