[svn] commit: r2340 - in /trunk: ./ src/bin/loadzone/ src/bin/loadzone/testdata/ src/bin/loadzone/tests/ src/bin/loadzone/tests/correct/ src/bin/loadzone/tests/error/ src/bin/loadzone/tests/normal/ src/lib/python/isc/datasrc/
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Jun 30 07:27:31 UTC 2010
Author: shentingting
Date: Wed Jun 30 07:27:30 2010
New Revision: 2340
Log:
Added verbose options to exactly what is happening with loadzone. Added loadzone test suite of different file formats to load.
Added:
trunk/src/bin/loadzone/tests/
trunk/src/bin/loadzone/tests/correct/
trunk/src/bin/loadzone/tests/correct/Makefile.am
trunk/src/bin/loadzone/tests/correct/correct_test.sh.in
trunk/src/bin/loadzone/tests/correct/example.db
trunk/src/bin/loadzone/tests/correct/get_zonedatas.py
trunk/src/bin/loadzone/tests/correct/inclsub.db
trunk/src/bin/loadzone/tests/correct/include.db
trunk/src/bin/loadzone/tests/correct/known.test.out
trunk/src/bin/loadzone/tests/correct/mix1.db
trunk/src/bin/loadzone/tests/correct/mix1sub1.db
trunk/src/bin/loadzone/tests/correct/mix1sub2.db
trunk/src/bin/loadzone/tests/correct/mix2.db
trunk/src/bin/loadzone/tests/correct/mix2sub1.txt
trunk/src/bin/loadzone/tests/correct/mix2sub2.txt
trunk/src/bin/loadzone/tests/correct/ttl1.db
trunk/src/bin/loadzone/tests/correct/ttl2.db
trunk/src/bin/loadzone/tests/correct/ttlext.db
trunk/src/bin/loadzone/tests/error/
trunk/src/bin/loadzone/tests/error/Makefile.am
trunk/src/bin/loadzone/tests/error/error.known
trunk/src/bin/loadzone/tests/error/error_test.sh.in
trunk/src/bin/loadzone/tests/error/formerr1.db
trunk/src/bin/loadzone/tests/error/formerr2.db
trunk/src/bin/loadzone/tests/error/formerr3.db
trunk/src/bin/loadzone/tests/error/formerr4.db
trunk/src/bin/loadzone/tests/error/formerr5.db
trunk/src/bin/loadzone/tests/error/include.txt
trunk/src/bin/loadzone/tests/error/keyerror1.db
trunk/src/bin/loadzone/tests/error/keyerror2.db
trunk/src/bin/loadzone/tests/error/keyerror3.db
trunk/src/bin/loadzone/tests/error/originerr1.db
trunk/src/bin/loadzone/tests/error/originerr2.db
trunk/src/bin/loadzone/tests/normal/
trunk/src/bin/loadzone/tests/normal/Kexample.com.+005+04456.key
trunk/src/bin/loadzone/tests/normal/Kexample.com.+005+04456.private
trunk/src/bin/loadzone/tests/normal/Kexample.com.+005+33495.key
trunk/src/bin/loadzone/tests/normal/Kexample.com.+005+33495.private
trunk/src/bin/loadzone/tests/normal/Ksql1.example.com.+005+12447.key
trunk/src/bin/loadzone/tests/normal/Ksql1.example.com.+005+12447.private
trunk/src/bin/loadzone/tests/normal/Ksql1.example.com.+005+33313.key
trunk/src/bin/loadzone/tests/normal/Ksql1.example.com.+005+33313.private
trunk/src/bin/loadzone/tests/normal/Ksql2.example.com.+005+38482.key
trunk/src/bin/loadzone/tests/normal/Ksql2.example.com.+005+38482.private
trunk/src/bin/loadzone/tests/normal/Ksql2.example.com.+005+63192.key
trunk/src/bin/loadzone/tests/normal/Ksql2.example.com.+005+63192.private
trunk/src/bin/loadzone/tests/normal/README
trunk/src/bin/loadzone/tests/normal/dsset-subzone.example.com
trunk/src/bin/loadzone/tests/normal/example.com
trunk/src/bin/loadzone/tests/normal/example.com.signed
trunk/src/bin/loadzone/tests/normal/sql1.example.com
trunk/src/bin/loadzone/tests/normal/sql1.example.com.signed
trunk/src/bin/loadzone/tests/normal/sql2.example.com
trunk/src/bin/loadzone/tests/normal/sql2.example.com.signed
Removed:
trunk/src/bin/loadzone/testdata/
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/src/bin/loadzone/Makefile.am
trunk/src/bin/loadzone/b10-loadzone.py.in
trunk/src/lib/python/isc/datasrc/master.py
Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog (original)
+++ trunk/ChangeLog Wed Jun 30 07:27:30 2010
@@ -1,3 +1,8 @@
+ 65. [func] shentingting
+ Added verbose options to exactly what is happening with loadzone.
+ Added loadzone test suite of different file formats to load.
+ (tingting-loadzone, svn r2339)
+
64. [func] jerry
Added python logging framework. It is for testing and experimenting
with logging ideas. Currently, it supports three channels(file,
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Wed Jun 30 07:27:30 2010
@@ -415,6 +415,8 @@
src/bin/cfgmgr/tests/Makefile
src/bin/host/Makefile
src/bin/loadzone/Makefile
+ src/bin/loadzone/tests/correct/Makefile
+ src/bin/loadzone/tests/error/Makefile
src/bin/msgq/Makefile
src/bin/msgq/tests/Makefile
src/bin/auth/Makefile
@@ -464,6 +466,8 @@
src/bin/bindctl/bindctl-source.py
src/bin/bindctl/tests/bindctl_test
src/bin/loadzone/run_loadzone.sh
+ src/bin/loadzone/tests/correct/correct_test.sh
+ src/bin/loadzone/tests/error/error_test.sh
src/bin/loadzone/b10-loadzone.py
src/bin/usermgr/run_b10-cmdctl-usermgr.sh
src/bin/usermgr/b10-cmdctl-usermgr.py
@@ -491,6 +495,8 @@
chmod +x src/bin/bindctl/tests/bindctl_test
chmod +x src/bin/bindctl/run_bindctl.sh
chmod +x src/bin/loadzone/run_loadzone.sh
+ chmod +x src/bin/loadzone/tests/correct/correct_test.sh
+ chmod +x src/bin/loadzone/tests/error/error_test.sh
chmod +x src/bin/usermgr/run_b10-cmdctl-usermgr.sh
chmod +x src/bin/msgq/run_msgq.sh
chmod +x src/bin/msgq/tests/msgq_test
Modified: trunk/src/bin/loadzone/Makefile.am
==============================================================================
--- trunk/src/bin/loadzone/Makefile.am (original)
+++ trunk/src/bin/loadzone/Makefile.am Wed Jun 30 07:27:30 2010
@@ -1,3 +1,5 @@
+SUBDIRS = tests/correct
+SUBDIRS += tests/error
bin_SCRIPTS = b10-loadzone
CLEANFILES = b10-loadzone
@@ -22,23 +24,27 @@
$(mkinstalldirs) $(DESTDIR)/@localstatedir@/@PACKAGE@
# TODO: permissions handled later
-EXTRA_DIST += testdata/README
-EXTRA_DIST += testdata/dsset-subzone.example.com.
-EXTRA_DIST += testdata/example.com
-EXTRA_DIST += testdata/example.com.signed
-EXTRA_DIST += testdata/Kexample.com.+005+04456.key
-EXTRA_DIST += testdata/Kexample.com.+005+04456.private
-EXTRA_DIST += testdata/Kexample.com.+005+33495.key
-EXTRA_DIST += testdata/Kexample.com.+005+33495.private
-EXTRA_DIST += testdata/Ksql1.example.com.+005+12447.key
-EXTRA_DIST += testdata/Ksql1.example.com.+005+12447.private
-EXTRA_DIST += testdata/Ksql1.example.com.+005+33313.key
-EXTRA_DIST += testdata/Ksql1.example.com.+005+33313.private
-EXTRA_DIST += testdata/Ksql2.example.com.+005+38482.key
-EXTRA_DIST += testdata/Ksql2.example.com.+005+38482.private
-EXTRA_DIST += testdata/Ksql2.example.com.+005+63192.key
-EXTRA_DIST += testdata/Ksql2.example.com.+005+63192.private
-EXTRA_DIST += testdata/sql1.example.com
-EXTRA_DIST += testdata/sql1.example.com.signed
-EXTRA_DIST += testdata/sql2.example.com
-EXTRA_DIST += testdata/sql2.example.com.signed
+EXTRA_DIST += tests/normal/README
+EXTRA_DIST += tests/normal/dsset-subzone.example.com.
+EXTRA_DIST += tests/normal/example.com
+EXTRA_DIST += tests/normal/example.com.signed
+EXTRA_DIST += tests/normal/Kexample.com.+005+04456.key
+EXTRA_DIST += tests/normal/Kexample.com.+005+04456.private
+EXTRA_DIST += tests/normal/Kexample.com.+005+33495.key
+EXTRA_DIST += tests/normal/Kexample.com.+005+33495.private
+EXTRA_DIST += tests/normal/Ksql1.example.com.+005+12447.key
+EXTRA_DIST += tests/normal/Ksql1.example.com.+005+12447.private
+EXTRA_DIST += tests/normal/Ksql1.example.com.+005+33313.key
+EXTRA_DIST += tests/normal/Ksql1.example.com.+005+33313.private
+EXTRA_DIST += tests/normal/Ksql2.example.com.+005+38482.key
+EXTRA_DIST += tests/normal/Ksql2.example.com.+005+38482.private
+EXTRA_DIST += tests/normal/Ksql2.example.com.+005+63192.key
+EXTRA_DIST += tests/normal/Ksql2.example.com.+005+63192.private
+EXTRA_DIST += tests/normal/sql1.example.com
+EXTRA_DIST += tests/normal/sql1.example.com.signed
+EXTRA_DIST += tests/normal/sql2.example.com
+EXTRA_DIST += tests/normal/sql2.example.com.signed
+
+pytest:
+ $(SHELL) tests/correct/correct_test.sh
+ $(SHELL) tests/error/error_test.sh
Modified: trunk/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- trunk/src/bin/loadzone/b10-loadzone.py.in (original)
+++ trunk/src/bin/loadzone/b10-loadzone.py.in Wed Jun 30 07:27:30 2010
@@ -19,7 +19,8 @@
import re, getopt
import isc.datasrc
from isc.datasrc.master import MasterFile
-
+import time
+import os
#########################################################################
# usage: print usage note and exit
#########################################################################
@@ -57,23 +58,32 @@
if len(args) != 1:
usage()
zonefile = args[0]
-
+ verbose = os.isatty(sys.stdout.fileno())
try:
- master = MasterFile(zonefile, initial_origin)
+ master = MasterFile(zonefile, initial_origin, verbose)
except Exception as e:
- print("Error reading zone file: " + str(e))
+ sys.stderr.write("Error reading zone file: %s\n" % str(e))
exit(1)
try:
zone = master.zonename()
+ if verbose:
+ sys.stdout.write("Using SQLite3 database file %s\n" % dbfile)
+ sys.stdout.write("Zone name is %s\n" % zone)
+ sys.stdout.write("Loading file \"%s\"\n" % zonefile)
except Exception as e:
- print("Error reading zone file: " + str(e))
+ sys.stdout.write("\n")
+ sys.stderr.write("Error reading zone file: %s\n" % str(e))
exit(1)
try:
isc.datasrc.sqlite3_ds.load(dbfile, zone, master.zonedata)
+ if verbose:
+ master.closeverbose()
+ sys.stdout.write("\nDone.\n")
except Exception as e:
- print("Error loading database: " + str(e))
+ sys.stdout.write("\n")
+ sys.stderr.write("Error loading database: %s\n"% str(e))
exit(1)
if __name__ == "__main__":
Modified: trunk/src/lib/python/isc/datasrc/master.py
==============================================================================
--- trunk/src/lib/python/isc/datasrc/master.py (original)
+++ trunk/src/lib/python/isc/datasrc/master.py Wed Jun 30 07:27:30 2010
@@ -16,7 +16,8 @@
# $Id$
import sys, re, string
-
+import time
+import os
#########################################################################
# define exceptions
#########################################################################
@@ -102,7 +103,7 @@
# isttl: check whether a string is a valid TTL specifier.
# returns: boolean
#########################################################################
-ttl_regex = re.compile('[0-9]+[wdhms]?', re.I)
+ttl_regex = re.compile('([0-9]+[wdhms]?)+', re.I)
def isttl(s):
global ttl_regex
if ttl_regex.match(s):
@@ -121,19 +122,26 @@
# MasterFileError
#########################################################################
def parse_ttl(s):
- m = re.match('([0-9]+)(.*)', s)
- if not m:
+ sum = 0
+ if not isttl(s):
raise MasterFileError('Invalid TTL: ' + s)
- ttl, suffix = int(m.group(1)), m.group(2)
- if suffix.lower() == 'w':
- ttl *= 604800
- elif suffix.lower() == 'd':
- ttl *= 86400
- elif suffix.lower() == 'h':
- ttl *= 3600
- elif suffix.lower() == 'm':
- ttl *= 60
- return str(ttl)
+ for ttl_expr in re.findall('\d+[wdhms]?', s, re.I):
+ if ttl_expr.isdigit():
+ ttl = int(ttl_expr)
+ sum += ttl
+ continue
+ ttl = int(ttl_expr[:-1])
+ suffix = ttl_expr[-1].lower()
+ if suffix == 'w':
+ ttl *= 604800
+ elif suffix == 'd':
+ ttl *= 86400
+ elif suffix == 'h':
+ ttl *= 3600
+ elif suffix == 'm':
+ ttl *= 60
+ sum += ttl
+ return str(sum)
#########################################################################
# records: generator function to return complete RRs from the zone file,
@@ -147,7 +155,9 @@
record = []
complete = True
paren = 0
+ size = 0
for line in input:
+ size += len(line)
list = cleanup(line).split()
for word in list:
if paren == 0:
@@ -169,10 +179,12 @@
if paren == 1 or not record:
continue
-
+
ret = ' '.join(record)
record = []
- yield ret
+ oldsize = size
+ size = 0
+ yield ret, oldsize
#########################################################################
# define the MasterFile class for reading zone master files
@@ -181,24 +193,62 @@
__rrclass = 'IN'
__maxttl = 0x7fffffff
__ttl = ''
+ __lastttl = ''
__zonefile = ''
__name = ''
-
- def __init__(self, filename, initial_origin = ''):
- if initial_origin == '.':
- initial_origin = ''
+ __file_level = 0
+ __file_type = ""
+ __init_time = time.time()
+ __records_num = 0
+
+ def __init__(self, filename, initial_origin = '', verbose = False):
self.__initial_origin = initial_origin
self.__origin = initial_origin
+ self.__datafile = filename
+
try:
self.__zonefile = open(filename, 'r')
except:
raise MasterFileError("Could not open " + filename)
+ self.__filesize = os.fstat(self.__zonefile.fileno()).st_size
+
+ self.__cur = 0
+ self.__numback = 0
+ self.__verbose = verbose
+ try:
+ self.__zonefile = open(filename, 'r')
+ except:
+ raise MasterFileError("Could not open " + filename)
+
+ def __status(self):
+ interval = time.time() - MasterFile.__init_time
+ if self.__filesize == 0:
+ percent = 100
+ else:
+ percent = (self.__cur * 100)/self.__filesize
+
+ sys.stdout.write("\r" + (80 * " "))
+ sys.stdout.write("\r%d RR(s) loaded in %d second(s) (%.2f%% of %s%s)"\
+ % (MasterFile.__records_num, interval, percent, MasterFile.__file_type, self.__datafile))
def __del__(self):
if self.__zonefile:
self.__zonefile.close()
-
- #########################################################################
+ ########################################################################
+ # check if the zonename is relative
+ # no then return
+ # yes , sets the relative domain name to the stated name
+ #######################################################################
+ def __statedname(self, name, record):
+ if name[-1] != '.':
+ if not self.__origin:
+ raise MasterFileError("Cannot parse RR, No $ORIGIN: " + record)
+ elif self.__origin == '.':
+ name += '.'
+ else:
+ name += '.' + self.__origin
+ return name
+ #####################################################################
# handle $ORIGIN, $TTL and $GENERATE directives
# (currently only $ORIGIN and $TTL are implemented)
# input:
@@ -216,20 +266,22 @@
raise MasterFileError('Invalid $ORIGIN')
if more:
raise MasterFileError('Invalid $ORIGIN')
- if second == '.':
- self.__origin = ''
- elif second[-1] == '.':
+ if second[-1] == '.':
self.__origin = second
+ elif not self.__origin:
+ raise MasterFileError("$ORIGIN is not absolute in record:%s" % s)
+ elif self.__origin != '.':
+ self.__origin = second + '.' + self.__origin
else:
- self.__origin = second + '.' + self.__origin
+ self.__origin = second + '.'
return True
elif re.match('\$ttl', first, re.I):
if not second or not isttl(second):
raise MasterFileError('Invalid TTL: "' + second + '"')
if more:
raise MasterFileError('Invalid $TTL statement')
- self.__ttl = parse_ttl(second)
- if int(self.__ttl) > self.__maxttl:
+ MasterFile.__ttl = parse_ttl(second)
+ if int(MasterFile.__ttl) > self.__maxttl:
raise MasterFileError('TTL too high: ' + second)
return True
elif re.match('\$generate', first, re.I):
@@ -246,14 +298,28 @@
# throws:
# MasterFileError
#########################################################################
- __filename = re.compile('[\"\']*([^\'\"]+)[\"\']*')
+ __include_syntax1 = re.compile('\s+(\S+)(?:\s+(\S+))?$', re.I)
+ __include_syntax2 = re.compile('\s+"([^"]+)"(?:\s+(\S+))?$', re.I)
+ __include_syntax3 = re.compile("\s+'([^']+)'(?:\s+(\S+))?$", re.I)
def __include(self, s):
- first, rest = pop(s)
- if re.match('\$include', first, re.I):
- m = self.__filename.match(rest)
- if m:
- file = m.group(1)
- return file
+ if not s.lower().startswith('$include'):
+ return "", ""
+ s = s[len('$include'):]
+ m = self.__include_syntax1.match(s)
+ if not m:
+ m = self.__include_syntax2.match(s)
+ if not m:
+ m = self.__include_syntax3.match(s)
+ if not m:
+ raise MasterFileError('Invalid $include format')
+ file = m.group(1)
+ if m.group(2):
+ if not isname(m.group(2)):
+ raise MasterFileError('Invalid $include format (invalid origin)')
+ origin = self.__statedname(m.group(2), s)
+ else:
+ origin = self.__origin
+ return file, origin
#########################################################################
# try parsing an RR on the assumption that the type is specified in
@@ -272,6 +338,14 @@
if istype(list[3]):
if isclass(list[2]) and isttl(list[1]) and isname(list[0]):
name, ttl, rrclass, rrtype = list[0:4]
+ ttl = parse_ttl(ttl)
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
+ rdata = ' '.join(list[4:])
+ ret = name, ttl, rrclass, rrtype, rdata
+ elif isclass(list[1]) and isttl(list[2]) and isname(list[0]):
+ name, rrclass, ttl, rrtype = list[0:4]
+ ttl = parse_ttl(ttl)
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
rdata = ' '.join(list[4:])
ret = name, ttl, rrclass, rrtype, rdata
return ret
@@ -284,6 +358,9 @@
# returns:
# empty list if parse failed, else name, ttl, class, type, rdata
#########################################################################
+ def __getttl(self):
+ return MasterFile.__ttl or MasterFile.__lastttl
+
def __three(self, record, curname):
ret = ''
list = record.split()
@@ -292,19 +369,25 @@
if istype(list[2]) and not istype(list[1]):
if isclass(list[1]) and not isttl(list[0]) and isname(list[0]):
rrclass = list[1]
- ttl = self.__ttl
+ ttl = self.__getttl()
name = list[0]
- elif not isclass(list[1]) and isttl(list[1]) and isname(list[0]):
+ elif not isclass(list[1]) and isttl(list[1]) and not isclass(list[0]) and isname(list[0]):
rrclass = self.__rrclass
ttl = parse_ttl(list[1])
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
name = list[0]
elif curname and isclass(list[1]) and isttl(list[0]):
- rrclass = self.__rrclass
+ rrclass = list[1]
ttl = parse_ttl(list[0])
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
+ name = curname
+ elif curname and isttl(list[1]) and isclass(list[0]):
+ rrclass = list[0]
+ ttl = parse_ttl(list[1])
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
name = curname
else:
return ret
-
rrtype = list[2]
rdata = ' '.join(list[3:])
ret = name, ttl, rrclass, rrtype, rdata
@@ -325,29 +408,37 @@
list = record.split()
if len(list) <= 2:
return ret
-
if istype(list[1]):
rrclass = self.__rrclass
rrtype = list[1]
if list[0].lower() == 'rrsig':
name = curname
- ttl = self.__ttl
+ ttl = self.__getttl()
rrtype = list[0]
rdata = ' '.join(list[1:])
elif isttl(list[0]):
ttl = parse_ttl(list[0])
name = curname
rdata = ' '.join(list[2:])
+ elif isclass(list[0]):
+ ttl = self.__getttl()
+ name = curname
+ rdata = ' '.join(list[2:])
elif isname(list[0]):
name = list[0]
- ttl = self.__ttl
+ ttl = self.__getttl()
rdata = ' '.join(list[2:])
else:
raise MasterFileError("Cannot parse RR: " + record)
ret = name, ttl, rrclass, rrtype, rdata
-
return ret
+
+ ########################################################################
+ #close verbose
+ ######################################################################
+ def closeverbose(self):
+ self.__status()
#########################################################################
# zonedata: generator function to parse a zone master file and return
@@ -355,16 +446,43 @@
#########################################################################
def zonedata(self):
name = ''
-
- for record in records(self.__zonefile):
+ last_status = 0.0
+ flag = 1
+
+ for record, size in records(self.__zonefile):
+ if self.__verbose:
+ now = time.time()
+ if flag == 1:
+ self.__status()
+ flag = 0
+ if now - last_status >= 1.0:
+ self.__status()
+ last_status = now
+
+ self.__cur += size
if self.__directive(record):
continue
- incl = self.__include(record)
+ incl, suborigin = self.__include(record)
if incl:
- sub = MasterFile(incl, self.__origin)
- for name, ttl, rrclass, rrtype, rdata in sub.zonedata():
- yield (name, ttl, rrclass, rrtype, rdata)
+ if self.__filesize == 0:
+ percent = 100
+ else:
+ percent = (self.__cur * 100)/self.__filesize
+ if self.__verbose:
+ sys.stdout.write("\r" + (80 * " "))
+ sys.stdout.write("\rIncluding \"%s\" from \"%s\"\n" % (incl, self.__datafile))
+ MasterFile.__file_level += 1
+ MasterFile.__file_type = "included "
+ sub = MasterFile(incl, suborigin, self.__verbose)
+
+ for rrname, ttl, rrclass, rrtype, rdata in sub.zonedata():
+ yield (rrname, ttl, rrclass, rrtype, rdata)
+ if self.__verbose:
+ sub.closeverbose()
+ MasterFile.__file_level -= 1
+ if MasterFile.__file_level == 0:
+ MasterFile.__file_type = ""
del sub
continue
@@ -373,7 +491,7 @@
if rl[0] == '@':
rl[0] = self.__origin
if not self.__origin:
- rl[0] = '.'
+ raise MasterFileError("Cannot parse RR, No $ORIGIN: " + record)
record = ' '.join(rl)
result = self.__four(record, name)
@@ -387,36 +505,43 @@
if not result:
first, rdata = pop(record)
if istype(first):
- result = name, self.__ttl, self.__rrclass, first, rdata
+ result = name, self.__getttl(), self.__rrclass, first, rdata
if not result:
raise MasterFileError("Cannot parse RR: " + record)
name, ttl, rrclass, rrtype, rdata = result
- if name[-1] != '.':
- name += '.' + self.__origin
+ name = self.__statedname(name, record)
if rrclass.lower() != 'in':
raise MasterFileError("CH and HS zones not supported")
-
- if not ttl:
- raise MasterFileError("No TTL specified; zone rejected")
# add origin to rdata containing names, if necessary
if rrtype.lower() in ('cname', 'dname', 'ns', 'ptr'):
if not isname(rdata):
raise MasterFileError("Invalid " + rrtype + ": " + rdata)
- if rdata[-1] != '.':
- rdata += '.' + self.__origin
+ rdata = self.__statedname(rdata, record)
+
if rrtype.lower() == 'soa':
soa = rdata.split()
if len(soa) < 2 or not isname(soa[0]) or not isname(soa[1]):
raise MasterFileError("Invalid " + rrtype + ": " + rdata)
- if soa[0][-1] != '.':
- soa[0] += '.' + self.__origin
- if soa[1][-1] != '.':
- soa[1] += '.' + self.__origin
+ soa[0] = self.__statedname(soa[0], record)
+ soa[1] = self.__statedname(soa[1], record)
+ if not MasterFile.__ttl and not ttl:
+ MasterFile.__ttl = MasterFile.__ttl or parse_ttl(soa[-1])
+ ttl = MasterFile.__ttl
+
+ for index in range(3, len(soa)):
+ if isttl(soa[index]):
+ soa[index] = parse_ttl(soa[index])
+ else :
+ raise MasterFileError("No TTL specified; in soa record!")
rdata = ' '.join(soa)
+
+ if not ttl:
+ raise MasterFileError("No TTL specified; zone rejected")
+
if rrtype.lower() == 'mx':
mx = rdata.split()
if len(mx) != 2 or not isname(mx[1]):
@@ -424,7 +549,7 @@
if mx[1][-1] != '.':
mx[1] += '.' + self.__origin
rdata = ' '.join(mx)
-
+ MasterFile.__records_num += 1
yield (name, ttl, rrclass, rrtype, rdata)
#########################################################################
@@ -436,16 +561,22 @@
return self.__name
old_origin = self.__origin
self.__origin = self.__initial_origin
+ cur_value = self.__cur
old_location = self.__zonefile.tell()
+ old_verbose = self.__verbose
+ self.__verbose = False
self.__zonefile.seek(0)
+
for name, ttl, rrclass, rrtype, rdata in self.zonedata():
if rrtype.lower() == 'soa':
break
self.__zonefile.seek(old_location)
self.__origin = old_origin
+ self.__cur = cur_value
if rrtype.lower() != 'soa':
raise MasterFileError("No SOA found")
self.__name = name
+ self.__verbose = old_verbose
return name
#########################################################################
@@ -454,7 +585,8 @@
def reset(self):
self.__zonefile.seek(0)
self.__origin = self.__initial_origin
- self.__ttl = ''
+ MasterFile.__ttl = ''
+ MasterFile.__lastttl = ''
#########################################################################
# main: used for testing; parse a zone file and print out each record
More information about the bind10-changes
mailing list