catalog: purge members before catDB commit

This commit is contained in:
Libor Peltan 2022-06-28 16:58:32 +02:00
parent 920dfc30f0
commit 986d295c97
5 changed files with 36 additions and 22 deletions

View file

@ -432,6 +432,20 @@ static knot_zonedb_t *create_zonedb(conf_t *conf, server_t *server, list_t *expi
knot_zonedb_insert(db_new, zone);
}
/* Remove deleted cataloged zones from conf before catalog removals are commited. */
catalog_it_t *cat_it = catalog_it_begin(&server->catalog_upd);
while (!catalog_it_finished(cat_it)) {
catalog_upd_val_t *upd = catalog_it_val(cat_it);
if (upd->type == CAT_UPD_REM) {
zone_t *zone = knot_zonedb_find(db_old, upd->member);
if (zone != NULL) {
zone_purge(conf, zone);
}
}
catalog_it_next(cat_it);
}
catalog_it_free(cat_it);
int ret = catalog_update_commit(&server->catalog_upd, &server->catalog);
if (ret != KNOT_EOK) {
log_error("catalog, failed to apply changes (%s)", knot_strerror(ret));
@ -526,19 +540,6 @@ static void remove_old_zonedb(conf_t *conf, knot_zonedb_t *db_old,
knot_zonedb_iter_free(it);
catalog_only:
; /* Remove deleted cataloged zones from conf. */
catalog_it_t *cat_it = catalog_it_begin(&server->catalog_upd);
while (!catalog_it_finished(cat_it)) {
catalog_upd_val_t *upd = catalog_it_val(cat_it);
if (upd->type == CAT_UPD_REM) {
zone_t *zone = knot_zonedb_find(db_old, upd->member);
if (zone != NULL) {
zone_purge(conf, zone);
}
}
catalog_it_next(cat_it);
}
catalog_it_free(cat_it);
/* Clear catalog changes. No need to use mutex as this is done from main
* thread while all zone events are paused. */

View file

@ -8,6 +8,7 @@ from dnstest.module import ModOnlineSign
import dnstest.params
import glob
import os
import shutil
from subprocess import DEVNULL, PIPE, Popen
import subprocess
@ -21,6 +22,9 @@ def check_keys(server, zone_name, expect_keys):
if lines != expect_keys:
set_err("CHECK # of KEYS (%d != %d)" % (lines, expect_keys))
def member_zonefile(server, zone):
return server.dir + "/catalog/" + zone + "zone"
t = Test()
master = t.server("knot")
@ -39,8 +43,9 @@ if random.choice([True, False]):
else:
slave.add_module(zone[1], ModOnlineSign(algorithm="ECDSAP256SHA256", single_type_signing=False))
os.mkdir(master.dir + "/catalog")
for zf in glob.glob(t.data_dir + "/*.zone"):
shutil.copy(zf, master.dir + "/master")
shutil.copy(zf, master.dir + "/catalog")
t.start()
@ -60,7 +65,7 @@ resp = master.dig("not-cataloged3.", "SOA")
resp.check(rcode="REFUSED")
# Updating a cataloged zone
subprocess.run(["sed", "-i", "s/10001/10002/;$s/$/\\nxyz A 1.2.3.4/", master.dir + "/master/cataloged1.zone"])
subprocess.run(["sed", "-i", "s/10001/10002/;$s/$/\\nxyz A 1.2.3.4/", member_zonefile(master, "cataloged1.")])
master.ctl("zone-reload cataloged1.")
t.sleep(4)
resp = slave.dig("xyz.cataloged1.", "A", dnssec=True)
@ -116,7 +121,9 @@ up.delete("bar.zones.catalog1.", "PTR", "cataloged2.")
up.add("bar2.zones.catalog1.", 0, "PTR", "cataloged2.")
up.send("NOERROR")
t.sleep(4)
shutil.copy(t.data_dir + "/cataloged2.zone", master.dir + "/master") # because the purge deletes even zonefile
if os.path.exists(member_zonefile(master, "cataloged2.")):
set_err("removed member zone file not purged")
shutil.copy(t.data_dir + "/cataloged2.zone", member_zonefile(master, "cataloged2.")) # because the purge deletes even zonefile
master.ctl("zone-reload cataloged2.")
t.sleep(6)
resp2 = slave.dig("cataloged2.", "DNSKEY")
@ -177,6 +184,8 @@ resp.check(rcode="REFUSED")
resp = slave.dig("cataloged1.", "DNSKEY")
resp.check(rcode="REFUSED")
check_keys(slave, "cataloged1", 0)
if os.path.exists(member_zonefile(master, "cataloged1.")):
set_err("removed member zone file 2 not purged")
# Check restoring catalog from backup
master.ctl("zone-restore +journal +backupdir %s/backup %s" % (master.dir, zone[1].name))

View file

@ -8,6 +8,7 @@ from dnstest.module import ModOnlineSign
import dnstest.params
import glob
import os
import shutil
from subprocess import DEVNULL, PIPE, Popen
import subprocess
@ -32,8 +33,9 @@ t.link(zone, master)
master.cat_interpret(zone)
os.mkdir(master.dir + "/catalog")
for zf in glob.glob(t.data_dir + "/*.zone"):
shutil.copy(zf, master.dir + "/master")
shutil.copy(zf, master.dir + "/catalog")
t.start()
@ -84,7 +86,7 @@ up.delete("group.foo.zones.catalog2.", "TXT")
up.send("NOERROR")
t.sleep(4)
# check that DNSSEC no longer works
with open(master.dir + "/master/cataloged1.zone", "a") as c1zf:
with open(master.dir + "/catalog/cataloged1.zone", "a") as c1zf:
c1zf.write("added A 1.2.3.4")
master.ctl("zone-reload cataloged1.")
t.sleep(4)

View file

@ -26,6 +26,8 @@ catz = t.zone("catalog1.", storage=".")
t.link(catz, knot)
knot.cat_interpret(catz)
os.mkdir(knot.dir + "/catalog")
t.start()
knot.zone_wait(catz, udp=False, tsig=True)
@ -45,7 +47,7 @@ for i in range(UPDATES):
zone_add = "member%d." % i
name_hash = hashlib.md5(zone_add.encode()).hexdigest()
shutil.copyfile(t.data_dir + "generic.zone" , knot.dir + "/master/" + zone_add + "zone")
shutil.copyfile(t.data_dir + "generic.zone" , knot.dir + "/catalog/" + zone_add + "zone")
up = knot.update(catz)
up.add(name_hash + ".zones", 0, "PTR", zone_add)

View file

@ -1500,7 +1500,7 @@ class Knot(Server):
break
if have_catalog is not None:
s.id_item("id", "catalog-default")
s.item_str("file", self.dir + "/master/%s.zone")
s.item_str("file", self.dir + "/catalog/%s.zone")
s.item_str("zonefile-load", "difference")
s.item_str("journal-content", z.journal_content)
@ -1515,13 +1515,13 @@ class Knot(Server):
self.config_xfr(z, s)
s.id_item("id", "catalog-signed")
s.item_str("file", self.dir + "/master/%s.zone")
s.item_str("file", self.dir + "/catalog/%s.zone")
s.item_str("journal-content", z.journal_content)
s.item_str("dnssec-signing", "on")
self.config_xfr(z, s)
s.id_item("id", "catalog-unsigned")
s.item_str("file", self.dir + "/master/%s.zone")
s.item_str("file", self.dir + "/catalog/%s.zone")
s.item_str("journal-content", z.journal_content)
self.config_xfr(z, s)