chg: test: Improve pytest jinja2 templates
Some checks are pending
CodeQL / Analyze (push) Waiting to run
SonarCloud / Build and analyze (push) Waiting to run

- Enable rendering ns-specific data in jinja2 templates using the `ns` varible.
- Add common zone/config snippets an `_common` templates.
- Allow jinja2 imports from `_common`.
- Improve the `_common/controls.conf.j2` snippet to render ns-specific IP rather than hardocded one.

Merge branch 'nicki/pytest-template-improvements' into 'main'

See merge request isc-projects/bind9!11805
This commit is contained in:
Nicki Křížek 2026-05-27 17:54:34 +02:00
commit 67bf433c0f
52 changed files with 218 additions and 113 deletions

View file

@ -1,9 +0,0 @@
key rndc_key {
secret "1234abcd8765";
algorithm @DEFAULT_HMAC@;
};
controls {
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};

View file

@ -0,0 +1,4 @@
{% include "_common/rndc.key" %}
controls {
inet @ns.ip@ port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};

View file

@ -0,0 +1,4 @@
zone "." {
type hint;
file "../../_common/root.hint";
};

View file

@ -0,0 +1,10 @@
{% if zones is defined and zones %}
{% for zone in zones.values() %}
{% if zone.ns.name == ns.name %}
zone "@zone.name@" {
type @zone.type@;
file "@zone.filepath@";
};
{% endif %}
{% endfor %}
{% endif %}

View file

@ -0,0 +1,5 @@
{% if delegations is defined and delegations %}
{% for zone in delegations %}
{% include '_common/zones/ns.partial.db.j2' %}
{% endfor %}
{% endif %}

View file

@ -0,0 +1,2 @@
@zone.name@. NS @zone.ns.name@.@zone.name@.
@zone.ns.name@.@zone.name@. A @zone.ns.ip@

View file

@ -0,0 +1,13 @@
$TTL 300
. IN SOA . a.root.servers.nil. (
2000042100 ; serial
600 ; refresh
600 ; retry
1200 ; expire
600 ; minimum
)
. NS a.root-servers.nil.
a.root-servers.nil. A 10.53.0.1
{% include '_common/zones/delegations.partial.db.j2' %}

View file

@ -0,0 +1,9 @@
$ORIGIN @zone.name@.
$TTL 300
{% raw %}@{% endraw %} IN SOA @zone.ns.name@.@zone.name@. . (
1 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)

View file

@ -0,0 +1,7 @@
{% include '_common/zones/soa.partial.db.j2' %}
{% include '_common/zones/ns.partial.db.j2' %}
{% include '_common/zones/delegations.partial.db.j2' %}
a A 10.0.0.1
b A 10.0.0.2
c A 10.0.0.3

View file

@ -1,2 +1 @@
/ns2/named.conf
/ns2/controls.conf

View file

@ -1 +0,0 @@
../../_common/controls.conf.in

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -10,7 +10,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -10,7 +10,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -10,7 +10,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -13,7 +13,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -19,7 +19,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -13,7 +13,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -9,7 +9,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -9,7 +9,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -9,7 +9,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -12,7 +12,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -19,7 +19,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -12,7 +12,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -21,7 +21,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -8,7 +8,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
zone "." {
type hint;

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {

View file

@ -7,7 +7,7 @@ options {
dnssec-validation no;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
view "internal" {
allow-query-on { any; };

View file

@ -14,7 +14,6 @@ import pytest
pytestmark = pytest.mark.extra_artifacts(
[
"dig.out.*",
"ns2/controls.conf",
]
)

View file

@ -655,3 +655,8 @@ def ns9(servers):
@pytest.fixture(scope="module")
def ns10(servers):
return servers["ns10"]
@pytest.fixture(scope="module")
def ns11(servers):
return servers["ns11"]

View file

@ -11,15 +11,20 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
from dataclasses import dataclass
from dataclasses import dataclass, field
from pathlib import Path
from re import compile as Re
from typing import Any
import re
import jinja2
from .log import debug
from .vars import ALL
NS_DIR_RE = Re(r"^(a?ns([0-9]+))/")
class TemplateEngine:
"""
@ -35,11 +40,29 @@ class TemplateEngine:
self.directory = Path(directory)
self.env_vars = dict(env_vars)
self.j2env = jinja2.Environment(
loader=jinja2.FileSystemLoader(str(self.directory)),
loader=jinja2.ChoiceLoader(
[
jinja2.FileSystemLoader(self.directory),
jinja2.PrefixLoader(
{
"_common": jinja2.FileSystemLoader(
Path(ALL["srcdir"]) / "_common"
),
}
),
]
),
undefined=jinja2.StrictUndefined,
variable_start_string="@",
variable_end_string="@",
trim_blocks=True,
keep_trailing_newline=True,
)
# allow instantiating the template dataclasses in jinja2 templates when
# using {% set %}
self.j2env.globals["Nameserver"] = Nameserver
self.j2env.globals["TrustAnchor"] = TrustAnchor
self.j2env.globals["Zone"] = Zone
def render(
self,
@ -53,18 +76,25 @@ class TemplateEngine:
variables which the engine was initialized with are also filled in. In
case of a variable name clash, `data` has precedence.
"""
available = self.j2env.list_templates()
if template is None:
template = f"{output}.j2.manual"
if not Path(template).is_file():
if template not in available:
template = f"{output}.j2"
if not Path(template).is_file():
raise RuntimeError('No jinja2 template found for "{output}"')
if template not in available:
raise RuntimeError(f'No jinja2 template found for "{output}"')
if data is None:
data = self.env_vars
data = {**self.env_vars}
else:
data = {**self.env_vars, **data}
# directory-specific "ns" var
assert "ns" not in data, '"ns" variable is reserved for nameserver data'
match = NS_DIR_RE.search(output)
if match:
data["ns"] = Nameserver(match.group(1))
debug("rendering template `%s` to file `%s`", template, output)
stream = self.j2env.get_template(template).stream(data)
stream.dump(output, encoding="utf-8")
@ -84,16 +114,48 @@ class TemplateEngine:
@dataclass
class Nameserver:
name: str
ip: str
num: int | None = None
ip: str | None = None
ip6: str | None = None
def __post_init__(self):
if self.num is None:
match = re.search(r"\d+", self.name)
assert match
self.num = int(match.group(0))
if self.ip is None:
self.ip = f"10.53.0.{self.num}"
if self.ip6 is None:
self.ip6 = f"fd92:7065:b8e:ffff::{self.num}"
NS1 = Nameserver("ns1")
NS2 = Nameserver("ns2")
NS3 = Nameserver("ns3")
NS4 = Nameserver("ns4")
NS5 = Nameserver("ns5")
NS6 = Nameserver("ns6")
NS7 = Nameserver("ns7")
NS8 = Nameserver("ns8")
NS9 = Nameserver("ns9")
NS10 = Nameserver("ns10")
NS11 = Nameserver("ns11")
@dataclass
class Zone:
name: str
filename: str
ns: Nameserver
type: str = "primary"
filepath: Path | None = field(default=None)
def __post_init__(self) -> None:
if self.filepath is None:
base = "root" if self.name == "." else self.name
self.filepath = Path(f"zones/{base}.db")
@dataclass

View file

@ -1 +0,0 @@
../../_common/controls.conf.in

View file

@ -14,7 +14,7 @@ options {
sig-signing-signatures 900;
};
include "controls.conf";
{% include "_common/controls.conf.j2" %}
dnssec-policy "optout" {
keys {

View file

@ -34,7 +34,6 @@ pytestmark = [
"ns2/*.signed",
"ns2/*.jnl",
"ns2/*.jbk",
"ns2/controls.conf",
"ns2/dsset-*",
"ns2/K*",
]

View file

@ -9,11 +9,13 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
from pathlib import Path
import shutil
from isctest.kasp import SettimeOptions, private_type_record
from isctest.run import EnvCmd
from isctest.template import Nameserver, TrustAnchor, Zone
from isctest.template import NS2, NS3, TrustAnchor, Zone
from isctest.vars.algorithms import Algorithm
import isctest
@ -50,7 +52,7 @@ def configure_tld(zonename: str, delegations: list[Zone]) -> Zone:
templates.render(f"ns2/{outfile}", tdata, template=f"ns2/{template}")
signer(f"-P -x -O full -o {zonename} -f {outfile}.signed {outfile}", cwd="ns2")
return Zone(zonename, f"{outfile}.signed", Nameserver("ns2", "10.53.0.2"))
return Zone(zonename, NS2, filepath=Path(f"{outfile}.signed"))
def configure_root(delegations: list[Zone]) -> TrustAnchor:
@ -150,7 +152,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> list[Zo
# Step 1:
# Introduce the first key. This will immediately be active.
zonename = f"step1.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
TactN = "now-7d"
TsbmN = "now-161h"
@ -173,7 +175,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> list[Zo
# Step 2:
# After the publication interval has passed the DNSKEY is OMNIPRESENT.
zonename = f"step2.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The time passed since the new algorithm keys have been introduced is 3 hours.
TpubN1 = "now-3h"
@ -205,7 +207,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> list[Zo
# Step 3:
# The zone signatures are also OMNIPRESENT.
zonename = f"step3.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The time passed since the new algorithm keys have been introduced is 7 hours.
TpubN1 = "now-7h"
@ -238,7 +240,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> list[Zo
# Step 4:
# The DS is swapped and can become OMNIPRESENT.
zonename = f"step4.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The time passed since the DS has been swapped is 3 hours.
TpubN1 = "now-10h"
@ -273,7 +275,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> list[Zo
# Step 5:
# The DNSKEY is removed long enough to be HIDDEN.
zonename = f"step5.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The time passed since the DNSKEY has been removed is 2 hours.
TpubN1 = "now-12h"
@ -306,7 +308,7 @@ def configure_algo_csk(tld: str, policy: str, reconfig: bool = False) -> list[Zo
# Step 6:
# The RRSIGs have been removed long enough to be HIDDEN.
zonename = f"step6.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Additional time passed: 7h.
TpubN1 = "now-19h"
@ -349,7 +351,7 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> list[Zone]:
# Step 1:
# Introduce the first key. This will immediately be active.
zonename = f"step1.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
TactN = "now-7d"
TsbmN = "now-161h"
@ -380,7 +382,7 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> list[Zone]:
# Step 2:
# After the publication interval has passed the DNSKEY is OMNIPRESENT.
zonename = f"step2.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The time passed since the new algorithm keys have been introduced is 3 hours.
# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h
@ -436,7 +438,7 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> list[Zone]:
# Step 3:
# The zone signatures are also OMNIPRESENT.
zonename = f"step3.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The time passed since the new algorithm keys have been introduced is 7 hours.
TpubN1 = "now-7h"
@ -491,7 +493,7 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> list[Zone]:
# Step 4:
# The DS is swapped and can become OMNIPRESENT.
zonename = f"step4.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The time passed since the DS has been swapped is 3 hours.
TpubN1 = "now-10h"
@ -548,7 +550,7 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> list[Zone]:
# Step 5:
# The DNSKEY is removed long enough to be HIDDEN.
zonename = f"step5.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The time passed since the DNSKEY has been removed is 2 hours.
TpubN1 = "now-12h"
@ -603,7 +605,7 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> list[Zone]:
# Step 6:
# The RRSIGs have been removed long enough to be HIDDEN.
zonename = f"step6.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Additional time passed: 7h.
TpubN1 = "now-19h"
@ -668,7 +670,7 @@ def configure_cskroll1(tld: str, policy: str) -> list[Zone]:
# Step 1:
# Introduce the first key. This will immediately be active.
zonename = f"step1.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
TactN = "now-7d"
keytimes = f"-P {TactN} -A {TactN}"
@ -689,7 +691,7 @@ def configure_cskroll1(tld: str, policy: str) -> list[Zone]:
# Step 2:
# It is time to introduce the new CSK.
zonename = f"step2.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
# KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC
@ -726,7 +728,7 @@ def configure_cskroll1(tld: str, policy: str) -> list[Zone]:
# Step 3:
# It is time to submit the DS and to roll signatures.
zonename = f"step3.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
#
@ -800,7 +802,7 @@ def configure_cskroll1(tld: str, policy: str) -> list[Zone]:
# (which is 26d3h). The DS is swapped after Iret (which is 4h).
# In other words, the DS is swapped before all zone signatures are replaced.
zonename = f"step4.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
# Trem(N) = Tret(N) - Iret + IretZ
@ -862,7 +864,7 @@ def configure_cskroll1(tld: str, policy: str) -> list[Zone]:
# After the DS is swapped in step 4, also the KRRSIG records can be removed.
# At this time these have all become hidden.
zonename = f"step5.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
TpubN = "now-4470h"
@ -906,7 +908,7 @@ def configure_cskroll1(tld: str, policy: str) -> list[Zone]:
# After the retire interval has passed the predecessor DNSKEY can be
# removed from the zone.
zonename = f"step6.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
# Trem(N) = Tret(N) + IretZ
@ -965,7 +967,7 @@ def configure_cskroll1(tld: str, policy: str) -> list[Zone]:
# Step 7:
# Some time later the predecessor DNSKEY enters the HIDDEN state.
zonename = f"step7.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h).
TpubN = "now-5093h"
@ -1008,7 +1010,7 @@ def configure_cskroll1(tld: str, policy: str) -> list[Zone]:
# Step 8:
# The predecessor DNSKEY can be purged.
zonename = f"step8.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract purge-keys interval from all the times (1h).
TpubN = "now-5094h"
@ -1064,7 +1066,7 @@ def configure_cskroll2(tld: str, policy: str) -> list[Zone]:
# Step 1:
# Introduce the first key. This will immediately be active.
zonename = f"step1.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
TactN = "now-7d"
keytimes = f"-P {TactN} -A {TactN}"
@ -1085,7 +1087,7 @@ def configure_cskroll2(tld: str, policy: str) -> list[Zone]:
# Step 2:
# It is time to introduce the new CSK.
zonename = f"step2.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
# KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC
@ -1122,7 +1124,7 @@ def configure_cskroll2(tld: str, policy: str) -> list[Zone]:
# Step 3:
# It is time to submit the DS and to roll signatures.
zonename = f"step3.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
#
@ -1196,7 +1198,7 @@ def configure_cskroll2(tld: str, policy: str) -> list[Zone]:
# The DS is swapped after Dreg + Iret (1w3h). In other words, the zone
# signatures are replaced before the DS is swapped.
zonename = f"step4.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
# Trem(N) = Tret(N) + IretZ
@ -1260,7 +1262,7 @@ def configure_cskroll2(tld: str, policy: str) -> list[Zone]:
# Some time later the DS can be swapped and the old DNSKEY can be removed from
# the zone.
zonename = f"step5.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract Iret (170h) - IretZ (38h) = 132h.
#
@ -1314,7 +1316,7 @@ def configure_cskroll2(tld: str, policy: str) -> list[Zone]:
# Step 6:
# Some time later the predecessor DNSKEY enters the HIDDEN state.
zonename = f"step6.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract DNSKEY TTL plus zone propagation delay (2h).
#
@ -1366,7 +1368,7 @@ def configure_cskroll2(tld: str, policy: str) -> list[Zone]:
# Step 7:
# The predecessor DNSKEY can be purged, but purge-keys is disabled.
zonename = f"step7.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract 90 days (default, 2160h) from all the times.
#
@ -1419,7 +1421,7 @@ def configure_cskroll2(tld: str, policy: str) -> list[Zone]:
# Step 8:
# The predecessor DNSKEY can be purged.
zonename = f"step8.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract purge-keys interval from all the times (1h).
TpubN = "now-5094h"
@ -1473,14 +1475,14 @@ def configure_enable_dnssec(tld: str, policy: str) -> list[Zone]:
# This is an unsigned zone and named should perform the initial steps of
# introducing the DNSSEC records in the right order.
zonename = f"step1.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
render_and_sign_zone(zonename, [], signing=False)
# Step 2:
# The DNSKEY has been published long enough to become OMNIPRESENT.
zonename = f"step2.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# DNSKEY TTL: 300 seconds
# zone-propagation-delay: 5 minutes (300 seconds)
@ -1505,7 +1507,7 @@ def configure_enable_dnssec(tld: str, policy: str) -> list[Zone]:
# Step 3:
# The zone signatures have been published long enough to become OMNIPRESENT.
zonename = f"step3.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Passed time since publication:
# max-zone-ttl: 12 hours (43200 seconds)
@ -1530,7 +1532,7 @@ def configure_enable_dnssec(tld: str, policy: str) -> list[Zone]:
# Step 4:
# The DS has been submitted long enough ago to become OMNIPRESENT.
zonename = f"step4.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# DS TTL: 2 hour (7200 seconds)
# parent-propagation-delay: 1 hour (3600 seconds)
@ -1568,7 +1570,7 @@ def configure_going_insecure(tld: str, reconfig: bool = False) -> list[Zone]:
# Step 1:
zonename = f"step1.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Timing metadata.
TpubN = "now-10d"
@ -1600,9 +1602,7 @@ def configure_going_insecure(tld: str, reconfig: bool = False) -> list[Zone]:
if reconfig:
# Step 2:
zonename = f"step2.{zone}"
zones.append(
Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))
)
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# The DS was withdrawn from the parent zone 26 hours ago.
TremN = "now-26h"
@ -1647,7 +1647,7 @@ def configure_straight2none(tld: str) -> list[Zone]:
keytimes = f"-P {TpubN} -A {TpubN} -P sync {TsbmN}"
zonename = f"going-straight-to-none.{tld}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Key generation.
csk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
@ -1664,9 +1664,7 @@ def configure_straight2none(tld: str) -> list[Zone]:
render_and_sign_zone(zonename, [csk_name], extra_options="-z")
zonename = f"going-straight-to-none-dynamic.{tld}"
zones.append(
Zone(zonename, f"{zonename}.db.signed", Nameserver("ns3", "10.53.0.3"))
)
zones.append(Zone(zonename, NS3, filepath=Path(f"{zonename}.db.signed")))
isctest.log.info(f"setup {zonename}")
# Key generation.
csk_name = keygen(f"-f KSK {keytimes} {zonename}", cwd="ns3").out.strip()
@ -1696,7 +1694,7 @@ def configure_ksk_doubleksk(tld: str) -> list[Zone]:
# Step 1:
# Introduce the first key. This will immediately be active.
zonename = f"step1.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Timing metadata.
TactN = "now-7d"
@ -1724,7 +1722,7 @@ def configure_ksk_doubleksk(tld: str) -> list[Zone]:
# Step 2:
# It is time to introduce the new KSK.
zonename = f"step2.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Lksk: 60d
# Dreg: n/a
@ -1766,7 +1764,7 @@ def configure_ksk_doubleksk(tld: str) -> list[Zone]:
# Step 3:
# It is time to submit the DS.
zonename = f"step3.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
# Iret = DprpP + TTLds (+retire-safety)
@ -1829,7 +1827,7 @@ def configure_ksk_doubleksk(tld: str) -> list[Zone]:
# Step 4:
# The DS should be swapped now.
zonename = f"step4.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Tpub(N) = now - Lksk - Iret = now - 60d - 50h
# = now - 1440h - 50h = now - 1490h
@ -1891,7 +1889,7 @@ def configure_ksk_doubleksk(tld: str) -> list[Zone]:
# Step 5:
# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
zonename = f"step5.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h).
# Tpub(N) = now - 1490h - 3h = now - 1493h
@ -1950,7 +1948,7 @@ def configure_ksk_doubleksk(tld: str) -> list[Zone]:
# Step 6:
# The predecessor DNSKEY can be purged.
zonename = f"step6.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract purge-keys interval from all the times (1h).
TpubN = "now-1494h"
@ -2019,7 +2017,7 @@ def configure_ksk_3crowd(tld: str) -> list[Zone]:
# Set up a zone that has a KSK (KEY1) and have the successor key (KEY2)
# published as well.
zonename = f"three-is-a-crowd.{tld}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# These times are the same as step3.ksk-doubleksk.autosign.
TpubN = "now-60d"
@ -2080,7 +2078,7 @@ def configure_zsk_prepub(tld: str) -> list[Zone]:
# Step 1:
# Introduce the first key. This will immediately be active.
zonename = f"step1.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Timing metadata.
TactN = "now-7d"
@ -2108,7 +2106,7 @@ def configure_zsk_prepub(tld: str) -> list[Zone]:
# Step 2:
# It is time to pre-publish the successor ZSK.
zonename = f"step2.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
# Tact(N) = now + Ipub - Lzsk = now + 26h - 30d
@ -2139,7 +2137,7 @@ def configure_zsk_prepub(tld: str) -> list[Zone]:
# After the publication interval has passed the DNSKEY of the successor ZSK
# is OMNIPRESENT and the zone can thus be signed with the successor ZSK.
zonename = f"step3.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# According to RFC 7583:
# Tpub(N+1) <= Tact(N) + Lzsk - Ipub
@ -2190,7 +2188,7 @@ def configure_zsk_prepub(tld: str) -> list[Zone]:
# After the retire interval has passed the predecessor DNSKEY can be
# removed from the zone.
zonename = f"step4.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Lzsk: 30d
# Ipub: 26h
@ -2249,7 +2247,7 @@ def configure_zsk_prepub(tld: str) -> list[Zone]:
# Step 5:
# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
zonename = f"step5.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract DNSKEY TTL + zone-propagation-delay from all the times (2h).
# Tact(N) = now - 961h - 2h = now - 963h
@ -2296,7 +2294,7 @@ def configure_zsk_prepub(tld: str) -> list[Zone]:
# Step 6:
# The predecessor DNSKEY can be purged.
zonename = f"step6.{zone}"
zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
zones.append(Zone(zonename, NS3))
isctest.log.info(f"setup {zonename}")
# Subtract purge-keys interval from all the times (1h).
TactN = "now-964h"

View file

@ -19,7 +19,7 @@ from isctest.kasp import (
private_type_record,
)
from isctest.run import EnvCmd
from isctest.template import Nameserver, Zone
from isctest.template import NS3, Zone
from isctest.vars.algorithms import Algorithm
from rollover.setup import configure_root, configure_tld, setkeytimes
@ -67,7 +67,7 @@ def setup_zone(zone, ksk_time, ksk_timings, zsk_time, zsk_timings) -> Zone:
templates.render(f"ns3/{outfile}", tdata, template=f"ns3/{template}")
signer(f"-P -x -O raw -o {zone} -f {outfile}.signed {outfile}", cwd="ns3")
return Zone(zone, outfile, Nameserver("ns3", "10.53.0.3"))
return Zone(zone, NS3)
def bootstrap():

View file

@ -1,4 +1,4 @@
{% for i in range(4096) %}
name@i@ 259200 A 1.2.3.4
name@i@ 259200 TXT "Hello World @i@"
{%- endfor %}
{% endfor %}