Skip to content

fix(rest-api): Prevent user from updating ExpectedRack rackId after creation - #4461

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

fix(rest-api): Prevent user from updating ExpectedRack rackId after creation#4461
dev-tnsq wants to merge 5 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

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (1)
  • rest-api/docs/index.html
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cfbef504-6a0b-453c-bdfa-d122f652b09e

📥 Commits

Reviewing files that changed from the base of the PR and between b262c12 and 9715f98.

📒 Files selected for processing (1)
  • rest-api/docs/index.html

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Summary by CodeRabbit

  • Bug Fixes

    • Expected Rack identifiers can no longer be changed through updates.
    • Rename attempts 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

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states that ExpectedRack rackId updates are prevented after creation.
Description check ✅ Passed The description accurately explains the rackId immutability fix, validation order, compatibility behavior, documentation, and tests.
Linked Issues check ✅ Passed The changes satisfy issue #4365 by rejecting rackId changes before mutation, preserving omitted or identical values, updating OpenAPI, and adding tests.
Out of Scope Changes check ✅ Passed All reviewed changes support rackId immutability, validation, documentation, SDK generation, or regression testing for ExpectedRack updates.
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>
@thossain-nv thossain-nv changed the title fix(rest-api): stop accepting unsupported ExpectedRack ID renames fix(rest-api): Prevent user from updating ExpectedRack rackId after creation Aug 3, 2026

@thossain-nv thossain-nv 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.

Looks good to me, thanks @dev-tnsq @chet Would you please take a look as well?

Comment thread rest-api/openapi/spec.yaml Outdated

For single updates (PATCH /expected-rack/{id}), the `id` field is optional in the body and will be ignored if provided (the `id` from the URL path is used).

The `rackId` field is immutable on update — omit it or provide the existing value. Renaming an Expected Rack is not supported.

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.

I would omit the follow up Renaming an Expected Rack is not supported. In NICo REST, rename indicates changing the name attribute of a resource.

@dev-tnsq dev-tnsq Aug 3, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

thanks for the review, @thossain-nv! You're right that in NICo REST, 'rename' refers to the name attribute, so that phrasing was misleading. I've omitted it in the latest commit (b262c12).

…ption (NVIDIA#4365)

In NICo REST, rename refers to changing the name attribute, not rackId. Remove the phrase from the request schema description and regenerate the SDK.

Signed-off-by: Tanishq <tanishq160405@gmail.com>
@thossain-nv

Copy link
Copy Markdown
Contributor

/ok to test b262c12

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Aug 3, 2026

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-08-03 18:12:56 UTC | Commit: b262c12

…VIDIA#4365)

The ExpectedRackUpdateRequest rackId property description changed in the spec; rebuild rest-api/docs/index.html via make publish-openapi.

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