]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/commitdiff
unbound: Public static leases in DNS, too
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 11 Oct 2016 17:14:33 +0000 (19:14 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 11 Oct 2016 17:14:33 +0000 (19:14 +0200)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
config/unbound/unbound-dhcp-leases-bridge

index 862b5814f03f073c83178fb25f73192507a22477..91bdb4f362541d0c132a88391a1b09788807d36a 100644 (file)
@@ -64,8 +64,9 @@ def reverse_pointer_to_ip_address(rr):
        return ".".join(parts)
 
 class UnboundDHCPLeasesBridge(object):
-       def __init__(self, dhcp_leases_file, unbound_leases_file):
+       def __init__(self, dhcp_leases_file, fix_leases_file, unbound_leases_file):
                self.leases_file = dhcp_leases_file
+               self.fix_leases_file = fix_leases_file
 
                self.unbound = UnboundConfigWriter(unbound_leases_file)
                self.running = False
@@ -77,7 +78,7 @@ class UnboundDHCPLeasesBridge(object):
                # Initially read leases file
                self.update_dhcp_leases()
 
-               i = inotify.adapters.Inotify([self.leases_file])
+               i = inotify.adapters.Inotify([self.leases_file, self.fix_leases_file])
 
                for event in i.event_gen():
                        # End if we are requested to terminate
@@ -93,12 +94,21 @@ class UnboundDHCPLeasesBridge(object):
                        if "IN_MODIFY" in type_names:
                                self.update_dhcp_leases()
 
+                       # If the file is deleted, we re-add the watcher
+                       if "IN_IGNORED" in type_names:
+                               i.add_watch(watch_path)
+
                log.info("Unbound DHCP Leases Bridge terminated")
 
        def update_dhcp_leases(self):
-               log.info("Reading DHCP leases from %s" % self.leases_file)
+               leases = []
+
+               for lease in DHCPLeases(self.leases_file):
+                       leases.append(lease)
+
+               for lease in FixLeases(self.fix_leases_file):
+                       leases.append(lease)
 
-               leases = DHCPLeases(self.leases_file)
                self.unbound.update_dhcp_leases(leases)
 
        def terminate(self):
@@ -117,6 +127,8 @@ class DHCPLeases(object):
                return iter(self._leases)
 
        def _parse(self):
+               log.info("Reading DHCP leases from %s" % self.path)
+
                leases = []
 
                with open(self.path) as f:
@@ -179,6 +191,58 @@ class DHCPLeases(object):
                return properties
 
 
+class FixLeases(object):
+       cache = {}
+
+       def __init__(self, path):
+               self.path = path
+
+               self._leases = self.cache[self.path] = self._parse()
+
+       def __iter__(self):
+               return iter(self._leases)
+
+       def _parse(self):
+               log.info("Reading fix leases from %s" % self.path)
+
+               leases = []
+               now = datetime.datetime.utcnow()
+
+               with open(self.path) as f:
+                       for line in f.readlines():
+                               line = line.rstrip()
+
+                               try:
+                                       hwaddr, ipaddr, enabled, a, b, c, hostname = line.split(",")
+                               except ValueError:
+                                       log.warning("Could not parse line: %s" % line)
+                                       continue
+
+                               # Skip any disabled leases
+                               if not enabled == "on":
+                                       continue
+
+                               l = Lease(ipaddr, {
+                                       "binding"         : "state active",
+                                       "client-hostname" : hostname,
+                                       "hardware"        : "ethernet %s" % hwaddr,
+                                       "starts"          : now.strftime("%w %Y/%m/%d %H:%M:%S"),
+                                       "ends"            : "never",
+                               })
+                               leases.append(l)
+
+               # Try finding any deleted leases
+               for lease in self.cache.get(self.path, []):
+                       if lease in leases:
+                               continue
+
+                       # Free the deleted lease
+                       lease.free()
+                       leases.append(lease)
+
+               return leases
+
+
 class Lease(object):
        def __init__(self, ipaddr, properties):
                self.ipaddr = ipaddr
@@ -208,6 +272,11 @@ class Lease(object):
                        state = state.split(" ", 1)
                        return state[1]
 
+       def free(self):
+               self._properties.update({
+                       "binding" : "state free",
+               })
+
        @property
        def active(self):
                return self.binding_state == "active"
@@ -430,6 +499,8 @@ if __name__ == "__main__":
                metavar="PATH", help="Path to the DHCPd leases file")
        parser.add_argument("--unbound-leases", default="/etc/unbound/dhcp-leases.conf",
                metavar="PATH", help="Path to the unbound configuration file")
+       parser.add_argument("--fix-leases", default="/var/ipfire/dhcp/fixleases",
+               metavar="PATH", help="Path to the fix leases file")
 
        # Parse command line arguments
        args = parser.parse_args()
@@ -444,7 +515,7 @@ if __name__ == "__main__":
 
        setup_logging(loglevel)
 
-       bridge = UnboundDHCPLeasesBridge(args.dhcp_leases, args.unbound_leases)
+       bridge = UnboundDHCPLeasesBridge(args.dhcp_leases, args.fix_leases, args.unbound_leases)
 
        ctx = daemon.DaemonContext(detach_process=args.daemon)
        ctx.signal_map = {