Skip to content

feat(dns): add --replace-conflicting-types flag, fix CNAME conflict errors#102

Merged
jpage-godaddy merged 9 commits into
rust-portfrom
agreement-key
Jul 21, 2026
Merged

feat(dns): add --replace-conflicting-types flag, fix CNAME conflict errors#102
jpage-godaddy merged 9 commits into
rust-portfrom
agreement-key

Conversation

@jpage-godaddy

@jpage-godaddy jpage-godaddy commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fix dns set/dns add surfacing an opaque validation error on a CNAME name-exclusivity conflict, by refreshing the Domains v3 OpenAPI spec and teaching format_api_error to render the v3 top-level details[] error shape. dns set also gains an opt-in --replace-conflicting-types flag that auto-removes the conflicting record(s) and retries the write, instead of only pointing at the manual dns delete command.
  • Related fix in domain purchase: validate the OAuth token's customer identity locally rather than relying on a caller-supplied consent principal, matching the refreshed spec (the register endpoint now derives agreedBy server-side).
  • Split the ~1760-line dns/mod.rs into per-command files (list.rs, add.rs, set.rs, delete.rs) with shared helpers in records.rs and conflicts.rs, mirroring the domain/ module's layout. Pure reorganization of this file — no behavior change from the split itself (the CNAME-conflict and --replace-conflicting-types behavior above are separate, intentional changes).
  • Make the DNS command error/recovery hints copy-pasteable: several included a bare gddy dns add/dns delete/dns list without the required domain positional or --type/--name flags.

Slack thread for context.

Test plan

  • cargo fmt --check
  • cargo build --workspace
  • cargo test --workspace (263 passing)
  • cargo clippy --workspace -- -D warnings
  • Manually verify dns set/dns add against a real domain with an existing CNAME conflict

🤖 Generated with Claude Code

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.

Pull request overview

Refactors the DNS command implementation into per-subcommand modules while updating the Domains v3 API surface (vendored spec + generated client expectations) and improving user-facing validation errors (notably CNAME/name-exclusivity conflicts) by supporting the v3 top-level details[] error shape. It also updates domain purchase to align with the refreshed spec by treating consent attribution (agreedBy) as server-derived and adding a local fail-fast check for customer-scoped OAuth identities.

Changes:

  • Update domain purchase consent handling: remove caller-supplied agreedBy, add local customer-identity validation, and harden cached agreement-type parsing with a clear stale-cache error.
  • Make API error rendering aware of v3 top-level details[] validation errors and reuse the formatter across dns and domain.
  • Split DNS functionality into list/add/set/delete modules with shared helpers and add improved name-exclusivity conflict diagnosis plus an opt-in auto-remediation flag for dns set.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
rust/src/domain/purchase.rs Align purchase execution with updated v3 consent model; fail-fast on non-customer OAuth subjects; validate cached agreement types via parsing.
rust/src/domain/mod.rs Re-export format_api_error for cross-module reuse (e.g., DNS).
rust/src/domain/guides/domain-purchase.md Remove documentation for the dropped --agreed-by flag.
rust/src/domain/common.rs Export format_api_error and support v3 top-level details[] validation errors in friendly formatting.
rust/src/dns/mod.rs Replace monolithic implementation with per-command modules + shared helpers.
rust/src/dns/records.rs Centralize DNS arg parsing/validation, record construction, pagination, and verify-next-action helper.
rust/src/dns/conflicts.rs Add structured detection/diagnosis for DUPLICATE_RECORD conflicts and render actionable explanations.
rust/src/dns/list.rs Implement dns list using shared record fetching + type/name filters.
rust/src/dns/add.rs Implement dns add with per-record outcomes and conflict-aware error rendering.
rust/src/dns/set.rs Implement dns set reconcile plan, partial-failure reporting, and optional auto-delete+retry on cross-type conflicts.
rust/src/dns/delete.rs Implement dns delete with per-record delete outcomes and summary error reporting.
rust/domains-client/src/lib.rs Update generated-client-facing tests/fixtures to match new spec enums and agreement type changes.
rust/domains-client/openapi/swagger_domains.v3.yaml Refresh vendored v3 spec to 3.1.0 with updated consent/agreement semantics and enums.
rust/domains-client/openapi/domains.oas3.json Refresh merged OAS3 JSON to reflect the updated v3 schema/enum changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rust/src/dns/set.rs
Comment thread rust/src/dns/conflicts.rs
Comment thread rust/src/dns/set.rs
jpage-godaddy added a commit that referenced this pull request Jul 14, 2026
…e detail format

Copilot review feedback on PR #102:
- dns add's DUPLICATE_RECORD remediation suggested `dns set --replace-conflicting-types`
  without its required args; point back at the reconstructable `dns add` command instead.
