Skip to content

Commit 50d445b

Browse files
committed
Various updates.
- Merges in the ixfr-out and full-signer-update-state branches as these were needed for local testing, but should be obsoleted / synced with main when PRs #631 ("Save last serial and key tags in zone state")and #605 ("Add IXFR out support") get merged. - Extends the persist-restore system test to cover more cases. Should perhaps be split out into separate smaller tests. - Actually adds restored diffs to the zone storage to be served by IXFR out. Will need updating to match the changes/fixes that have since been made in PR #605. - Fixes an issue where persisted diffs from multiple SOA serials, e.g. 1..2..3 would be condensed on restore so that only a single IXFR diff from 1..3 would be available instead of two diffs from 1..2 and 2..3 being available. - Clears the set of known persisted data file paths for a zone if any of those files are missing or cannot be parsed during restoration.
1 parent 0887919 commit 50d445b

14 files changed

Lines changed: 844 additions & 120 deletions

File tree

crates/zonedata/src/diff.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{RegularRecord, SoaRecord};
1919
/// [`DiffData`] can be used to store the data for an old zone (where it is the
2020
/// base, and the next newer zone is the target). This is perfect for serving
2121
/// IXFR requests.
22-
#[derive(Clone, Default)]
22+
#[derive(Clone, Debug, Default)]
2323
pub struct DiffData {
2424
/// The SOA record to remove.
2525
///

crates/zonedata/src/restorer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ impl SignedZoneRestorer {
469469
.find(|inst| inst.soa.is_some())
470470
.map(|inst| SignedZoneReader::new(curr_loaded, inst))
471471
}
472+
473+
/// The diff from the preceding signed instance to the current one.
474+
pub fn take_diff(&mut self) -> Option<Box<DiffData>> {
475+
self.diff.take()
476+
}
472477
}
473478

