Skip to content

fix(rest-api): stop accepting unsupported ExpectedRack ID renames - #4461

Open
dev-tnsq wants to merge 3 commits into
NVIDIA:mainfrom
dev-tnsq:nicofix/4365-expected-rack-immutable
Open

fix(rest-api): stop accepting unsupported ExpectedRack ID renames#4461
dev-tnsq wants to merge 3 commits into
NVIDIA:mainfrom
dev-tnsq:nicofix/4365-expected-rack-immutable

Conversation

@dev-tnsq

Copy link
Copy Markdown

Related issues

  • Fixes #4365fix(rest-api): stop accepting unsupported ExpectedRack ID renames

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

Additional Notes

Problem

PATCH /expected-rack/{id} accepted a new rackId, wrote it to Cloud, then ran the UpdateExpectedRack workflow — which fails in Core because Core identifies expected racks by rack_id. The rename could never complete, and the Cloud row was mutated (then rolled back) before the failure surfaced.

Solution

Treat rackId as immutable on update, following the same boundary already applied to ExpectedMachine BMC MAC identity (expectedmachine.go). A changed value is rejected with 400 (validation.Errors{"rackId": "RackID cannot be changed after creation"}) after site-access checks and before any database write or workflow trigger. Omitted or identical values remain a no-op, and RackID is no longer passed into the DAO update input, so the update path is structurally incapable of a rename.

Only single PATCH ever accepted a rename; site-inventory-sync (NICo as source of truth) and the PUT /expected-rack/all ReplaceAll endpoint are unaffected.

Docs / generated code

OpenAPI updated (rackId marked deprecated in the update request schema, PATCH operation description) and sdk/standard regenerated.

Tests

Table-driven handler tests cover changed → 400, changed-to-existing → 400, identical → 200 (stored value preserved), and site-access-checked-before-identity → 403. A dedicated handler test asserts rejection happens without any DB mutation or workflow trigger. Model, DAO, and inventory-sync activity suites pass.

…IDIA#4365)

Make rackId immutable on PATCH /expected-rack/{id}. A changed value is rejected with 400 before any database mutation or workflow trigger, mirroring the ExpectedMachine BMC MAC identity boundary. Omitted or identical values remain a no-op, and RackID is no longer passed into the DAO update input so the update path is structurally incapable of a rename. OpenAPI marks rackId deprecated in the update request schema; sdk/standard regenerated.

Signed-off-by: Tanishq <tanishq160405@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 31, 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: 652a3fe2-9f00-4b24-8f60-b17404f96bfc

📥 Commits

Reviewing files that changed from the base of the PR and between e33d919 and 0695beb.

⛔ Files ignored due to path filters (1)
  • rest-api/sdk/standard/model_expected_rack_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
📒 Files selected for processing (1)
  • rest-api/openapi/spec.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • rest-api/openapi/spec.yaml

Summary by CodeRabbit

  • Bug Fixes

    • Expected Rack identifiers can no longer be changed through updates.
    • Attempts to rename an identifier return HTTP 400 with validation details and do not modify data or trigger workflows.
    • Existing identifiers may be omitted or re-sent unchanged.
  • Documentation

    • Updated API documentation to mark rackId as immutable and deprecated for compatibility.

Walkthrough

The Expected Rack PATCH handler rejects changed RackID values with HTTP 400 before database or workflow operations. Omitted or unchanged IDs remain valid. Tests and OpenAPI documentation reflect the immutable identifier contract.

Changes

Expected Rack ID Immutability

