from libcloud.dns.types import Provider, RecordType from libcloud.dns.providers import get_driver import requests import yaml import logging import argparse logger = logging.getLogger('dns') def update_or_create_record_for_zone(driver, zone, name, type, ip): for r in driver.iterate_records(zone): rname = "" if r.name is None else r.name # glitch with empty name if rname == name and r.type == type: if r.data == ip: logger.info( "Record ok: {}".format(r) ) return r logger.info( "Update {}".format(r) ) return driver.update_record( r, name=name, type=type, data=ip ) logger.info("Create {} {}".format(type, name)) return zone.create_record(name=name, type=type, data=ip) def run_config(config): cls = get_driver(Provider.AURORADNS) # logger.debug("Config {}".format(config)) ipv6 = requests.get('http://ip6only.me/api').text.split(',')[1] logger.info("IPv6: {}".format(ipv6)) ipv4 = requests.get('http://ip4.me/api').text.split(',')[1] logger.info("IPv4: {}".format(ipv4)) driver = cls(config['client_key'],config['client_secret']) for z in config['zones']: for name, records in z.items(): zone = driver.get_zone(name) logger.info("Zone: {} - {}".format(name, zone.id)) for record in records: logger.debug("Record: {}".format(record)) if record['type'] not in RecordType.__dict__: raise Exception("Invalid record type: {}".format(record['type'])) # Following assumption is not 100% valid, but works for me # adjust it if you need anything else. ip = ipv6 if record['type'] == RecordType.AAAA else ipv4 update_or_create_record_for_zone(driver, zone, record['name'], record['type'], ip) if __name__ == '__main__': argParser = argparse.ArgumentParser( description='Connect with PCExtreme Aurora DNS and set records from config based on current ip.') argParser.add_argument( '--config', '-c', required=True, type=str, help='The yaml config file to load' ) argParser.add_argument( '--verbose', '-v', action='store_true' ) argParser.add_argument( '--silent', '-s', action='store_true', help="Only log on warning (decreases verbosity). For use with cron." ) args = argParser.parse_args() logLevel = logging.DEBUG if args.verbose else (logging.WARNING if args.silent else logging.INFO) logging.basicConfig(level=logLevel) with open(args.config, 'r') as fp: config = yaml.load(fp) run_config(config)