Skip to content

fix(dns): change a retained record's TTL by delete-then-create in dns set - #352

Merged
jpage-godaddy merged 1 commit into
godaddy:mainfrom
AshutoshMore142k4:fix/dns-set-ttl-change
Nov 2, 2026
Merged

jpage-godaddy merged 1 commit into
godaddy:mainfrom
AshutoshMore142k4:fix/dns-set-ttl-change

Conversation

@AshutoshMore142k4

Copy link
Copy Markdown
Contributor

Follow-up to #257. That PR was merged with one review finding still open: a retained value with an explicit TTL change was treated as already held.

Problem

gddy dns set --type A --name www --data 1.2.3.4 --ttl 7200 on a zone that already holds 1.2.3.4 at 3600:

  1. plan_set pairs the value with its existing record (same_content ignores ttl, on purpose).
  2. apply_replace sees the explicit TTL change and creates the new record before deleting the old one.
  3. v3 identifies a record by its content, not its TTL (the premise of fix(dns): pair retained values before position in the set plan #257), so that create is an exact duplicate: DUPLICATE_RECORD. The old record stays at 3600 and the command fails.

This predates #257 (positional pairing paired the same two records), but the TTL-only case is the one #257's review flagged and it was never addressed.

Fix

In apply_replace, a kept value (same_content) is now one of two things:

  • no explicit --ttl, or the same TTL as stored: no-op, as before.
  • explicit --ttl that differs: retime_record deletes the old record, creates it with the new TTL, and puts the old record back unchanged if the create fails. Only if that restore also fails is a cleanup outcome added saying the record is gone and how to re-create it.

Deleting first opens a short window where the value is missing. With only create/delete on the record endpoint (no in-place update, see #136) that cannot be avoided for a TTL-only change, hence the restore.

Values that are not kept still go through create-then-delete, unchanged.

Tests

retime_* in rust/src/dns/set/write_tests.rs:

  • delete fails: no create is attempted (proves delete runs first)
  • create fails: old record is restored (POST with the old TTL), failure reported
  • create and restore both fail: cleanup outcome

The existing apply_replace_is_not_a_no_op_when_ttl_explicitly_changes and ..._is_still_a_no_op_when_ttl_is_omitted... still pass.

write.rs would have passed the 1000-line limit, so its test module moves to write_tests.rs (same #[path] pattern as hosting/client.rs). That part of the diff is a dedent only; the only changed lines are rustfmt re-wrapping a few json_body calls.

Checks

cargo check --workspace, cargo clippy --workspace -- -D warnings, cargo test --workspace, cargo fmt --check and rust/scripts/check-module-size.sh all pass.

Not verified against the live API: the create-after-delete order is exercised with mock servers only.

… set

`dns set --ttl N` for a value the zone already holds paired the value with
its existing record (same content), then `apply_replace` created the
new-TTL record before deleting the old one. v3 identifies a record by its
content, not its TTL, so that create is an exact duplicate and fails with
DUPLICATE_RECORD, leaving the old TTL in place and the command failing.

A kept value with a different explicit `--ttl` now goes through
`retime_record`: delete the old record, create it with the new TTL, and
if the create fails put the old record back unchanged. Only when that
restore also fails is a `cleanup` outcome added saying the record is gone.
An omitted `--ttl` is still a no-op.

The `write.rs` test module moves to `write_tests.rs` (as in
`hosting/client.rs`) to keep the file under the 1000-line limit; the move
is a dedent only.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@jpage-godaddy
jpage-godaddy merged commit 46a97c5 into godaddy:main Nov 2, 2026
5 checks passed
@jpage-godaddy

Copy link
Copy Markdown
Collaborator

Thanks for the contribution, @AshutoshMore142k4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants