90 lines
2.4 KiB
Python
90 lines
2.4 KiB
Python
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)
|
|
|
|
|
|
|