import configparser import os import sys import xml.etree.ElementTree as ET from requests import get BASE_URL = 'https://www.namesilo.com/api' UPDATE_URL = '{base}/dnsUpdateRecord?version=1&type=xml&key={key}' \ '&domain={domain}&rrid={rrid}&' \ 'rrhost={host}&rrvalue={new_value}&rrttl=7207' LIST_URL = '{base}/dnsListRecords?version=1&type=xml&key={key}&domain={domain}' EVERYDAY_IP_SERVICE = 'https://tool.everyday.in.th/ip?format=text' '''Updater procedure 1. Getch a new public IP 2. Get a namesilo's DNS 3. check if 1 & 2 are different, then Update ''' def get_public_ip(): '''Get current public IP return IP or None ''' res = get(EVERYDAY_IP_SERVICE) if res.status_code != 200: return None ip = res.text.strip().replace('::ffff:', '') return ip def get_namesilo_dns(key, domain, target_host): res = get(LIST_URL.format(base=BASE_URL, key=key, domain=domain)) if res.status_code != 200: return None tree = ET.fromstring(res.text.strip()) for i in tree.iter('resource_record'): host = i.find('./host').text if host == target_host: return { 'rrid': i.find('./record_id').text, 'value': i.find('./value').text, 'host': host, } break return {} def update_namesilo_data(key, domain, rrid, subdomain, new_value): res = get(UPDATE_URL.format( base=BASE_URL, key=key, domain=domain, rrid=rrid, host=subdomain, new_value=new_value)) if res.status_code != 200: return None return True def main(): config = configparser.ConfigParser() config.read('settings.conf') domain = config['default']['domain'] subdomain = config['default']['subdomain'] api_key = os.environ.get('NAMESILO_API', None) if not api_key: if 'namesilo_api' not in config['default']: print('NAMESILO_API not found.') sys.exit() api_key = config['default']['namesilo_api'] print('KEY: {}...'.format(api_key[:3])) target = '{}.{}'.format(subdomain, domain) print('TARGET: {}'.format(target)) public_ip = get_public_ip() print('PUBLIC IP: {}..'.format(public_ip[:-5])) namesilo_data = get_namesilo_dns(api_key, domain, target) if not namesilo_data: print('NAMESILO API service is down or target not found') sys.exit() curr_ip = namesilo_data['value'] if curr_ip == public_ip: print('Current value is okay. No need to do anything') sys.exit() rrid = namesilo_data['rrid'] result = update_namesilo_data(api_key, domain, rrid, subdomain, public_ip) if not result: print('Updating process failed.') sys.exit() print('Updated to a new IP: {} from {}'.format(public_ip, curr_ip)) if __name__ == '__main__': main()