#!/usr/bin/env python # Splice TinyDNS validator and uploader # David North, August 2009 import os, sys, glob ## Configuration user = 'david' #os.getenv('USERV_USER') datadir= '/home/david/Desktop/data' #'/etc/bmdns/data' userdatadir='/home/' + user + '/dns' zonelist= '/home/david/Desktop/zonelist' #'/etc/bmdns/zonelist' ## End configuration def validate(line, line_number, file): """ Validate a TinyDNS line. TinyDNS record types (id'd by first char of line) are: 6=ipv6+rDNS, +=host, .=authority, @=mx, C=cname, &=ns '=txt, _=generic (e.g. SRV), Z=soa, 3=6 with no rDNS """ def die(msg): """Conk out with 'error on line x' + msg""" sys.stderr.write('Error on line %s of %s: %s\n', line_number, file, msg) sys.stderr.write('Upload aborted. Please fix the error above.\n') sys.exit(1) if not line: return # blank lines are ignored else: first = line[0] if first == '#': return # comments are ignored, so they're fine too elif first == '6': # IPv6 + rDNS: must not be for an IP in another splicer's range, # and hostname must be in one of user's domains elif first == '3': #same as 6, but range restriction not needed as no automatic rDNS insertion elif first == '.': # rDNS authority: allowed for david and rdns only respectively, as they handle it for v4 and v6 elif first == '@': # MX record. If it's for the splice MX, only david should give the IP, and it should be the right one elif first in ['C', "'", '+', '_']: # CNAME, TXT, A and custom (SRV, etc.) # hostname must be in one of user's domains elif first in ['Z', '&']: # SOA and NS die("SOA and NS records are not implemented, because David didn't see the need. Email him and tell him not to be a lazy so-and-so.") else: die('Unsupported record type. Please speak to David.') # check the contents of the user's ~/dns/ folder for sanity # ignore files with names ending .old .ctold ~ files = [f for f in os.listdir(userdatadir) if not f.endswith('~') and not f.endswith('.old') and not f.endswith('.ctold')] paths = [os.path.join(datadir, f) for f in files] for fp in paths: f = open(fp, 'r') line_number = 0 for line in f: validate(l.strip(), line_number, fp) # exits script with error if appropriate line_number += 1 # If we've reached this point, the data is good, so copy it to the datadir and push it to the servers # delete any previous data for this user for f in glob.glob(os.path.join(datadir, user) + '-*') os.unlink(f) for f in files: os.copy cp $userdatadir/$fn $datadir/$USERV_USER-$fn # run the Bytemark upload script os.chdir(datadir) ./upload