A Python 3 script to update DNS on DigitalOcean. https://gitlab.no/rune/py-dyndns
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

py-dyndns.py 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #!/usr/bin/python3
  2. import urllib.request
  3. import configparser
  4. import json
  5. import logging
  6. import argparse
  7. import requests
  8. # Config stuff
  9. config = configparser.ConfigParser()
  10. config.read('config.ini')
  11. api = config['DYNDNS']['api_key']
  12. ip4 = config['DYNDNS']['ip4']
  13. ip6 = config['DYNDNS']['ip6']
  14. domain_name = config['DYNDNS']['baseuri']
  15. logging.basicConfig(filename=config['DYNDNS']['logfile'],level=logging.INFO)
  16. local_ip4 = urllib.request.urlopen("http://ip4.iurl.no").read().decode('utf-8')
  17. # The program
  18. def updateip(ip, domain):
  19. data = {'data': ip}
  20. headers = {'Authorization': 'Bearer ' + api, "Content-Type": "application/json"}
  21. response = requests.put('https://api.digitalocean.com/v2/domains/'+domain_name+'/records/' + domain, data=json.dumps(data), headers=headers)
  22. return str(response)
  23. def createnewdomain(name, ip):
  24. data = {'name': name[0],
  25. 'data': ip,
  26. 'type': "A",
  27. 'ttl': 3600
  28. }
  29. headers = {'Authorization': 'Bearer ' + api, "Content-Type": "application/json"}
  30. response = requests.post('https://api.digitalocean.com/v2/domains/' + domain_name + '/records',
  31. data=json.dumps(data), headers=headers)
  32. print(str(response))
  33. if str(response) == '<Response [201]>':
  34. return response.json()
  35. else:
  36. return 'Fail'
  37. def runupdate():
  38. for section in config.sections():
  39. if not config.has_option(section, 'subdomainid'):
  40. continue
  41. for name, value in config.items(section):
  42. req = urllib.request.Request('https://api.digitalocean.com/v2/domains/' + domain_name + '/records/' +
  43. value)
  44. req.add_header('Content-Type', 'application/json')
  45. req.add_header('Authorization', 'Bearer ' + api)
  46. current = urllib.request.urlopen(req)
  47. remote = current.read().decode('utf-8')
  48. remoteData = json.loads(remote)
  49. remoteIP4 = remoteData['domain_record']['data']
  50. if remoteIP4 != local_ip4:
  51. response = updateip(local_ip4, value)
  52. if '200' in response:
  53. logging.info('Success! Domain %s updated with IP: %s', section,remoteIP4)
  54. else:
  55. logging.error('Failure! '+response)
  56. else:
  57. logging.info('No need to update the IP! Local IP ('+local_ip4+') for '+section+' is the same as '
  58. 'Remote IP ('+remoteIP4+')')
  59. def listdomains():
  60. req = urllib.request.Request('https://api.digitalocean.com/v2/domains/' + domain_name + '/records/')
  61. req.add_header('Content-Type', 'application/json')
  62. req.add_header('Authorization', 'Bearer ' + api)
  63. current = urllib.request.urlopen(req)
  64. remote = current.read().decode('utf-8')
  65. remoteData = json.loads(remote)
  66. for k in remoteData["domain_records"]:
  67. print('Name : '+k['name']+' Id : '+str(k['id'])+' (IP: '+str(k['data'])+')')
  68. def listcurrent():
  69. for section in config.sections():
  70. if not config.has_option(section, 'subdomainid'):
  71. continue
  72. for name, value in config.items(section):
  73. req = urllib.request.Request('https://api.digitalocean.com/v2/domains/' + domain_name + '/records/' +
  74. value)
  75. req.add_header('Content-Type', 'application/json')
  76. req.add_header('Authorization', 'Bearer ' + api)
  77. current = urllib.request.urlopen(req)
  78. remote = current.read().decode('utf-8')
  79. remoteData = json.loads(remote)
  80. remoteIP4 = remoteData['domain_record']['data']
  81. print(section+' : '+remoteIP4)
  82. def addnewdomin(newdata):
  83. currentlocalip = urllib.request.urlopen("http://ip4.iurl.no").read().decode('utf-8')
  84. response = createnewdomain(newdata['add'][0], currentlocalip)
  85. if response is not 'Fail':
  86. logging.info('Success! Domain %s updated with ID: %s', newdata['add'][0], response['domain_record']['id'])
  87. domainid = str(response['domain_record']['id'])
  88. section = str(newdata['add'][0])
  89. section = section.strip("[']")
  90. config[section] = {
  91. 'subdomainid': str(domainid)
  92. }
  93. with open('config.ini', 'w') as f:
  94. config.write(f)
  95. print('Domain ' + str(section) + ' added with ID ' + str(domainid) + ' and config.ini updated!')
  96. else:
  97. print('ERROR! Domain not added!')
  98. # Commandline arguments
  99. parser = argparse.ArgumentParser(description='DigitalOcean Dynamic DNS')
  100. parser.add_argument('-l', '--list', help='List the available sub-domains on the domain supplied in the '
  101. 'config.ini file.', required=False, action="store_true")
  102. parser.add_argument('-c', '--current', help='List the current IP address for the sub-domains in the config.ini file',
  103. required=False, action="store_true")
  104. parser.add_argument('-a', '--add', help='Add a new domain to your DigitalOcean account and to the config.ini file',
  105. required=False, nargs=1, action='append')
  106. args = vars(parser.parse_args())
  107. if args['list']:
  108. listdomains()
  109. elif args['current']:
  110. listcurrent()
  111. elif args['add']:
  112. addnewdomin(args)
  113. else:
  114. runupdate()