return msg
-def wait_for_serial(server_ip, zone, expected_serial, timeout=30):
- """Wait until the server has the expected SOA serial for the zone.
-
- Queries the server repeatedly until the SOA serial matches or the
- timeout expires.
+def get_soa_serial(server_ip, zone, timeout=10):
+ """
+ Get the current SOA serial of a zone from a server.
- 'server_ip' is the IP address to query (string).
- 'zone' is the zone name (string, with or without trailing dot).
- 'expected_serial' is the expected SOA serial number (int).
- 'timeout' is the maximum time to wait in seconds (default 30).
+ Queries the server repeatedly until it responds with a well-formed
+ SOA answer or the timeout expires.
"""
query = create(zone, "SOA", dnssec=False)
+ serial = None
def check():
- res = tcp(query, server_ip)
+ nonlocal serial
+ res = tcp(
+ query,
+ server_ip,
+ timeout=3,
+ attempts=1,
+ expected_rcode=dns.rcode.NOERROR,
+ )
soa = res.get_rrset(
res.answer,
dns.name.from_text(zone),
dns.rdataclass.IN,
dns.rdatatype.SOA,
)
- return soa is not None and len(soa) == 1 and soa[0].serial == expected_serial
+ assert soa is not None and len(soa) == 1
+ serial = soa[0].serial
+ return True
+
+ isctest.run.retry_with_timeout(
+ check,
+ timeout=timeout,
+ msg=f"timed out getting SOA serial of {zone} from {server_ip}",
+ )
+ return serial
+
+
+def wait_for_serial(server_ip, zone, expected_serial, timeout=30):
+ """
+ Wait until the server has the expected SOA serial for the zone.
+
+ Queries the server repeatedly until the SOA serial matches or the
+ timeout expires.
+ """
+
+ def check():
+ return get_soa_serial(server_ip, zone) == expected_serial
isctest.run.retry_with_timeout(
check,
import os
-import dns.name
-import dns.rcode
-import dns.rdataclass
-import dns.rdatatype
import dns.update
import pytest
), "dnssec record found in journal"
-def get_soa_serial(server, zone):
- fqdn = f"{zone}."
- query = isctest.query.create(fqdn, dns.rdatatype.SOA)
- response = isctest.query.tcp(
- query, server.ip, server.ports.dns, timeout=3, attempts=1
- )
- assert response.rcode() == dns.rcode.NOERROR
- soa = response.get_rrset(
- response.answer,
- dns.name.from_text(fqdn),
- dns.rdataclass.IN,
- dns.rdatatype.SOA,
- )
- assert soa is not None and len(soa) == 1
- return soa[0].serial
-
-
def wait_for_serial(primary, server, zone, previous_serial=None):
if primary.identifier == server.identifier:
assert previous_serial is not None
def check_prev_serial():
- return get_soa_serial(server, zone) != previous_serial
+ return isctest.query.get_soa_serial(server.ip, zone) != previous_serial
isctest.run.retry_with_timeout(check_prev_serial, timeout=30)
return
def check_serial():
- serial1 = get_soa_serial(primary, zone)
- serial2 = get_soa_serial(server, zone)
+ serial1 = isctest.query.get_soa_serial(primary.ip, zone)
+ serial2 = isctest.query.get_soa_serial(server.ip, zone)
return (
f"zone {zone}/IN (signed): serial {serial2} (unsigned {serial1})"
def nsupdate_and_wait(primary, server, zone, update_msg):
previous_serial = None
if primary.identifier == server.identifier:
- previous_serial = get_soa_serial(server, zone)
+ previous_serial = isctest.query.get_soa_serial(server.ip, zone)
primary.nsupdate(update_msg)
wait_for_serial(primary, server, zone, previous_serial)