Layer / File(s) Summary
Immutable handler contract
rest-api/api/pkg/api/handler/expectedrack.go, rest-api/api/pkg/api/model/expectedrack.go, rest-api/api/pkg/api/model/expectedrack_test.go
The handler rejects changed RackID values and no longer sends RackID to the DAO. Model comments and validation tests describe the handler-enforced immutability.
Immutability validation
rest-api/api/pkg/api/handler/expectedrack_test.go
Tests cover changed, identical, and omitted IDs. They verify authorization ordering and confirm that rejected renames do not mutate the database or trigger workflows.
OpenAPI contract
rest-api/openapi/spec.yaml
The PATCH contract documents rackId as an immutable, deprecated compatibility field. Changed values return HTTP 400 before database mutation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • NVIDIA/infra-controller#4317: Both changes enforce immutability for identity fields in REST PATCH handlers and update related tests and API documentation.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the fix: rejecting unsupported Expected Rack ID renames.
Description check ✅ Passed The description accurately explains the bug, immutable-ID behavior, compatibility rules, documentation, and tests.
Linked Issues check ✅ Passed The changes satisfy the linked issue by rejecting renames before mutation, preserving omitted or unchanged IDs, updating OpenAPI, and adding tests.
Out of Scope Changes check ✅ Passed All reviewed changes support the linked issue and its objectives; no unrelated code changes are evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@thossain-nv thossain-nv added the rest-api Add this label when an issue or PR concerns NICo REST API label Jul 31, 2026 — with ChatGPT Codex Connector
@dev-tnsq
dev-tnsq marked this pull request as ready for review August 1, 2026 06:35
@dev-tnsq
dev-tnsq requested a review from a team as a code owner August 1, 2026 06:35
Copilot AI review requested due to automatic review settings August 1, 2026 06:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR closes the gap where PATCH /expected-rack/{id} would accept a changed rackId (attempting an unsupported rename), mutate the Cloud record, and then fail downstream because Core/Flow treat rackId as the identity key. The new behavior rejects rackId changes early (after site-access checks) and makes the update path structurally incapable of performing a rename.

Changes:

  • Enforce rackId immutability in the ExpectedRack PATCH handler and stop passing rackId through the DAO update input.
  • Update OpenAPI and regenerate the Go SDK to document/reflect the immutability and deprecation on the update request schema.
  • Expand unit tests to cover rename rejection, compatibility for identical/omitted rackId, and ordering relative to site-access checks (plus a dedicated “no mutation / no workflow” assertion for rename attempts).

Reviewed changes

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

Show a summary per file
File Description
rest-api/api/pkg/api/handler/expectedrack.go Rejects rackId changes with 400 and removes rackId from DAO update input.
rest-api/api/pkg/api/handler/expectedrack_test.go Adds coverage for rename rejection, identical-id compatibility, and pre-mutation/pre-workflow guarantees.
rest-api/api/pkg/api/model/expectedrack.go Clarifies API update-model semantics in comments for rackId immutability.
rest-api/api/pkg/api/model/expectedrack_test.go Updates validation test wording to reflect handler-enforced immutability.
rest-api/openapi/spec.yaml Documents rackId immutability for PATCH and marks rackId deprecated in the update request schema.
rest-api/sdk/standard/api_expected_rack.go Propagates PATCH documentation update into the generated SDK client.
rest-api/sdk/standard/model_expected_rack_update_request.go Propagates schema deprecation + immutability notes into the generated SDK model.
Files not reviewed (2)
  • rest-api/sdk/standard/api_expected_rack.go: Generated file
  • rest-api/sdk/standard/model_expected_rack_update_request.go: Generated file

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

Comment thread rest-api/api/pkg/api/handler/expectedrack.go

@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/openapi/spec.yaml`:
- Around line 24397-24399: Update the rackId schema description associated with
the deprecated field to document that providing JSON null also preserves the
stored rackId, alongside the existing omit-or-existing-value compatibility
behavior.
🪄 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: d3b74c68-d01b-45e3-a6c5-6fffbb6abe98

📥 Commits

Reviewing files that changed from the base of the PR and between 3e1b818 and 864f679.

⛔ Files ignored due to path filters (2)
  • rest-api/sdk/standard/api_expected_rack.go is excluded by !rest-api/sdk/standard/api_*.go
  • rest-api/sdk/standard/model_expected_rack_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
📒 Files selected for processing (5)
  • rest-api/api/pkg/api/handler/expectedrack.go
  • rest-api/api/pkg/api/handler/expectedrack_test.go
  • rest-api/api/pkg/api/model/expectedrack.go
  • rest-api/api/pkg/api/model/expectedrack_test.go
  • rest-api/openapi/spec.yaml

Comment thread rest-api/openapi/spec.yaml Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Tanishq <139997424+dev-tnsq@users.noreply.github.com>
@dev-tnsq

dev-tnsq commented Aug 1, 2026

Copy link
Copy Markdown
Author

@chet @thossain-nv , can u have a look at this

NVIDIA#4365)

The rackId property in ExpectedRackUpdateRequest accepts null; document that null preserves the stored value, matching the immutable-identity contract. Regenerates sdk/standard.

Signed-off-by: Tanishq <tanishq160405@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rest-api Add this label when an issue or PR concerns NICo REST API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(rest-api): stop accepting unsupported ExpectedRack ID renames

3 participants