|
|
|
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
|
|
|
|
return res.text.strip()
|
|
|
|
|
|
|
|
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('./host').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():
|
|
|
|
api_key = os.environ['NAMESILO_API']
|
|
|
|
if not api_key:
|
|
|
|
print('NAMESILO_API in env is not found.')
|
|
|
|
sys.exit()
|
|
|
|
print('KEY: {}...'.format(api_key[:3]))
|
|
|
|
config = configparser.ConfigParser()
|
|
|
|
config.read('settings.conf')
|
|
|
|
domain = config['default']['domain']
|
|
|
|
subdomain = config['default']['subdomain']
|
|
|
|
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()
|
|
|
|
|
|
|
|
if namesilo_data['value'] == 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: {}'.format(public_ip))
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|