1
0
mirror of https://github.com/oskar456/dzonegit.git synced 2024-05-11 05:55:41 +00:00

Support custom $UNIXTIME directive in place of SOA serial

This commit is contained in:
Ondřej Caletka
2018-08-20 14:43:29 +02:00
parent 03cf26bbbe
commit 17f771bca6
2 changed files with 60 additions and 4 deletions

View File

@ -83,14 +83,26 @@ def get_file_contents(path, revision=None):
return r.stdout return r.stdout
def compile_zone(zonename, zonedata): def unixtime_directive(zonedata, unixtime=None):
""" Filter binary zone data. Replace $UNIXTIME with current unix time. """
if unixtime is None:
unixtime = int(time.time())
return re.sub(
br'\$UNIXTIME\b',
str(unixtime).encode("ascii"),
zonedata,
flags=re.IGNORECASE,
)
def compile_zone(zonename, zonedata, unixtime=None):
""" Compile the zone. Return tuple with results.""" """ Compile the zone. Return tuple with results."""
CompileResults = namedtuple( CompileResults = namedtuple(
"CompileResults", "success, serial, zonehash, stderr", "CompileResults", "success, serial, zonehash, stderr",
) )
r = subprocess.run( r = subprocess.run(
["/usr/sbin/named-compilezone", "-o", "-", zonename, "/dev/stdin"], ["/usr/sbin/named-compilezone", "-o", "-", zonename, "/dev/stdin"],
input=zonedata, input=unixtime_directive(zonedata, unixtime),
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
) )
@ -193,13 +205,14 @@ def get_zone_name(path, zonedata):
def check_updated_zones(against, revision=None, autoupdate_serial=False): def check_updated_zones(against, revision=None, autoupdate_serial=False):
""" Check whether all updated zone files compile. """ """ Check whether all updated zone files compile. """
unixtime = int(time.time())
for f in get_altered_files(against, "AMCR", revision): for f in get_altered_files(against, "AMCR", revision):
if not f.suffix == ".zone": if not f.suffix == ".zone":
continue continue
print("Checking file {f}".format(f=f)) print("Checking file {f}".format(f=f))
zonedata = get_file_contents(f, revision) zonedata = get_file_contents(f, revision)
zname = get_zone_name(f, zonedata) zname = get_zone_name(f, zonedata)
rnew = compile_zone(zname, zonedata) rnew = compile_zone(zname, zonedata, unixtime)
if not rnew.success: if not rnew.success:
raise HookException( raise HookException(
"New zone version does not compile", "New zone version does not compile",
@ -208,7 +221,7 @@ def check_updated_zones(against, revision=None, autoupdate_serial=False):
try: try:
zonedata = get_file_contents(f, against) zonedata = get_file_contents(f, against)
zname = get_zone_name(f, zonedata) zname = get_zone_name(f, zonedata)
rold = compile_zone(zname, zonedata) rold = compile_zone(zname, zonedata, unixtime-1)
if (rold.success and rold.zonehash != rnew.zonehash and not if (rold.success and rold.zonehash != rnew.zonehash and not
is_serial_increased(rold.serial, rnew.serial)): is_serial_increased(rold.serial, rnew.serial)):

View File

@ -74,6 +74,26 @@ ns.example.com. 60 IN A 192.0.2.1
assert r.zonehash == r2.zonehash assert r.zonehash == r2.zonehash
def test_compile_unsmudged_zone():
testzone = b"""
$ORIGIN example.com.
@ 60 IN SOA ns hostmaster (
$UNIXTIME ; serial
3600 ; refresh (1 hour)
900 ; retry (15 minutes)
1814400 ; expire (3 weeks)
60 ; minimum (1 minute)
)
60 IN NS ns
ns.example.com. 60 IN A 192.0.2.1
"""
replaced = dzonegit.unixtime_directive(testzone)
assert b"$UNIXTIME" not in replaced
r = dzonegit.compile_zone("example.com", testzone, 123456)
assert r.success
assert r.serial == str(123456)
def test_is_serial_increased(): def test_is_serial_increased():
assert dzonegit.is_serial_increased(1234567890, "2018010100") assert dzonegit.is_serial_increased(1234567890, "2018010100")
assert dzonegit.is_serial_increased("2018010100", "4018010100") assert dzonegit.is_serial_increased("2018010100", "4018010100")
@ -228,6 +248,29 @@ $ORIGIN dummy.
dzonegit.check_updated_zones("HEAD", autoupdate_serial=True) dzonegit.check_updated_zones("HEAD", autoupdate_serial=True)
subprocess.call(["git", "add", "dummy.zone"]) subprocess.call(["git", "add", "dummy.zone"])
dzonegit.check_updated_zones(dzonegit.get_head()) dzonegit.check_updated_zones(dzonegit.get_head())
git_dir.join("dummy.zone").write("""
$ORIGIN dummy.
@ 60 IN SOA ns hm $UNIXTIME 61 60 60 60
60 NS ns.example.org.
""")
subprocess.call(["git", "add", "dummy.zone"])
dzonegit.check_updated_zones(dzonegit.get_head())
subprocess.call(["git", "commit", "-m", "dummy.zone with $UNIXTIME"])
git_dir.join("dummy.zone").write("""
$ORIGIN dummy.
@ 60 IN SOA ns hm 1 60 60 60 60
60 NS ns.example.org.
""")
subprocess.call(["git", "add", "dummy.zone"])
with pytest.raises(ValueError):
dzonegit.check_updated_zones(dzonegit.get_head())
git_dir.join("dummy.zone").write("""
$ORIGIN dummy.
@ 60 IN SOA ns hm $UNIXTIME 60 60 60 60
60 NS ns.example.org.
""")
subprocess.call(["git", "add", "dummy.zone"])
dzonegit.check_updated_zones(dzonegit.get_head())
subprocess.call(["git", "commit", "-m", "final dummy.zone"]) subprocess.call(["git", "commit", "-m", "final dummy.zone"])
dzonegit.check_updated_zones("HEAD~", "HEAD") dzonegit.check_updated_zones("HEAD~", "HEAD")