- dns set's partial-failure remediation suggested `gddy dns set` bare, which can't be
  reconstructed (missing --data); rephrase to "the original command".
- dns set's plain-delete outcomes reported the raw record id while
  --replace-conflicting-types deletes reported "<TYPE> <DATA>", mixing identifiers in
  the same breakdown; both now use the type+data format.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jpage-godaddy
jpage-godaddy requested a review from Copilot July 14, 2026 19:45

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Comment thread rust/src/dns/conflicts.rs
Comment thread rust/src/dns/conflicts.rs Outdated

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Comment thread rust/src/domain/common.rs
Comment thread rust/src/domain/common.rs

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread rust/domains-client/openapi/domains.oas3.json

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Comment thread rust/src/dns/add.rs
Comment thread rust/src/dns/delete.rs

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Comment thread rust/src/dns/delete.rs Outdated
Comment thread rust/domains-client/openapi/swagger_domains.v3.yaml
Comment thread rust/src/dns/set.rs

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Comment thread rust/src/domain/purchase.rs
Comment thread rust/src/dns/set.rs

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Comment thread rust/src/domain/purchase.rs
Comment thread rust/domains-client/openapi/swagger_domains.v3.yaml
Comment thread rust/domains-client/openapi/domains.oas3.json

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread rust/src/dns/conflicts.rs

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.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

@jpage-godaddy jpage-godaddy changed the title refactor(dns): split dns into per-command files, fix CNAME conflict errors feat(dns): add --replace-conflicting-types flag, fix CNAME conflict errors Jul 14, 2026
jpage-godaddy and others added 9 commits July 20, 2026 10:07
…flict errors

Refresh the Domains v3 OpenAPI spec and use it to fix `dns set`/`dns add`
surfacing an opaque error on a CNAME name-exclusivity conflict, plus a
related fix in `domain purchase`. Also break up the ~1760-line dns/mod.rs
into per-command files (list/add/set/delete) with shared helpers split into
records.rs and conflicts.rs, mirroring the domain/ module's layout for
easier navigation. No behavior change from the reorganization itself.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…e detail format

Copilot review feedback on PR #102:
- dns add's DUPLICATE_RECORD remediation suggested `dns set --replace-conflicting-types`
  without its required args; point back at the reconstructable `dns add` command instead.
- dns set's partial-failure remediation suggested `gddy dns set` bare, which can't be
  reconstructed (missing --data); rephrase to "the original command".
- dns set's plain-delete outcomes reported the raw record id while
  --replace-conflicting-types deletes reported "<TYPE> <DATA>", mixing identifiers in
  the same breakdown; both now use the type+data format.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The DUPLICATE_RECORD remediation hint for a CNAME-vs-other-types conflict
only named the first conflicting type's delete command, so a name with
e.g. both A and MX records would leave the MX record behind after
following the hint, and the re-run `dns add` would still fail. Also
correct a doc comment claiming `conflicting_records_at`'s no-type-filter
fetch matches what `dns list --name` does — `dns list` actually requires
`--type` whenever `--name` is given, so this helper does something the
CLI doesn't expose.
…ription

The v3 error-details schema documents description as unstable ("MAY
change... MUST NOT depend on this value") while issue is the stable
fine-grained code. friendly_field_errors dropped any detail with an
empty description, producing an opaque fallback message even when a
usable issue code was present.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The partial-failure hints told users to "re-run gddy dns add"/"gddy
dns delete" without the required domain positional or --type/--name
flags, so they couldn't be copy-pasted as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The "re-run gddy dns list" hint for a record returned without a
recordId omitted the domain positional and --type/--name flags,
same class of bug as the add/delete recovery hints fixed earlier.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ests

- purchase.rs: name the discarded consent_principal() result and explain
  why only its validation (not the customer id) is needed here.
- dns/set.rs: cover write_with_conflict_handling's DUPLICATE_RECORD
  branching — direct success, conflict without --replace-conflicting-types,
  and conflict-with-the-flag (delete_conflicts outcome then retry outcome,
  in order) — against a mocked domains-client server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ement types

A re-quote won't help when the API has introduced a genuinely new
agreement type rather than the cache just being stale — that requires
a newer CLI build with the updated generated AgreementType enum.
A name-exclusivity conflict can span multiple existing records (e.g.
A + MX both blocking a CNAME write); "remove it automatically" implied
just one, unlike the matching CLI help text which already says
"conflicting record(s)".
@jpage-godaddy

Copy link
Copy Markdown
Collaborator Author

Disappointingly I've asked for this to be reviewed several times and it hasn't been. It's now a week old. Merging to block the outstanding ask.

@jpage-godaddy
jpage-godaddy merged commit 2c0e576 into rust-port Jul 21, 2026
1 check passed
@jpage-godaddy
jpage-godaddy deleted the agreement-key branch July 21, 2026 17:15
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.

2 participants