Skip to content

feat(dns): serve reverse PTR for overlay instance addresses#2855

Merged
chet merged 1 commit into
NVIDIA:mainfrom
chet:gh-issue-2776
Jun 25, 2026
Merged

feat(dns): serve reverse PTR for overlay instance addresses#2855
chet merged 1 commit into
NVIDIA:mainfrom
chet:gh-issue-2776

Conversation

@chet

@chet chet commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Overlay (DPU-managed) instances got forward A/AAAA records in #2408, but their addresses still resolved to nothing in reverse -- find_ptr_record only answered from machine interfaces, and overlay addresses live in instance_addresses. This adds the reverse half: an overlay instance's address now answers a PTR with its own FQDN, so a forward record and its PTR round-trip.

find_ptr_record gains a second UNION arm over instance_addresses that mirrors the dns_records_instance forward view -- same join to the segment's forward zone, same host_inband exclusion (those addresses are the host's own, already answered by the machine arm). It reads the hostname stored at allocation, so there is no second IP-to-name derivation; the lookup is by address, like the machine arm.

Tests added!

This supports #2776

@chet chet requested a review from a team as a code owner June 24, 2026 19:20
@chet

chet commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai PTAL, thanks!

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 43bbd458-0cac-481e-8f53-fa4113074bdf

📥 Commits

Reviewing files that changed from the base of the PR and between e7781e0 and 984e4ba.

📒 Files selected for processing (1)
  • crates/api-db/src/dns/resource_record.rs

Summary by CodeRabbit

  • Bug Fixes
    • Improved reverse DNS (PTR) resolution so IP-to-name results are returned more reliably across supported sources, avoiding duplicate answers.
    • Ensured overlay instance addresses correctly return a single PTR for both IPv4 and IPv6.
    • Confirmed entries marked as in-band are excluded from reverse lookups.
    • Standardized reverse DNS TTL handling to match forward DNS timing (defaulting to 300 when unset).

Walkthrough

PTR reverse lookup now resolves records from machine interface and overlay instance sources. The query adds an overlay arm, excludes host_inband, and the tests cover IPv4, IPv6, and empty-result cases.

Changes

PTR reverse lookup

Layer / File(s) Summary
PTR union query
crates/api-db/src/dns/resource_record.rs
find_ptr_record now documents and queries PTRs from machine interface rows with COALESCE(meta.ttl, 300) and overlay instance rows via dns_records_instance, with host_inband excluded by the instance view.
PTR resolution tests
crates/api-db/src/dns/resource_record.rs
The PTR tests seed overlay IPv4 and IPv6 instance addresses, assert the returned ptr_content matches the instance-forward FQDN, and assert host_inband addresses produce no PTR rows.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: reverse PTR support for overlay instance addresses.
Description check ✅ Passed The description is directly aligned with the changeset and accurately explains the new PTR lookup path and tests.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Fetch PR details
gh pr view 2855 --repo NVIDIA/infra-controller --json title,body,files,additions,deletions,state

echo "=== PR DIFF ==="
gh pr diff 2855 --repo NVIDIA/infra-controller

Length of output: 7183


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the full file for complete context
cat -n crates/api-db/src/dns/resource_record.rs

Length of output: 19106



@chet — clean, well-scoped implementation. The query structure, doc-comment, and test coverage are all production-grade. One primary concern and one minor observation below.


Primary concern — UNION should be UNION ALL

The doc-comment itself states:

"The two arms are disjoint (an overlay address is never a machine interface address), so the UNION only ever merges an accidental exact match."

If the arms are provably disjoint, UNION is semantically wrong here: it adds an unnecessary deduplication step (sort or hash aggregate over every returned row) at zero benefit. UNION ALL is both more accurate and cheaper. Reserve UNION for cases where duplicates are possible and must be suppressed.

      AND (mi.primary_interface = TRUE OR mi.interface_type = 'Bmc')
-   UNION
+   UNION ALL
    SELECT

If a future change ever makes an address appear in both arms, that is the point at which UNION (or explicit de-dup logic) should be reconsidered — not preemptively here at the cost of every PTR lookup.


