#!/usr/bin/env python3 """Update HS DNS settings behind Google WiFi systems.""" import argparse import json import urllib.request import urllib.parse import sys import dns.resolver WIFI_STATUS_URI = 'http://192.168.86.1/api/v1/status' def get_wan_ip(): with urllib.request.urlopen(WIFI_STATUS_URI) as req: data = req.read() status = json.loads(data) return status['wan']['localIpAddress'] def update_ip(hostname, password, ip=None): """Update HE DNS with new settings.""" params = { 'hostname': hostname, 'password': password, } if ip: params['myip'] = ip body = urllib.parse.urlencode(params).encode() url = 'https://dyn.dns.he.net/nic/update' req = urllib.request.Request(url, body) with urllib.request.urlopen(req) as response: return response.read() def get_parser(): """Get CLI parser.""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--hostname', required=True) parser.add_argument('-p', '--password', '--key', required=True) parser.add_argument('-a', '--address', '--ip') parser.add_argument('-q', '--quiet', action='store_true') return parser def main(argv): """The main entry point for scripts.""" parser = get_parser() opts = parser.parse_args(argv) if opts.quiet: p = lambda *args: None else: p = print curr_ip = get_wan_ip() p('Current IP', curr_ip) p('Looking up', opts.hostname, '...') answers = dns.resolver.resolve(opts.hostname, 'A') for msg in answers: p('Current DNS', msg.to_text()) if curr_ip != msg.to_text(): p('Updating IP') resp = update_ip(opts.hostname, opts.password, opts.address) p(resp) else: p('Up-to-date!') break if __name__ == '__main__': sys.exit(main(sys.argv[1:]))