#!/usr/bin/python import re import argparse from subprocess import Popen, PIPE import ipaddr def ipfamily_by_ip(ip): if isinstance(ip, ipaddr.IPv4Address): return 'A' elif isinstance(ip, ipaddr.IPv6Address): return 'AAAA' assert False def nsupdate_add(hostname, domain, ttl, ip): """ip_family: A or AAAA""" command = "update add {hostname}.{domain} {ttl} IN {ip_family} {ip}\n\n".format(hostname=hostname, domain=domain, ttl=ttl, ip_family=ipfamily_by_ip(ip), ip=ip) p = Popen(['nsupdate', '-l'], stdin=PIPE) p.communicate(command) def nsupdate_delete(hostname, domain, ip_family): """ip_family: A or AAAA""" command = "update delete {hostname}.{domain} {ip_family}\n\n".format(hostname=hostname, domain=domain, ip_family=ip_family) p = Popen(['nsupdate', '-l'], stdin=PIPE) p.communicate(command) def main(args): if args.delete: if args.ip is None: nsupdate_delete(args.hostname, args.domain, 'A') nsupdate_delete(args.hostname, args.domain, 'AAAA') else: nsupdate_delete(args.hostname, args.domain, ipfamily_by_ip(args.ip)) else: nsupdate_delete(args.hostname, args.domain, ipfamily_by_ip(args.ip)) nsupdate_add(args.hostname, args.domain, args.ttl, args.ip) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Add or delete a hostname from dyndns (simplifies call to nsupdate).') parser.add_argument('-d', '--delete', action='store_true', help='delete instead of add') parser.add_argument('-i', '--ip', help='IP address (either IPv4 or IPv6)') # parser.add_argument('-t', '--ttl', type=int, default=600, help='TTL (default: 600)') parser.add_argument('hostname', help='hostname to add or delete, e.g. myserver') args = parser.parse_args() args.domain = 'dyn.colgarra.priv.at' # <---- TODO args.ttl = 600 # <---- TODO # check ip if not args.delete and not args.ip: parser.error('The IP address is mandatory') if args.ip: try: args.ip = ipaddr.IPAddress(args.ip) # throws an exception if the IP address is not valid except ValueError: parser.error('The IP address is not valid') # check hostname if re.match(r'[-0-9a-z]+(\.[-0-9a-z]+)*$', args.hostname) is None: parser.error('The hostname has an invalid format.') main(args)