Minor observation — hostname IS NOT NULL vs. empty string

AND ia.hostname IS NOT NULL

Since address_to_hostname is guaranteed to return a non-empty string, this is safe in practice. As a belt-and-suspenders measure, AND ia.hostname <> '' costs nothing and prevents a malformed '.tenant.example.com.' FQDN from ever being emitted should a NULL-to-empty-string migration or a raw INSERT ever land in the table. Take or leave — this is purely defensive.


Everything else looks solid

Area Assessment
SQL join chain (instance_addresses → network_segments → domains) Correctly mirrors the dns_records_instance forward view
host_inband exclusion (<> on an enum discriminant) Correct and consistent with the forward view
TTL (hardcoded 300) Appropriate — no dns_record_metadata join exists for instance addresses in the forward path either
Index use (ia.address = $1::inet) Rides the address index as intended
PTR FQDN format (concat(ia.hostname, '.', d.name, '.')) Produces a correct trailing-dot FQDN
Test coverage Both address families, plus the host_inband exclusion case — comprehensive

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
crates/api-db/src/dns/resource_record.rs (1)

391-431: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a small table for the IPv4/IPv6 PTR assertions.

The two lookup/assert blocks exercise the same operation with different inputs; a table keeps the reverse test aligned with the nearby forward DNS test and makes future address-family cases cheaper to add.

As per coding guidelines, “Use table-driven test style when writing tests in Rust.”

♻️ Proposed refactor
-        // The PTR answers with the instance's forward FQDN -- the reverse of `#2408`'s
-        // A/AAAA record, so the two round-trip.
-        let v4 = super::find_ptr_record(
-            txn.as_mut(),
-            "10.1.2.3".parse::<std::net::IpAddr>().unwrap(),
-        )
-        .await
-        .unwrap();
-        assert_eq!(v4.len(), 1, "one PTR for the overlay address");
-        assert_eq!(v4[0].ptr_content, "10-1-2-3.tenant.example.com.");
-
-        let v6 = super::find_ptr_record(
-            txn.as_mut(),
-            "2001:db8:abcd::2".parse::<std::net::IpAddr>().unwrap(),
-        )
-        .await
-        .unwrap();
-        assert_eq!(v6.len(), 1, "one PTR for the overlay address");
-        assert_eq!(
-            v6[0].ptr_content,
-            "2001-0db8-abcd-0000-0000-0000-0000-0002.tenant.example.com."
-        );
+        let cases = [
+            ("10.1.2.3", "10-1-2-3.tenant.example.com."),
+            (
+                "2001:db8:abcd::2",
+                "2001-0db8-abcd-0000-0000-0000-0000-0002.tenant.example.com.",
+            ),
+        ];
+
+        for (address, expected_ptr) in cases {
+            let ptrs =
+                super::find_ptr_record(txn.as_mut(), address.parse::<std::net::IpAddr>().unwrap())
+                    .await
+                    .unwrap();
+
+            assert_eq!(ptrs.len(), 1, "one PTR for {address}");
+            assert_eq!(ptrs[0].ptr_content, expected_ptr, "PTR for {address}");
+        }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/api-db/src/dns/resource_record.rs` around lines 391 - 431, The PTR
test in the `find_ptr_record` block repeats the same lookup/assert pattern for
IPv4 and IPv6, so refactor it into a small table-driven test. Keep the existing
`add_address` setup, then iterate over a table of address, expected PTR content,
and expected label count, using `super::find_ptr_record` and the same assertions
for each case. This should live in the same `resource_record.rs` test area and
preserve the current behavior while making it easier to add more address-family
cases later.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/api-db/src/dns/resource_record.rs`:
- Around line 391-431: The PTR test in the `find_ptr_record` block repeats the
same lookup/assert pattern for IPv4 and IPv6, so refactor it into a small
table-driven test. Keep the existing `add_address` setup, then iterate over a
table of address, expected PTR content, and expected label count, using
`super::find_ptr_record` and the same assertions for each case. This should live
in the same `resource_record.rs` test area and preserve the current behavior
while making it easier to add more address-family cases later.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7ced9313-fa45-4495-8b32-f2e9dfb90e7b

📥 Commits

