mirror of
https://github.com/oskar456/dzonegit.git
synced 2024-05-11 05:55:41 +00:00
Support auto-update of the serial number
This commit is contained in:
35
dzonegit.py
35
dzonegit.py
@ -188,7 +188,7 @@ def get_zone_name(path, zonedata):
|
|||||||
return stemname
|
return stemname
|
||||||
|
|
||||||
|
|
||||||
def check_updated_zones(against, revision=None):
|
def check_updated_zones(against, revision=None, autoupdate_serial=False):
|
||||||
""" Check whether all updated zone files compile. """
|
""" Check whether all updated zone files compile. """
|
||||||
for f in get_altered_files(against, "AM", revision):
|
for f in get_altered_files(against, "AM", revision):
|
||||||
if not f.suffix == ".zone":
|
if not f.suffix == ".zone":
|
||||||
@ -209,13 +209,20 @@ def check_updated_zones(against, revision=None):
|
|||||||
|
|
||||||
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)):
|
||||||
errmsg = "Old revision {}, serial {}, new serial {}".format(
|
errmsg = "Zone contents changed without increasing serial."
|
||||||
|
diagmsg = "Old revision {}, serial {}, new serial {}".format(
|
||||||
against, rold.serial, rnew.serial,
|
against, rold.serial, rnew.serial,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if autoupdate_serial:
|
||||||
|
newserial = get_increased_serial(rnew.serial)
|
||||||
|
replace_serial(f, rnew.serial, newserial)
|
||||||
|
errmsg += " Serial has been automatically increased."
|
||||||
|
errmsg += " Check and recommit."
|
||||||
raise HookException(
|
raise HookException(
|
||||||
"Zone contents changed without increasing serial",
|
errmsg,
|
||||||
fname=f,
|
fname=f,
|
||||||
stderr=errmsg,
|
stderr=diagmsg,
|
||||||
)
|
)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
pass # Old version of zone did not exist
|
pass # Old version of zone did not exist
|
||||||
@ -233,8 +240,9 @@ def get_config(name, type_=None):
|
|||||||
r = subprocess.run(
|
r = subprocess.run(
|
||||||
cmd,
|
cmd,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
check=True,
|
|
||||||
)
|
)
|
||||||
|
if r.returncode != 0:
|
||||||
|
return None
|
||||||
if type_ == bool:
|
if type_ == bool:
|
||||||
return r.stdout == b"true\n"
|
return r.stdout == b"true\n"
|
||||||
elif type_ == int:
|
elif type_ == int:
|
||||||
@ -243,11 +251,26 @@ def get_config(name, type_=None):
|
|||||||
return r.stdout.decode("utf-8").rstrip("\n")
|
return r.stdout.decode("utf-8").rstrip("\n")
|
||||||
|
|
||||||
|
|
||||||
|
def replace_serial(path, oldserial, newserial):
|
||||||
|
contents = path.read_text()
|
||||||
|
updated, count = re.subn(
|
||||||
|
r'(^.*\sSOA\s.+?\s){}([^0-9])'.format(oldserial),
|
||||||
|
r'\g<1>{}\g<2>'.format(newserial),
|
||||||
|
contents,
|
||||||
|
count=1,
|
||||||
|
flags=re.DOTALL | re.IGNORECASE | re.MULTILINE,
|
||||||
|
)
|
||||||
|
if count != 1:
|
||||||
|
raise HookException("Cannot update zone serial number")
|
||||||
|
path.write_text(updated)
|
||||||
|
|
||||||
|
|
||||||
def pre_commit():
|
def pre_commit():
|
||||||
against = get_head()
|
against = get_head()
|
||||||
|
autoupdate_serial = not get_config("hooks.noserialupdate", bool)
|
||||||
try:
|
try:
|
||||||
check_whitespace_errors(against)
|
check_whitespace_errors(against)
|
||||||
check_updated_zones(against)
|
check_updated_zones(against, autoupdate_serial=autoupdate_serial)
|
||||||
except HookException as e:
|
except HookException as e:
|
||||||
print(e)
|
print(e)
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
@ -141,6 +141,44 @@ ns 60 IN A 192.0.2.1
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_replace_serial(git_dir):
|
||||||
|
git_dir.join("dummy.zone").write("""
|
||||||
|
@ 60 IN SOA ns hm 1 61 60 60 60
|
||||||
|
60 NS ns.example.org.
|
||||||
|
""")
|
||||||
|
dzonegit.replace_serial(Path("dummy.zone"), "1", "60")
|
||||||
|
assert git_dir.join("dummy.zone").read() == """
|
||||||
|
@ 60 IN SOA ns hm 60 61 60 60 60
|
||||||
|
60 NS ns.example.org.
|
||||||
|
"""
|
||||||
|
dzonegit.replace_serial(Path("dummy.zone"), "60", "61")
|
||||||
|
assert git_dir.join("dummy.zone").read() == """
|
||||||
|
@ 60 IN SOA ns hm 61 61 60 60 60
|
||||||
|
60 NS ns.example.org.
|
||||||
|
"""
|
||||||
|
git_dir.join("dummy.zone").write("""
|
||||||
|
@ 60 IN SOA ns hm (
|
||||||
|
60 ; serial
|
||||||
|
60 ; refresh
|
||||||
|
60 ; retry
|
||||||
|
60 ; expire
|
||||||
|
60 ; minimum
|
||||||
|
)
|
||||||
|
60 NS ns.example.org.
|
||||||
|
""")
|
||||||
|
dzonegit.replace_serial(Path("dummy.zone"), "60", "6000000")
|
||||||
|
assert git_dir.join("dummy.zone").read() == """
|
||||||
|
@ 60 IN SOA ns hm (
|
||||||
|
6000000 ; serial
|
||||||
|
60 ; refresh
|
||||||
|
60 ; retry
|
||||||
|
60 ; expire
|
||||||
|
60 ; minimum
|
||||||
|
)
|
||||||
|
60 NS ns.example.org.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_check_updated_zones(git_dir):
|
def test_check_updated_zones(git_dir):
|
||||||
git_dir.chdir()
|
git_dir.chdir()
|
||||||
git_dir.join("dummy.zone").write("")
|
git_dir.join("dummy.zone").write("")
|
||||||
@ -178,10 +216,13 @@ $ORIGIN other.
|
|||||||
dzonegit.check_updated_zones(dzonegit.get_head())
|
dzonegit.check_updated_zones(dzonegit.get_head())
|
||||||
git_dir.join("dummy.zone").write("""
|
git_dir.join("dummy.zone").write("""
|
||||||
$ORIGIN dummy.
|
$ORIGIN dummy.
|
||||||
@ 60 IN SOA ns hm 2 60 60 60 60
|
@ 60 IN SOA ns hm 1 61 60 60 60
|
||||||
60 NS ns.example.org.
|
60 NS ns.example.org.
|
||||||
""")
|
""")
|
||||||
subprocess.call(["git", "add", "dummy.zone"])
|
subprocess.call(["git", "add", "dummy.zone"])
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
dzonegit.check_updated_zones("HEAD", autoupdate_serial=True)
|
||||||
|
subprocess.call(["git", "add", "dummy.zone"])
|
||||||
dzonegit.check_updated_zones(dzonegit.get_head())
|
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