474479
impl SignedZoneRestorer {

integration-tests/scripts/manage-test-environment.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,7 @@ pattern:
298298
name: secondary
299299
zonefile: "%s.secondary-zone"
300300
allow-notify: 127.0.0.1 NOKEY
301-
# Until Cascade supports IXFR we always use AXFR
302-
request-xfr: AXFR 127.0.0.1@${_cascade_port} NOKEY
301+
request-xfr: 127.0.0.1@${_cascade_port} NOKEY
303302
provide-xfr: 127.0.0.1 NOKEY
304303
305304
zone:

integration-tests/system-tests.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,21 @@ jobs:
166166
with:
167167
log-level: ${{ inputs.log-level }}
168168

169+
ixfr-out:
170+
name: Serve a zone via IXFR to the NSD secondary.
171+
runs-on: ubuntu-latest
172+
strategy:
173+
matrix:
174+
rust: [stable]
175+
steps:
176+
- uses: actions/checkout@v4
177+
- uses: ./.github/actions/set-build-profile
178+
with:
179+
build-profile: ${{ inputs.build-profile }}
180+
- uses: ./integration-tests/tests/ixfr-out
181+
with:
182+
log-level: ${{ inputs.log-level }}
183+
169184
incremental-signing:
170185
name: Test incremental signing.
171186
runs-on: ubuntu-latest
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Making reusable composite actions documented at
2+
# https://docs.github.com/en/actions/tutorials/create-actions/create-a-composite-action#creating-a-composite-action-within-the-same-repository
3+
name: 'Serve a zone via IXFR to the NSD secondary.'
4+
description: 'Serve a zone via IXFR to the NSD secondary.'
5+
defaults:
6+
# see: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#defaultsrunshell
7+
run:
8+
shell: bash --noprofile --norc -eo pipefail -x {0}
9+
inputs:
10+
log-level:
11+
description: The level of logging that Cascade should output.
12+
required: false
13+
default: debug
14+
type: choice
15+
options:
16+
- error
17+
- warning
18+
- info
19+
- debug
20+
- trace
21+
runs:
22+
using: "composite"
23+
steps:
24+
- uses: ./.github/actions/prepare-systest-env
25+
- uses: ./.github/actions/setup-and-start-cascade
26+
with:
27+
log-level: ${{ inputs.log-level }}
28+
29+
- name: Add a NOTIFY with TSIG outbound policy
30+
run: |
31+
POLICY_DIR=$(integration-tests/scripts/get-default-path.sh policy-dir)
32+
cascade template policy | grep -Ev '(send-notify-to|accept-xfr-from)' > "${POLICY_DIR}/custom.toml"
33+
34+
sed -i -e 's/serial-policy = "date-counter"/serial-policy = "keep"/' "${POLICY_DIR}/custom.toml"
35+
echo 'send-notify-to = ["127.0.0.1:1054"]' >> "${POLICY_DIR}/custom.toml"
36+
37+
# TODO: Extend the test to use TSIG (driven by inputs ala the tsig-downstream test)
38+
# once PRs #564 and #587 have been merged.
39+
# echo 'send-notify-to = ["127.0.0.1:1054^tsig-key"]' >> "${POLICY_DIR}/custom.toml"
40+
# cascade tsig add tsig-key hmac-sha256 "COzoVsYQmXeXiyq1Quhp0bbVnMyxjPxsaGSoIWR98i0="
41+
cascade policy reload
42+
43+
- name: Make an initial zone based on RFC 1995 section 7
44+
run: |
45+
tee example.test.zone <<'EOF'
46+
EXAMPLE.TEST. IN SOA NS.EXAMPLE.TEST. mail.example.test. (
47+
1 60 60 3600 5)
48+
IN NS NS.EXAMPLE.TEST.
49+
NS.EXAMPLE.TEST. IN A 133.69.136.1
50+
NEZU.EXAMPLE.TEST. IN A 133.69.136.5
51+
EOF
52+
53+
- name: Add the zone using the custom policy
54+
run: |
55+
cascade zone add --policy custom --source $PWD/example.test.zone example.test
56+
57+
- name: Check zone status
58+
run: |
59+
timeout=10 # seconds
60+
start=$(date +%s)
61+
until cascade zone status example.test | grep -q "Published zone available"; do
62+
if (($(date +%s) > (start + timeout))); then
63+
cascade zone status example.test
64+
echo "timeout: zone status did not report published zone available" >&2
65+
exit 1
66+
fi
67+
sleep 1
68+
done
69+
70+
- name: Check the SOA SERIAL at the NSD secondary
71+
run: |
72+
timeout=10 # seconds
73+
start=$(date +%s)
74+
until dig +short @127.0.0.1 -p 1054 example.test SOA | grep -q 'ns.example.test. mail.example.test. 1 60 60 3600 5'; do
75+
if (($(date +%s) > (start + timeout))); then
76+
cascade zone status example.test
77+
dig +short @127.0.0.1 -p 1054 example.test SOA
78+
echo "::error:: timeout: NSD did not acquire the zone changes"
79+
exit 1
80+
fi
81+
sleep 1
82+
done
83+
84+
- name: Edit the source zone and tell Cascade to reload it.
85+
run: |
86+
tee example.test.zone <<'EOF'
87+
example.test. IN SOA ns.example.test. mail.example.test. (
88+
2 60 60 3600 5)
89+
IN NS NS.EXAMPLE.TEST.
90+
NS.EXAMPLE.TEST. IN A 133.69.136.1
91+
JAIN-BB.EXAMPLE.TEST. IN A 133.69.136.4
92+
IN A 192.41.197.2
93+
EOF
94+
cascade zone reload example.test
95+
96+
- name: Check zone status
97+
run: |
98+
timeout=10 # seconds
99+
start=$(date +%s)
100+
until cascade zone status example.test | grep -q "Published zone available"; do
101+
if (($(date +%s) > (start + timeout))); then
102+
cascade zone status example.test
103+
echo "timeout: zone status did not report published zone available" >&2
104+
exit 1
105+
fi
106+
sleep 1
107+
done
108+
109+
- name: Check the SOA SERIAL at the NSD secondary
110+
run: |
111+
timeout=10 # seconds
112+
start=$(date +%s)
113+
until dig +short @127.0.0.1 -p 1054 example.test SOA | grep -q 'ns.example.test. mail.example.test. 2 60 60 3600 5'; do
114+
if (($(date +%s) > (start + timeout))); then
115+
cascade zone status example.test
116+
dig +short @127.0.0.1 -p 1054 example.test SOA
117+
echo "::error:: timeout: NSD did not acquire the zone changes"
118+
exit 1
119+
fi
120+
sleep 1
121+
done
122+
123+
- name: Edit the source zone and tell Cascade to reload it.
124+
run: |
125+
tee example.test.zone <<'EOF'
126+
EXAMPLE.TEST. IN SOA ns.example.test. mail.example.test. (
127+
3 60 60 3600 5)
128+
IN NS NS.EXAMPLE.TEST.
129+
NS.EXAMPLE.TEST. IN A 133.69.136.1
130+
JAIN-BB.EXAMPLE.TEST. IN A 133.69.136.3
131+
IN A 192.41.197.2
132+
EOF
133+
cascade zone reload example.test
134+
135+
- name: Check zone status
136+
run: |
137+
timeout=10 # seconds
138+
start=$(date +%s)
139+
until cascade zone status example.test | grep -q "Published zone available"; do
140+
if (($(date +%s) > (start + timeout))); then
141+
cascade zone status example.test
142+
echo "timeout: zone status did not report published zone available" >&2
143+
exit 1
144+
fi
145+
sleep 1
146+
done
147+
148+
- name: Check the SOA SERIAL at the NSD secondary
149+
run: |
150+
timeout=10 # seconds
151+
start=$(date +%s)
152+
until dig +short @127.0.0.1 -p 1054 example.test SOA | grep -q 'ns.example.test. mail.example.test. 3 60 60 3600 5'; do
153+
if (($(date +%s) > (start + timeout))); then
154+
cascade zone status example.test
155+
dig +short @127.0.0.1 -p 1054 example.test SOA
156+
echo "::error:: timeout: NSD did not acquire the zone changes"
157+
exit 1
158+
fi
159+
sleep 1
160+
done
161+
162+
# Note: There is no NSD metric that I am aware of that we can use to
163+
# verify that it received IXFR from Cascade instead of AXFR, nor is there
164+
# any Cascade Prometheus metric or CLI command that we can use to check
165+
# this either. Increasing the NSD log level to 9 doesn't cause it to
166+
# report whether it received IXFR or AXFR either.
167+
168+
# TODO: Verify the AXFR and IXFR response content is as expected /
169+
# matching that of NSD.
170+
171+
- run: dig +onesoa +noall +answer @127.0.0.1 -p 4542 example.test AXFR > cascade-axfr.log
172+
173+
- run: dig +onesoa +noall +answer @127.0.0.1 -p 4542 example.test -t IXFR=1 >cascade-ixfr-1.log
174+
175+
- run: dig +onesoa +noall +answer @127.0.0.1 -p 4542 example.test -t IXFR=2 >cascade-ixfr-2.log
176+
177+
- run: dig +onesoa +noall +answer @127.0.0.1 -p 4542 example.test -t IXFR=3 >cascade-ixfr-3.log
178+
179+
- run: dig +onesoa +noall +answer @127.0.0.1 -p 1054 example.test AXFR >nsd-axfr.log
180+
181+
- name: Print log files on any failure in this job
182+
uses: ./.github/actions/print-logfiles
183+
if: failure()

0 commit comments

Comments
 (0)