mirror of
https://gitlab.nic.cz/knot/knot-dns.git
synced 2026-05-28 04:02:31 -04:00
conf: allow empty value for some zone items (references to remotes)
This allows overriding of corresponding non-empty template items.
This commit is contained in:
parent
4930ccf99e
commit
4784c4c601
6 changed files with 82 additions and 4 deletions
|
|
@ -2604,6 +2604,7 @@ master
|
|||
An ordered list of references :ref:`remote<remote_id>` and
|
||||
:ref:`remotes<remotes_id>` to zone primary servers
|
||||
(formerly known as master servers).
|
||||
Empty value is allowed for template value overriding.
|
||||
|
||||
*Default:* not set
|
||||
|
||||
|
|
@ -2630,6 +2631,7 @@ notify
|
|||
An ordered list of references :ref:`remote<remote_id>` and
|
||||
:ref:`remotes<remotes_id>` to secondary servers to which notify
|
||||
message is sent if the zone changes.
|
||||
Empty value is allowed for template value overriding.
|
||||
|
||||
*Default:* not set
|
||||
|
||||
|
|
@ -2933,7 +2935,7 @@ ds-push
|
|||
-------
|
||||
|
||||
Per zone configuration of :ref:`policy_ds-push`. This option overrides possible
|
||||
per policy option.
|
||||
per policy option. Empty value is allowed for template value overriding.
|
||||
|
||||
*Default:* not set
|
||||
|
||||
|
|
|
|||
|
|
@ -191,6 +191,10 @@ conf_val_t conf_zone_get_txn(
|
|||
conf_db_get(conf, txn, C_ZONE, key1_name, dname, dname_size, &val);
|
||||
switch (val.code) {
|
||||
case KNOT_EOK:
|
||||
if (val.blob_len == 1 && (val.item->flags & CONF_REF_EMPTY)) {
|
||||
static const conf_val_t empty = { .code = KNOT_ENOENT };
|
||||
return empty;
|
||||
}
|
||||
return val;
|
||||
default:
|
||||
CONF_LOG_ZONE(LOG_ERR, dname, "failed to read '%s/%s' (%s)",
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#define CONF_IO_FRLD_MOD YP_FUSR8 /*!< Reload global modules. */
|
||||
#define CONF_IO_FRLD_ZONE YP_FUSR9 /*!< Reload a specific zone. */
|
||||
#define CONF_IO_FRLD_ZONES YP_FUSR10 /*!< Reload all zones. */
|
||||
#define CONF_REF_EMPTY YP_FUSR11 /*!< Allow empty reference value for zone item. */
|
||||
#define CONF_IO_FRLD_ALL (CONF_IO_FRLD_SRV | CONF_IO_FRLD_LOG | \
|
||||
CONF_IO_FRLD_MOD | CONF_IO_FRLD_ZONES)
|
||||
|
||||
|
|
|
|||
|
|
@ -454,9 +454,11 @@ static const yp_item_t desc_policy[] = {
|
|||
#define ZONE_ITEMS(FLAGS) \
|
||||
{ C_STORAGE, YP_TSTR, YP_VSTR = { STORAGE_DIR }, FLAGS }, \
|
||||
{ C_FILE, YP_TSTR, YP_VNONE, FLAGS }, \
|
||||
{ C_MASTER, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI, { check_ref } }, \
|
||||
{ C_MASTER, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI | CONF_REF_EMPTY, \
|
||||
{ check_ref } }, \
|
||||
{ C_DDNS_MASTER, YP_TREF, YP_VREF = { C_RMT }, YP_FNONE, { check_ref_empty } }, \
|
||||
{ C_NOTIFY, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI, { check_ref } }, \
|
||||
{ C_NOTIFY, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI | CONF_REF_EMPTY, \
|
||||
{ check_ref } }, \
|
||||
{ C_ACL, YP_TREF, YP_VREF = { C_ACL }, YP_FMULTI, { check_ref } }, \
|
||||
{ C_MASTER_PIN_TOL, YP_TINT, YP_VINT = { 0, UINT32_MAX, 0, YP_STIME } }, \
|
||||
{ C_PROVIDE_IXFR, YP_TBOOL, YP_VBOOL = { true } }, \
|
||||
|
|
@ -474,7 +476,7 @@ static const yp_item_t desc_policy[] = {
|
|||
{ C_DNSSEC_SIGNING, YP_TBOOL, YP_VNONE, FLAGS }, \
|
||||
{ C_DNSSEC_VALIDATION, YP_TBOOL, YP_VNONE, FLAGS }, \
|
||||
{ C_DNSSEC_POLICY, YP_TREF, YP_VREF = { C_POLICY }, FLAGS, { check_ref_dflt } }, \
|
||||
{ C_DS_PUSH, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI | FLAGS, \
|
||||
{ C_DS_PUSH, YP_TREF, YP_VREF = { C_RMT, C_RMTS }, YP_FMULTI | CONF_REF_EMPTY | FLAGS, \
|
||||
{ check_ref } }, \
|
||||
{ C_REVERSE_GEN, YP_TDNAME,YP_VNONE, FLAGS | CONF_IO_FRLD_ZONES }, \
|
||||
{ C_SERIAL_POLICY, YP_TOPT, YP_VOPT = { serial_policies, SERIAL_POLICY_INCREMENT } }, \
|
||||
|
|
|
|||
|
|
@ -236,6 +236,13 @@ int check_ref(
|
|||
|
||||
bool found1 = false, found2 = false;
|
||||
|
||||
// Check if allowed empty value for specific zone items.
|
||||
if (args->data_len == 1 && (args->item->flags & CONF_REF_EMPTY) &&
|
||||
args->item->parent->name[0] == C_ZONE[0] &&
|
||||
memcmp(&args->item->parent->name[1], &C_ZONE[1], C_ZONE[0]) == 0) {
|
||||
return KNOT_EOK;
|
||||
}
|
||||
|
||||
// Try to find the id in the first section.
|
||||
found1 = conf_rawid_exists_txn(args->extra->conf, args->extra->txn,
|
||||
ref->name, args->data, args->data_len);
|
||||
|
|
|
|||
62
tests-extra/tests/config/template/test.py
Normal file
62
tests-extra/tests/config/template/test.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
'''Test for configuration zone templates'''
|
||||
|
||||
import os
|
||||
|
||||
from dnstest.libknot import libknot
|
||||
from dnstest.test import Test
|
||||
|
||||
t = Test()
|
||||
|
||||
master = t.server("knot")
|
||||
slave = t.server("knot")
|
||||
zones = t.zone_rnd(2, records=5, dnssec=False)
|
||||
for z in zones:
|
||||
z.name = z.name.lower()
|
||||
|
||||
t.link(zones, master, slave, ixfr=True)
|
||||
|
||||
ctl = libknot.control.KnotCtl()
|
||||
|
||||
t.start()
|
||||
|
||||
serials_init = master.zones_wait(zones)
|
||||
slave.zones_wait(zones)
|
||||
|
||||
ctl.connect(os.path.join(master.dir, "knot.sock"))
|
||||
ctl.send_block(cmd="conf-begin")
|
||||
resp = ctl.receive_block()
|
||||
|
||||
# Move notify setting from zones to the default template.
|
||||
ctl.send_block(cmd="conf-get", section="zone", item="notify", identifier=zones[0].name)
|
||||
resp = ctl.receive_block()
|
||||
for val in resp['zone'][zones[0].name]['notify']:
|
||||
ctl.send_block(cmd="conf-set", section="template", identifier="default", item="notify", data=val)
|
||||
resp = ctl.receive_block()
|
||||
ctl.send_block(cmd="conf-unset", section="zone", item="notify")
|
||||
resp = ctl.receive_block()
|
||||
|
||||
# Override template setting with the default (none) for the first zone.
|
||||
ctl.send_block(cmd="conf-set", section="zone", item="notify", identifier=zones[0].name, data="")
|
||||
resp = ctl.receive_block()
|
||||
|
||||
ctl.send_block(cmd="conf-commit")
|
||||
resp = ctl.receive_block()
|
||||
ctl.send(libknot.control.KnotCtlType.END)
|
||||
ctl.close()
|
||||
|
||||
# Modify the zones and check that notify doesn't work for the first zone.
|
||||
serials_prev = serials_init
|
||||
serial1 = serials_init[zones[0].name]
|
||||
for i in range(2):
|
||||
for zone in zones:
|
||||
master.update_zonefile(zone, random=True)
|
||||
master.ctl('zone-reload')
|
||||
|
||||
serials_prev = master.zones_wait(zones, serials_prev)
|
||||
slave.zone_wait(zones[1], serials_prev[zones[1].name], equal=True, greater=False)
|
||||
t.sleep(1)
|
||||
slave.zone_wait(zones[0], serial1, equal=True, greater=False)
|
||||
|
||||
t.end()
|
||||
Loading…
Reference in a new issue