Index: nodes/fresh-dns.sh
===================================================================
--- nodes/fresh-dns.sh	(revision 8598)
+++ nodes/fresh-dns.sh	(revision 8598)
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# Deploy fresh/changed WL autogenerated DNS zones
+#
+CONFIGROOT='/usr/home/rvdzwet/genesis/nodes'
+DEPLOYROOT='/etc/namedb/master'
+
+TFILE=`mktemp /tmp/$(basename $0).XXXXX`
+trap "rm $TFILE; exit 1" 1 2 3 15
+
+# Generate new DNS and only complain/die on errors
+(
+  svn up $CONFIGROOT $CONFIGROOT/../dns || exit 1
+  $CONFIGROOT/genesis-to-yaml.pl $CONFIGROOT/*/wleiden.conf || exit 1
+  $CONFIGROOT/gformat.py dns || exit 1
+) 2>&1 > $TFILE || { cat $TFILE; exit 1; }
+
+
+UPDATE_ZONES=""
+# Check all zone files for updates
+for NEW in $CONFIGROOT/dns/*; do
+  ZONE=`basename $NEW | cut -c 4-`  
+  OLD=$DEPLOYROOT/`basename $NEW`
+
+  # Contains new data?
+  diff -I 'SOA' $OLD $NEW
+  if [ $? -eq 0 ]; then
+    continue
+  fi
+
+  # Syntax valid?
+  named-checkzone $ZONE $NEW
+  if [ $? -ne 0 ] ; then
+    continue
+  fi
+
+  # Deploy
+  cp $NEW $OLD
+  UPDATE_ZONES="$UPDATE_ZONES $ZONE"
+done
+
+# Make sure to reload if updates are executed
+if [ -n "$UPDATE_ZONES" ]; then
+  rndc reload
+fi
Index: nodes/gformat.py
===================================================================
--- nodes/gformat.py	(revision 8597)
+++ nodes/gformat.py	(revision 8598)
@@ -545,7 +545,9 @@
 def make_dns():
   items = dict()
+
   # hostname is key, IP is value
   wleiden_zone = dict()
   wleiden_cname = dict()
+
   pool = dict()
   for node in get_hostlist():
@@ -559,10 +561,7 @@
     wleiden_zone[fqdn] = datadump['masterip']
 
-    #items['node'] = node
-    #items['wdir'] = "./static/%(node)s" % items
-    #if not os.path.isdir(items['wdir']):
-    #  os.makedirs(items['wdir'])
+    # Hacking to get proper DHCP IPs and hostnames
     for iface_key in get_interface_keys(datadump):
-      iface_name = datadump[iface_key]['interface'].replace(':',"_alias_")
+      iface_name = datadump[iface_key]['interface'].replace(':',"-alias-")
       (ip, netmask) = datadump[iface_key]['ip'].split('/')
       try:
@@ -585,6 +584,5 @@
         continue
 
-  # wleiden_zone["2%s-%s.%s" % ("unused", iface_name, fqdn)] = ip
-  # #XXX: automatic naming convention namely 2 + remote.lower()
+  # Automatic naming convention of interlinks namely 2 + remote.lower()
   for (key,value) in pool.iteritems():
     if len(value) == 1:
@@ -600,24 +598,72 @@
       for item in value:
         (iface_name, fqdn, ip) = item 
-        pool_name = "2pool-" + showaddr(key).replace('.','-') + "-" + "_".join(sorted(list(set(pool_members) - set([fqdn]))))
+        pool_name = "2pool-" + showaddr(key).replace('.','-') + "-" + "-".join(sorted(list(set(pool_members) - set([fqdn]))))
         wleiden_zone["%s.%s" % (pool_name, fqdn)] = ip
+
+  # Include static DNS entries
+  # XXX: Should they override the autogenerated results?
+  # XXX: Convert input to yaml more useable.
+  # Format:
+  ##; this is a comment
+  ## roomburgh=CNodeRoomburgh1
+  ## apkerk1.CNodeVosko=172.17.176.8 ;this as well
+  f = open('../dns/staticDNS.conf','r')
+  for l in f.readlines():
+    # Get rid of comments
+    l = l.strip().split(';')[0].strip()
+    if l:
+      k,v = l.split('=')
+      if valid_addr(v):
+        wleiden_zone[k] = v
+      else:
+        wleiden_cname[k] = v
+  f.close()
       
+  details = dict()
+  # 24 updates a day allowed
+  details['serial'] = time.strftime('%Y%m%d%H')
+
+  dns_header = '''
+$TTL 3h
+%(zone)s. SOA sunny.wleiden.net. beheer.lijst.wirelessleiden.nl. ( %(serial)s 1d 12h 1w 3h )
+	; Serial, Refresh, Retry, Expire, Neg. cache TTL
+
+	NS	sunny.wleiden.net.
+  \n'''
+
     
-  f = open("db.wleiden.net", "w")
+  if not os.path.isdir('dns'):
+    os.makedirs('dns')
+  details['zone'] = 'wleiden.net'
+  f = open("dns/db." + details['zone'], "w")
+  f.write(dns_header % details)
+
   for host,ip in wleiden_zone.iteritems():
-    f.write("%s.wleiden.net. A %s ~\n" % (host, ip)) 
+    if valid_addr(ip):
+      f.write("%s.wleiden.net. IN A %s \n" % (host, ip)) 
   for source,dest in wleiden_cname.iteritems():
-    f.write("%s.wleiden.net. CNAME %s.wleiden.net. ~\n" % (source, dest))
+    f.write("%s.wleiden.net. IN CNAME %s.wleiden.net.\n" % (source, dest))
   f.close()
-  f = open("db.172.in-addr.arpa", "w")
-  for host,ip in wleiden_zone.iteritems():
-    rev_ip = '.'.join(reversed(ip.split('.')))
-    f.write("%s.in-addr.arpa. PTR %s.wleiden.net. ~\n" % (rev_ip, host)) 
-  f.close()
+  
+  # Create whole bunch of specific sub arpa zones. To keep it compliant
+  for s in range(16,32):
+    details['zone'] = '%i.172.in-addr.arpa' % s
+    f = open("dns/db." + details['zone'], "w")
+    f.write(dns_header % details)
+
+    #XXX: Not effient, fix to proper data structure and do checks at other
+    # stages
+    for host,ip in wleiden_zone.iteritems():
+      if valid_addr(ip):
+        if int(ip.split('.')[1]) == s:
+          rev_ip = '.'.join(reversed(ip.split('.')))
+          f.write("%s.in-addr.arpa. IN PTR %s.wleiden.net.\n" % (rev_ip, host)) 
+    f.close()
 
 
 def usage():
-  print """Usage: %s <standalone [port] |test [test arguments]|static>
+  print """Usage: %s <standalone [port] |test [test arguments]|static|dns>
 Examples:
+\tdns                          =  Generate BIND compliant zone files in dns.
 \tstandalone                   =  Run configurator webserver [default port=8000]
 \tstatic                       =  Generate all config files and store on disk