Reviewing files that changed from the base of the PR and between c34597c and 4eca2bc.

📒 Files selected for processing (1)
  • crates/api-db/src/dns/resource_record.rs

@github-actions

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 265 6 24 98 7 130
machine-validation-runner 717 32 188 267 36 194
machine_validation 717 32 188 267 36 194
machine_validation-aarch64 717 32 188 267 36 194
nvmetal-carbide 717 32 188 267 36 194
TOTAL 3139 134 776 1172 151 906

Per-CVE detail lives in the per-service grype-* artifacts (JSON + SARIF). Severity counts only — no CVE IDs published here.

@chet

chet commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chet

chet commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review please, thanks!

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@chet Understood — I’ll rerun a full review of Pull Request #2855 now.

🐇

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
crates/api-db/src/dns/resource_record.rs (1)

423-431: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the overlay PTR TTL in the reverse tests.

The overlay SQL branch explicitly returns 300 AS ttl, and the DNS handler forwards ttl to clients. Add a direct assertion so the test covers that changed contract, not just ptr_content.

As per coding guidelines, “Verification should exercise the behavior that changed.”

Proposed test assertion
             assert_eq!(ptrs.len(), 1, "one PTR for {}", case.address);
             assert_eq!(ptrs[0].ptr_content, case.ptr);
+            assert_eq!(ptrs[0].ttl, 300, "PTR TTL for {}", case.address);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/api-db/src/dns/resource_record.rs` around lines 423 - 431, The reverse
DNS test currently verifies only ptr_content, but it should also validate the
new overlay TTL contract. Update the loop in the PTR reverse test around
find_ptr_record and the existing assert_eq! checks to add a direct assertion
that the returned PTR record ttl is 300, since the overlay SQL branch in the DNS
path now explicitly sets ttl and the handler forwards it to clients.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/api-db/src/dns/resource_record.rs`:
- Around line 423-431: The reverse DNS test currently verifies only ptr_content,
but it should also validate the new overlay TTL contract. Update the loop in the
PTR reverse test around find_ptr_record and the existing assert_eq! checks to
add a direct assertion that the returned PTR record ttl is 300, since the
overlay SQL branch in the DNS path now explicitly sets ttl and the handler
forwards it to clients.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: aec03b6d-6503-444d-90fd-711fa99dc162

📥 Commits

Reviewing files that changed from the base of the PR and between ecf44bd and 802d873.

📒 Files selected for processing (1)
  • crates/api-db/src/dns/resource_record.rs

Overlay (DPU-managed) instances got forward A/AAAA records in NVIDIA#2408, but
their addresses still resolved to nothing in reverse -- find_ptr_record
only answered from machine interfaces, and overlay addresses live in
instance_addresses. This adds the reverse half: an overlay instance's
address now answers a PTR with its own FQDN, so a forward record and its
PTR round-trip.

find_ptr_record gains a second UNION arm that reads the dns_records_instance
forward view by IP, so forward and reverse resolve overlay names through one
definition. The view already carries the stored hostname, the segment's
forward zone, and the host_inband exclusion (those addresses are the host's
own, answered by the machine arm) -- so there is no duplicated join or
IP-to-name derivation. The lookup is by address, like the machine arm.

- Add a UNION arm to find_ptr_record that reads dns_records_instance by IP,
  answering an overlay address with <hostname>.<zone>.
- Reuse NVIDIA#2408's forward view outright -- forward matches it by name, reverse
  by IP -- so the two cannot drift.

Tests added!

This supports NVIDIA#2776

Signed-off-by: Chet Nichols III <chetn@nvidia.com>
@chet

chet commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chet

chet commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

@chet Understood — I’ll rerun a full review of #2855 now.

✅ Action performed

Full review finished.

@chet

chet commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

@chet Understood — I’ll rerun a full review of PR #2855 now.

✅ Action performed

Full review finished.

@chet chet enabled auto-merge (squash) June 25, 2026 05:25
@chet chet merged commit cc31499 into NVIDIA:main Jun 25, 2026
58 checks passed
@chet chet deleted the gh-issue-2776 branch June 25, 2026 06:06
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