-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathValidateZoneFile.py
executable file
·105 lines (92 loc) · 3.28 KB
/
ValidateZoneFile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env python
import re
import sys
import StringIO
IGNORE_PREFIX="#@Z:'&"
def isCorrectHostName(name):
if name.find(' ') != -1: # name contains spaces
return False
for part in name.split('.'): # split the parts of the server name
if not re.match("^[a-zA-Z0-9_\-]*$", part):
return False
return True
def isCorrectInteger(s):
return re.match("^(0|[1-9][0-9]*)$", s) != None
def isCorrectIPv4(addr):
parts = addr.split('.')
if len(parts) != 4: # ipv4 contains 4 numbers
return False
for part in parts:
if not isCorrectInteger(part): # check if it's a number
return False
if int(part) > 255: # check if the number is within 0~255
return False
return True
def validateRecordPlus(fields):
if len(fields) < 2: # check if the record contains at least 2 fields
return (False, "+ records must have at least 2 fields")
if not isCorrectHostName(fields[0]):
return (False, "incorrect hostname: \"%s\"" % (fields[0]))
if not isCorrectIPv4(fields[1]):
return (False, "incorrect ipv4 address: \"%s\"" % (fields[1]))
if len(fields) >= 3 and not isCorrectInteger(fields[2]):
return (False, "should be an integer: %s" % (fields[2]))
return (True,"")
def validateRecordC(fields):
if len(fields) < 2: # check if the record contains at least 2 fields
return (False, "+ records must have at least 2 fields")
if not isCorrectHostName(fields[0]):
return (False, "incorrect hostname: \"%s\"" % (fields[0]))
if not isCorrectHostName(fields[1]):
return (False, "incorrect ipv4 address: \"%s\"" % (fields[1]))
if len(fields) >= 3 and not isCorrectInteger(fields[2]):
return (False, "should be an integer: %s" % (fields[2]))
return (True,"")
def stripComments(line):
hashIndex = line.find('#')
if hashIndex >= 0:
return line[:hashIndex]
else:
return line
def validateLine(line):
line = stripComments(line).strip()
if len(line) == 0: # empty or comment line
return (True,"")
# select validate function based on its prefix
prefix = line[0]
if prefix in IGNORE_PREFIX:
return (True,"")
fields = line[1:].split(':')
if prefix == '+':
return validateRecordPlus(fields)
elif prefix == 'C':
return validateRecordC(fields)
else:
return (False, "unknown prefix: \"%s\"" % (prefix))
def reportError(lineno, errmsg, fout=sys.stdout):
fout.write("error: line %d: %s\n" % (lineno, errmsg))
def validateFile(fin):
lineno = 0
nerror = 0
fout = StringIO.StringIO()
for line in fin:
lineno += 1
line = line.strip()
(success, errmsg) = validateLine(line)
if not success:
reportError(lineno, errmsg, fout)
nerror += 1
if line != "": # last line must be a newline
reportError(lineno, "file must end with a newline", fout)
nerror += 1
return (nerror == 0, fout.getvalue())
if __name__ == "__main__":
success = False
if len(sys.argv) > 1:
with open(sys.argv[1], "r") as f:
(success, errmsg) = validateFile(f)
else:
(success, errmsg) = validateFile(sys.stdin)
if not success:
sys.stderr.write(errmsg)
sys.exit(1)