Application to use your DigitalOcean account/service as a dynamic DNS service. https://gitlab.no/rune/DO_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.

78 lines
3.0 KiB

  1. #!/usr/bin/python3
  2. #################################
  3. # @author Rune Olsen #
  4. # @license GPL v3 #
  5. # #
  6. #################################
  7. import sys
  8. import urllib.request
  9. import configparser
  10. import json
  11. import logging
  12. import argparse
  13. import requests
  14. import os
  15. import time
  16. # Config stuff
  17. linuxfilepath = '~/.config/dyndns/'
  18. filepath = os.path.expanduser(linuxfilepath)
  19. config = configparser.ConfigParser()
  20. local_ip4 = urllib.request.urlopen("http://ip4.iurl.no").read().decode('utf-8')
  21. try:
  22. config.read(filepath + 'config.ini')
  23. api = config['DYNDNS']['api_key']
  24. domain_name = config['DYNDNS']['baseuri']
  25. if not os.path.exists(filepath + config['DYNDNS']['logfile']):
  26. open(filepath + config['DYNDNS']['logfile'], 'a').close()
  27. logging.basicConfig(filename=filepath + config['DYNDNS']['logfile'], level=logging.INFO)
  28. except KeyError:
  29. logging.basicConfig(filename=filepath + 'dyndns.log', level=logging.INFO)
  30. logging.error(time.strftime("%Y-%m-%d %H:%M") + ' Missing config.ini in ' + filepath)
  31. print('Woops!\n\nMissing config.ini file!\n\nPlease execute the main \'dyndns\' application to create '
  32. 'the default config.ini file, then edit this file before starting the application again!')
  33. sys.exit()
  34. # The program
  35. def update_ip(ip, domain):
  36. data = {'data': ip}
  37. headers = {'Authorization': 'Bearer ' + api, "Content-Type": "application/json"}
  38. response = requests.put('https://api.digitalocean.com/v2/domains/' + domain_name + '/records/' + domain,
  39. data=json.dumps(data), headers=headers)
  40. return str(response)
  41. def run_update():
  42. for section in config.sections():
  43. if not config.has_option(section, 'subdomainid'):
  44. continue
  45. for name, value in config.items(section):
  46. req = urllib.request.Request('https://api.digitalocean.com/v2/domains/' + domain_name + '/records/' +
  47. value)
  48. req.add_header('Content-Type', 'application/json')
  49. req.add_header('Authorization', 'Bearer ' + api)
  50. current = urllib.request.urlopen(req)
  51. remote = current.read().decode('utf-8')
  52. remoteData = json.loads(remote)
  53. remoteIP4 = remoteData['domain_record']['data']
  54. if remoteIP4 != local_ip4:
  55. response = update_ip(local_ip4, value)
  56. if '200' in response:
  57. logging.info(time.strftime("%Y-%m-%d %H:%M") +
  58. ' - Success! Domain %s updated with IP: %s (old IP: %s)', section, local_ip4,
  59. remoteIP4)
  60. else:
  61. logging.error('Failure! ' + response)
  62. else:
  63. logging.info(time.strftime("%Y-%m-%d %H:%M") + ' - No need to update the IP! Local IP ('
  64. + local_ip4 + ') for ' + section + ' is the same as Remote IP (' + remoteIP4 + ')')
  65. run_update()