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:
21
dzonegit.py
21
dzonegit.py
@ -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)):
|
||||||
|
@ -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")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user