feat(dns): add HTTPS, SVCB, and TLSA record support - #246
Conversation
gddy dns add/set/delete/list now recognize HTTPS, SVCB, and TLSA record types. TLSA's certificate association fields (usage/selector/matching-type) get dedicated flags, with the certificate data carried by the existing --data flag; HTTPS/SVCB get a --parameters flag for SvcParams, and reuse the existing --priority for SvcPriority.
There was a problem hiding this comment.
🟡 Changes recommended
The TLSA flag parsers currently accept out-of-spec values (e.g., --usage 0..=255 instead of 0..=3), which can allow invalid input through and lead to avoidable API validation failures.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds first-class CLI support for managing modern DNS record types (HTTPS, SVCB, TLSA) in the gddy dns command family, aligning the Rust CLI’s record modeling and request payloads with the updated v3 Domains API schema.
Changes:
- Expand recognized writable/listable record types to include
HTTPS,SVCB, andTLSA, and update help text accordingly. - Add TLSA-specific flags (
--usage,--selector,--matching-type) and an HTTPS/SVCB--parametersflag, plus pre-flight validation for type-specific options. - Update v3 record construction and write-path tests to ensure HTTPS parameters and TLSA fields serialize into request bodies correctly.
File summaries
| File | Description |
|---|---|
| rust/src/dns/set/write.rs | Adds write-path tests verifying HTTPS parameters and TLSA fields are sent in the POST body. |
| rust/src/dns/set/mod.rs | Wires in new TLSA/SVCB validation before executing dns set. |
| rust/src/dns/records.rs | Extends supported types, adds new flags/options, validates type-specific fields, and maps TLSA/HTTPS/SVCB fields into v3 DnsRecord. |
| rust/src/dns/list.rs | Updates dns list --type help text to include HTTPS/SVCB/TLSA. |
| rust/src/dns/delete.rs | Updates dns delete --type help text to include HTTPS/SVCB/TLSA. |
| rust/src/dns/add.rs | Wires in new TLSA/SVCB validation before executing dns add. |
Review details
Suppressed comments (2)
rust/src/dns/records.rs:170
- The clap range for
--selectorallows 0..=255, but TLSA selector is defined as 0-1. Restricting the range provides immediate user feedback and prevents avoidable API validation errors.
/// TLSA selector, 0-1 (RFC 6698 §2.1.2; TLSA only; required for TLSA). 0
/// full certificate, 1 SubjectPublicKeyInfo.
#[arg(long = "selector", value_name = "N", value_parser = clap::value_parser!(i64).range(0..=255), required_if_eq("record_type", "TLSA"))]
pub(super) selector: Option<i64>,
rust/src/dns/records.rs:175
- The clap range for
--matching-typeallows 0..=255, but TLSA matching type is defined as 0-2. Tighten the range so invalid inputs are rejected at parse time.
/// TLSA matching type, 0-2 (RFC 6698 §2.1.3; TLSA only; required for
/// TLSA). 0 exact match, 1 SHA-256, 2 SHA-512.
#[arg(long = "matching-type", value_name = "N", value_parser = clap::value_parser!(i64).range(0..=255), required_if_eq("record_type", "TLSA"))]
pub(super) matching_type: Option<i64>,
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
RFC 6698 defines usage 0-3, selector 0-1, and matching-type 0-2; values outside those ranges aren't supported by the API and would otherwise round-trip to a 422 instead of failing fast at parse time.
There was a problem hiding this comment.
🟡 Changes recommended
TLSA records now omit data (using certificateData instead), but downstream conflict/duplicate detection and per-record reporting still assume data, leading to incorrect behavior and confusing output for TLSA operations.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
rust/src/dns/records.rs:133
--priorityis documented as “MX, SRV, HTTPS, and SVCB only”, but it can currently be provided for any record type and will be sent to the API (since there’s no validation like the CAA/TLSA/SVCB guards). This makes the CLI accept invalid combinations and can lead to confusing API-side validation errors.
Consider adding a validation guard (similar to validate_caa_fields) that rejects --priority unless the record type is one of MX/SRV/HTTPS/SVCB, and call it from both dns add and dns set before any network calls.
rust/src/dns/records.rs:137
--port/--protocolare described here as “SRV and TLSA only”, but there’s no reverse validation to prevent them being set for other record types (and they will be serialized into the v3 request body). That mismatch between help text and behavior can produce hard-to-understand validation failures downstream.
Consider adding a validation helper that rejects SRV/TLSA-only fields (--port, --protocol, and also the SRV-only --service/--weight) unless record_type is SRV (and TLSA where applicable).
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
v3_record() moves TLSA's value into certificateData since data isn't used for that type, but conflict diagnosis, delete/set reporting, and exact-duplicate detection still read data directly, so TLSA records showed "(no data)" and dodged duplicate detection. Adds a record_value helper that checks certificateData when data is absent, and switches every one of those read sites to use it.
There was a problem hiding this comment.
🔵 Needs a closer look
The CLI now documents several flags as type-specific (e.g., --priority, --port, --protocol) but still accepts and forwards them for unrelated record types without validation, creating an inconsistent and potentially confusing public interface.
Review details
Suppressed comments (1)
rust/src/dns/records.rs:149
- The CLI help text now documents
--priority/--port/--protocolas only applying to specific record types, but there’s no validation to reject these flags for other types (andv3_recordwill still include any provided values in the request body). This can lead to confusing UX (flags appear accepted but are ignored or rejected server-side). Consider adding a small validation helper (similar tovalidate_caa_fields/validate_tlsa_fields/validate_svcb_fields) that rejectspriorityunless type is MX/SRV/HTTPS/SVCB and rejectsport/protocolunless type is SRV/TLSA (and ideally also gateweight/serviceto SRV).
/// Record priority (MX, SRV, HTTPS, and SVCB only). For HTTPS/SVCB, 0
/// means AliasMode.
#[arg(long, value_name = "N", value_parser = clap::value_parser!(i64).range(0..=65535))]
pub(super) priority: Option<i64>,
/// Service port (SRV and TLSA only).
#[arg(long, value_name = "PORT", value_parser = clap::value_parser!(i64).range(1..=65535))]
pub(super) port: Option<i64>,
/// Record weight (SRV only).
#[arg(long, value_name = "N", value_parser = clap::value_parser!(i64).range(0..=65535))]
pub(super) weight: Option<i64>,
/// Service protocol, e.g. _tcp (SRV and TLSA only).
#[arg(long, value_name = "PROTO")]
pub(super) protocol: Option<String>,
/// Service type (SRV only).
#[arg(long, value_name = "SERVICE")]
pub(super) service: Option<String>,
- Files reviewed: 8/8 changed files
- Comments generated: 0 new
- Review effort level: Lite
Summary
gddy dns add/set/delete/listnow recognizeHTTPS,SVCB, andTLSArecord types (DEVEX-1105).--usage/--selector/--matching-typeflags (clap-validated to their actual RFC 6698 ranges: 0-3/0-1/0-2); its certificate association data is carried by the existing--dataflag.--parametersflag for SvcParams;--priority(already existing) doubles as SvcPriority.record_value()helper so TLSA's value (which lives incertificateData, notdata) is correctly shown indelete/setreporting and recognized by exact-duplicate detection, instead of reading as "(no data)".Stacked on #244 (spec-drift), which resynced the v3 API spec with the real TLSA/HTTPS/SVCB fields this depends on — please merge that first.
Test plan
cargo check --workspacecargo clippy --workspace -- -D warningscargo test --workspace(760 passed, incl. 8 new unit tests + 2 new httpmock write-path tests)cargo fmt --check./rust/scripts/check-module-size.sh