#!/usr/bin/env python3
#
# Simple script to renew local DDNS record for reservation defined hostnames
#
# Copyright (C) 2020 FUSS Project <info@fuss.bz.it>
# Author: Simone Piccardi <piccardi@truelite.it>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

import re, netaddr
import dns.resolver, dns.tsigkeyring, dns.update, dns.query


DDNS_CONF_FILE = '/etc/bind/named.conf.local'
STATIC_LEASE_FILE = '/etc/dhcp/dhcp-reservations'

## getting settings by DNS configuration
# get file with the key for DDNS
data=open(DDNS_CONF_FILE).read()
regexp=r'^include "(.*key)";'
reg=re.compile(regexp,re.M|re.S)
keyfile=open(reg.findall(data)[0]).read()
# direct zone
regexp=r'^zone "([a-z0-9.]+)"'
reg=re.compile(regexp,re.M)
zone=reg.findall(data)[0]
# reverse zone
regexp=r'^zone "([0-9.]+in-addr.arpa)"'
reg=re.compile(regexp,re.M)
reverse=reg.findall(data)[0]
# get key data from key file
regexp=r'^key "([^"]+)"\s+{.+secret\s+([^ ;]+);'
reg=re.compile(regexp,re.M|re.S)
keydata=reg.findall(keyfile)
key = { keydata[0][0]: keydata[0][1] }
keyring=dns.tsigkeyring.from_text(key)

## getting static reservations data
raw_data = open(STATIC_LEASE_FILE).readlines()
data = "".join([x for x in raw_data if not x.startswith("#")])
for d in data.split("host"):
    d = d.strip()
    if d:
        item = dict()
        hostname, content = d.split("{")
        lines = content.split(";")
        item['hostname'] = hostname.strip()
        for line in lines:
            if "hardware ethernet" in line:
                item['mac'] = line.split(" ")[-1].strip()
            if "fixed-address" in line:
                item['address'] = line.split(" ")[-1].strip()

        print(item)

        update=dns.update.Update(zone,keyring=keyring)
        update.add(item['hostname'], 604800, 'A',item['address'])
        dns.query.tcp(update,'127.0.0.1')
        update=dns.update.Update(reverse,keyring=keyring)
        update.add(netaddr.IPAddress(item['address']).reverse_dns,
                   604800, 'PTR', item['hostname']+"."+zone+".")
        dns.query.tcp(update,'127.0.0.1')
        
