Skip to content

feat(api): persist and reconcile SitePrefixes in Core#4031

Open
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-3884
Open

feat(api): persist and reconcile SitePrefixes in Core#4031
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-3884

Conversation

@chet

@chet chet commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

As part of supporting tenant-provided site prefixes (#3883), site_fabric_prefixes currently reaches Core as an in-memory config list. That is enough for VpcPrefix admission and DPU rendering, but it does not give each configured root a stable resource ID or lifecycle record for the tenant-managed layers to reference.

This adds a Core SitePrefix resource with explicit Configured and TenantManaged authorities. Startup reconciliation canonicalizes configured CIDRs, keeps IDs stable across unchanged restarts, marks removed roots Deleting, and reactivates the same row if a CIDR returns. A transaction advisory lock makes concurrent Core startup converge on one row, while source-scoped reconciliation leaves tenant rows alone.

Tenant-owned rows use a composite GiST exclusion to reject overlap within one tenant while allowing equal address space across tenants. The migration installs and verifies btree_gist, and the read-only RPCs expose owner, authority, routing scope, lifecycle, metadata, versions, and timestamps without opening the tenant mutation path yet.

This is additive: VpcPrefix admission and DPU rendering still use the existing in-memory configuration.

Related issues

This supports #3884

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated

  • Integration tests added/updated

  • Manual testing performed

  • No testing required (docs, internal refactor, etc.)

  • cargo test -p carbide-api-model -p carbide-uuid site_prefix --lib

  • cargo test -p carbide-rpc site_prefix --features model

  • cargo test -p carbide-api-db site_prefix --lib -- --nocapture --test-threads=1

  • cargo test -p carbide-api-core site_prefix --lib -- --nocapture --test-threads=1

  • cargo make check-format-nightly

  • cargo make clippy

  • cargo make carbide-lints

Additional Notes

The migration requires btree_gist and fails before changing the SitePrefix schema when the extension is unavailable or installed outside the public schema.

Tenant mutation APIs, VpcPrefix parent linkage, DPU-acknowledged readiness, REST projection, tenant authorization, and overlap-constraint changes remain separate follow-up layers.

@chet
chet requested a review from a team as a code owner July 23, 2026 19:59
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Adds typed site-prefix models, PostgreSQL persistence with tenant overlap constraints and configured-prefix reconciliation, protobuf and RPC conversion support, Forge lookup endpoints with RBAC, startup reconciliation, and model, database, and API tests.

Changes

Site prefix inventory

Layer / File(s) Summary
Typed model and RPC schema
crates/uuid/..., crates/api-model/..., crates/rpc/proto/*, crates/rpc/build.rs, rest-api/proto/...
Defines site-prefix IDs, model structures, validation rules, protobuf messages, and generated serialization mappings.
RPC/model conversion
crates/rpc/src/model/*
Adds strict enum, resource, and search-filter conversions between RPC and internal types.
Database persistence and reconciliation
crates/api-db/migrations/*, crates/api-db/src/*
Creates tenant-aware storage, overlap constraints, persistence helpers, configured-prefix reconciliation, lookup queries, and SQL-backed validation.
Forge API integration
crates/api-core/src/api.rs, crates/api-core/src/handlers/*, crates/api-core/src/auth/*, crates/api-core/src/setup.rs, crates/api-core/src/tests/*
Adds site-prefix lookup RPCs, RBAC permissions, request validation, database delegation, startup reconciliation, and API coverage.

Estimated code review effort: 5 (Critical) | ~90 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ForgeAPI
  participant SitePrefixHandler
  participant SitePrefixDB
  Client->>ForgeAPI: Submit site-prefix lookup request
  ForgeAPI->>SitePrefixHandler: Dispatch lookup RPC
  SitePrefixHandler->>SitePrefixDB: Query IDs or records
  SitePrefixDB-->>SitePrefixHandler: Return matching data
  SitePrefixHandler-->>Client: Return RPC response
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title is concise and accurately captures the main change: persisting and reconciling SitePrefix resources in Core.
Description check ✅ Passed The description is directly aligned with the changeset and accurately summarizes the new SitePrefix resource, reconciliation, and RPC exposure.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@chet

chet commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@chet, I’ll perform a complete re-review of the PR.

🐇🔍

✅ Action performed

Full review finished.

@github-actions

Copy link
Copy Markdown

🔐 TruffleHog Secret Scan

No secrets or credentials found!

Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉

🔗 View scan details

🕐 Last updated: 2026-07-23 20:02:06 UTC | Commit: 1165819

@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/site_prefix.rs (1)

223-238: 🚀 Performance & Scalability | 🔵 Trivial

Optional: containment lookups are unindexed. The prefix >>= $1 / prefix <<= $1 predicates cannot exploit the tenant-scoped partial GiST exclusion index, so these filters will fall back to a sequential scan across site_prefixes. This is inconsequential at the expected site-prefix cardinality, but should inventory growth ever materialise, consider a dedicated GiST index on prefix (e.g. USING gist (prefix inet_ops)) to keep containment queries index-backed.

🤖 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/site_prefix.rs` around lines 223 - 238, The
PrefixMatch::Contains and PrefixMatch::ContainedBy query predicates lack a
supporting GiST index. Add a dedicated GiST index on the site_prefixes prefix
column using the inet_ops operator class, while leaving the PrefixMatch::Exact
query and existing predicate behavior unchanged.
🤖 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/site_prefix.rs`:
- Around line 223-238: The PrefixMatch::Contains and PrefixMatch::ContainedBy
query predicates lack a supporting GiST index. Add a dedicated GiST index on the
site_prefixes prefix column using the inet_ops operator class, while leaving the
PrefixMatch::Exact query and existing predicate behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a48b2d4c-bac9-400e-8fa5-1d0a37f57065

📥 Commits

Reviewing files that changed from the base of the PR and between 648be0a and 1165819.

📒 Files selected for processing (19)
  • crates/api-core/src/api.rs
  • crates/api-core/src/auth/internal_rbac_rules.rs
  • crates/api-core/src/handlers/mod.rs
  • crates/api-core/src/handlers/site_prefix.rs
  • crates/api-core/src/setup.rs
  • crates/api-core/src/tests/mod.rs
  • crates/api-core/src/tests/site_prefix.rs
  • crates/api-db/migrations/20260723120000_site_prefixes.sql
  • crates/api-db/src/lib.rs
  • crates/api-db/src/site_prefix.rs
  • crates/api-model/src/lib.rs
  • crates/api-model/src/site_prefix.rs
  • crates/rpc/build.rs
  • crates/rpc/proto/common.proto
  • crates/rpc/proto/forge.proto
  • crates/rpc/src/model/mod.rs
  • crates/rpc/src/model/site_prefix.rs
  • crates/uuid/src/lib.rs
  • crates/uuid/src/site_prefix/mod.rs

@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/migrations/20260723120000_site_prefixes.sql (1)

76-91: 🚀 Performance & Scalability | 🔵 Trivial

Containment lookups over configured prefixes are unindexed.

The GiST index backing site_prefixes_tenant_prefix_excl is partial (WHERE authority = 'tenant_managed'), and site_prefixes_configured_prefix_key is a B-tree that only accelerates exact = matches. Consequently, find_ids queries using the >>= / <<= containment operators against configured (or authority-unfiltered) rows will fall back to sequential scans.

This is acceptable while the configured set remains a small collection of site-fabric roots, but should the inventory grow, consider a dedicated GiST index on prefix (or a non-partial one) to keep containment lookups index-backed.

🤖 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/migrations/20260723120000_site_prefixes.sql` around lines 76 -
91, Review the site_prefixes indexes and add a GiST index on prefix that covers
configured and authority-unfiltered containment queries using >>= and <<=,
rather than relying on the partial tenant-managed exclusion index or exact-match
B-tree. Preserve the existing uniqueness and tenant-managed lookup indexes.
🤖 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/migrations/20260723120000_site_prefixes.sql`:
- Around line 76-91: Review the site_prefixes indexes and add a GiST index on
prefix that covers configured and authority-unfiltered containment queries using
>>= and <<=, rather than relying on the partial tenant-managed exclusion index
or exact-match B-tree. Preserve the existing uniqueness and tenant-managed
lookup indexes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 44fdec9d-3861-42da-866d-6ec57ca3f5cb

📥 Commits

Reviewing files that changed from the base of the PR and between 648be0a and 1165819.

📒 Files selected for processing (19)
  • crates/api-core/src/api.rs
  • crates/api-core/src/auth/internal_rbac_rules.rs
  • crates/api-core/src/handlers/mod.rs
  • crates/api-core/src/handlers/site_prefix.rs
  • crates/api-core/src/setup.rs
  • crates/api-core/src/tests/mod.rs
  • crates/api-core/src/tests/site_prefix.rs
  • crates/api-db/migrations/20260723120000_site_prefixes.sql
  • crates/api-db/src/lib.rs
  • crates/api-db/src/site_prefix.rs
  • crates/api-model/src/lib.rs
  • crates/api-model/src/site_prefix.rs
  • crates/rpc/build.rs
  • crates/rpc/proto/common.proto
  • crates/rpc/proto/forge.proto
  • crates/rpc/src/model/mod.rs
  • crates/rpc/src/model/site_prefix.rs
  • crates/uuid/src/lib.rs
  • crates/uuid/src/site_prefix/mod.rs

@chet

chet commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@chet, I’ll perform a complete re-review of #4031.

🐇🔍

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 9 minutes.

@github-actions

Copy link
Copy Markdown

`site_fabric_prefixes` currently reaches Core as an in-memory config
list. That is enough for VpcPrefix admission and DPU rendering, but it
does not give each configured root a stable resource ID or lifecycle
record for the tenant-managed layers to reference.

This adds a Core `SitePrefix` resource with explicit `Configured` and
`TenantManaged` authorities. Startup reconciliation canonicalizes
configured CIDRs, keeps IDs stable across unchanged restarts, marks
removed roots `Deleting`, and reactivates the same row if a CIDR
returns. A transaction advisory lock makes concurrent Core startup
converge on one row, while source-scoped reconciliation leaves tenant
rows alone.

Tenant-owned rows use a composite GiST exclusion to reject overlap
within one tenant while allowing equal address space across tenants.
The migration installs and verifies `btree_gist`, and the read-only RPCs
expose owner, authority, routing scope, lifecycle, metadata, versions,
and timestamps without opening the tenant mutation path yet.

This is additive: VpcPrefix admission and DPU rendering still use the
existing in-memory configuration. Tests cover canonicalization,
reconciliation no-ops, removal/reactivation, source isolation,
concurrent startup and tenant inserts, cross-tenant reuse, RPC
conversion, filtering, and request guards.

This supports NVIDIA#3884

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

chet commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@chet, I’ll perform a complete re-review of #4031.

🐇🔍

✅ 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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@rest-api/proto/core/src/v1/nico_nico.proto`:
- Around line 9451-9474: Add the repository-standard pagination request fields
to SitePrefixSearchFilter and a continuation/next-page field to
SitePrefixIdList, matching the established FindResourceNameIds and
FindResourceNamesByIds API pattern. Update the SitePrefix lookup contract so
FindSitePrefixIds returns bounded ID pages while FindSitePrefixesByIds remains
responsible for retrieving resource state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8fac0dec-341c-47a7-a1a5-8a6ec92e224c

📥 Commits

Reviewing files that changed from the base of the PR and between 1165819 and 656d696.

⛔ Files ignored due to path filters (3)
  • rest-api/proto/core/gen/v1/common_nico.pb.go is excluded by !**/*.pb.go, !**/gen/**, !rest-api/**/*.pb.go
  • rest-api/proto/core/gen/v1/nico_nico.pb.go is excluded by !**/*.pb.go, !**/gen/**, !rest-api/**/*.pb.go
  • rest-api/proto/core/gen/v1/nico_nico_grpc.pb.go is excluded by !**/*.pb.go, !**/gen/**, !rest-api/**/*.pb.go, !rest-api/**/*_grpc.pb.go
📒 Files selected for processing (21)
  • crates/api-core/src/api.rs
  • crates/api-core/src/auth/internal_rbac_rules.rs
  • crates/api-core/src/handlers/mod.rs
  • crates/api-core/src/handlers/site_prefix.rs
  • crates/api-core/src/setup.rs
  • crates/api-core/src/tests/mod.rs
  • crates/api-core/src/tests/site_prefix.rs
  • crates/api-db/migrations/20260723120000_site_prefixes.sql
  • crates/api-db/src/lib.rs
  • crates/api-db/src/site_prefix.rs
  • crates/api-model/src/lib.rs
  • crates/api-model/src/site_prefix.rs
  • crates/rpc/build.rs
  • crates/rpc/proto/common.proto
  • crates/rpc/proto/forge.proto
  • crates/rpc/src/model/mod.rs
  • crates/rpc/src/model/site_prefix.rs
  • crates/uuid/src/lib.rs
  • crates/uuid/src/site_prefix/mod.rs
  • rest-api/proto/core/src/v1/common_nico.proto
  • rest-api/proto/core/src/v1/nico_nico.proto
🚧 Files skipped from review as they are similar to previous changes (19)
  • crates/uuid/src/lib.rs
  • crates/api-core/src/handlers/mod.rs
  • crates/api-model/src/lib.rs
  • crates/api-core/src/handlers/site_prefix.rs
  • crates/rpc/proto/common.proto
  • crates/api-db/src/lib.rs
  • crates/api-core/src/tests/mod.rs
  • crates/api-core/src/auth/internal_rbac_rules.rs
  • crates/api-core/src/api.rs
  • crates/rpc/src/model/mod.rs
  • crates/rpc/build.rs
  • crates/uuid/src/site_prefix/mod.rs
  • crates/rpc/proto/forge.proto
  • crates/api-core/src/setup.rs
  • crates/api-core/src/tests/site_prefix.rs
  • crates/api-db/migrations/20260723120000_site_prefixes.sql
  • crates/api-model/src/site_prefix.rs
  • crates/rpc/src/model/site_prefix.rs
  • crates/api-db/src/site_prefix.rs

Comment thread rest-api/proto/core/src/v1/nico_nico.proto
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.

1 participant