Skip to content

chore: Add FromProto receivers for ExpectedMachine, PowerShelf, Switch, Rack#500

Merged
chet merged 2 commits intoNVIDIA:mainfrom
chet:proto-expected-fromproto-receivers
May 7, 2026
Merged

chore: Add FromProto receivers for ExpectedMachine, PowerShelf, Switch, Rack#500
chet merged 2 commits intoNVIDIA:mainfrom
chet:proto-expected-fromproto-receivers

Conversation

@chet
Copy link
Copy Markdown
Contributor

@chet chet commented May 7, 2026

Description

Mirrors the existing ToProto receivers on the aforementioned DB models so that the inventory-reconciliation activities (across workflow/pkg/activity/expected*) no longer build proto-derived field maps inline. Each FromProto:

  • Treats a nil proto as a no-op.
  • Copies every persisted field that has a proto counterpart, so the receiver and ToProto stay symmetric.
  • Leaves the receiver's existing ID untouched on missing/invalid proto.Id (callers pre-validate the UUID before calling).
  • Accepts non-persisted side inputs as additional args (e.g. linkedMachineID for ExpectedMachine, since BMC-MAC to Machine resolution lives in the activity).

The duplicated getLabelsMapFromProto helper that lived in three sites is replaced by a new LabelsFromProtoMetadata in db/pkg/db/model, used by FromProto (and in tests). In this function, empty/nil distinction is preserved: nil metadata or nil labels yield nil map; empty labels yield an empty map (not nil), so callers can still distinguish "no labels reported" from "labels explicitly cleared".

I'm also dropping in an update to AGENTS.md that talks about "Proto conversion methods", so agent-assisted code changes going into the REST API adhere/support the modeling here: ToProto/FromProto receiver methods on DB and API models, plus the carve-outs for entities that map to multiple proto request types (e.g. Tenant) or produce reusable sub-messages (e.g. RackFilter.ToTargetSpec and APIRackGetAllRequest.ToFilters).

Tests added!

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

Type of Change

  • Feature - New feature or functionality (feat:)
  • Fix - Bug fixes (fix:)
  • Chore - Modification or removal of existing functionality (chore:)
  • Refactor - Refactoring of existing functionality (refactor:)
  • Docs - Changes in documentation or OpenAPI schema (docs:)
  • CI - Changes in GitHub workflows. Requires additional scrutiny (ci:)
  • Version - Issuing a new release version (version:)

Services Affected

  • API - API models or endpoints updated
  • Workflow - Workflow service updated
  • DB - DB DAOs or migrations updated
  • Site Manager - Site Manager updated
  • Cert Manager - Cert Manager updated
  • Site Agent - Site Agent updated
  • RLA - RLA service updated
  • Powershelf Manager - Powershelf Manager updated
  • NVSwitch Manager - NVSwitch Manager updated

Related Issues (Optional)

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

@chet chet requested a review from a team as a code owner May 7, 2026 05:48
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack

Walkthrough

Adds a proto-conversion guidance section, centralizes metadata label extraction, implements FromProto on ExpectedMachine/ExpectedPowerShelf/ExpectedRack/ExpectedSwitch, and refactors workflow activities/tests to use those FromProto methods instead of manual field mapping.

Changes

Proto Conversion Standardization and Activity Refactoring

Layer / File(s) Summary
Documentation and Standards
AGENTS.md
New "Proto conversion methods" guidance defines standardized receiver-method naming (ToProto, FromProto), required FromProto behavior, side-input conventions, and optional constructor wrappers.
Centralized Label Conversion Utility
db/pkg/db/model/common.go, db/pkg/db/model/common_test.go
Adds LabelsFromProtoMetadata to convert proto Metadata.Labels into map[string]string with nil vs empty-map semantics, key filtering, and value defaulting; table-driven tests added.
ExpectedMachine Proto Conversion
db/pkg/db/model/expectedmachine.go, db/pkg/db/model/expectedmachine_test.go
Adds FromProto to populate ExpectedMachine from cwssaws.ExpectedMachine (conditional UUID parse, pointer normalization, linkedMachineID assignment, labels via centralized helper); tests cover nil, invalid UUID, and full mapping.
ExpectedPowerShelf Proto Conversion
db/pkg/db/model/expectedpowershelf.go, db/pkg/db/model/expectedpowershelf_test.go
Adds FromProto to populate ExpectedPowerShelf (conditional UUID parse, empty BmcIpAddress → nil pointer, optional fields, labels); tests added.
ExpectedRack Proto Conversion
db/pkg/db/model/expectedrack.go, db/pkg/db/model/expectedrack_test.go
Adds FromProto to populate ExpectedRack (conditional RackID handling, RackProfileID from RackType, metadata→name/description/labels); tests added.
ExpectedSwitch Proto Conversion
db/pkg/db/model/expectedswitch.go, db/pkg/db/model/expectedswitch_test.go
Adds FromProto to populate ExpectedSwitch (conditional UUID parse, BmcIpAddress normalization, rack pointer handling, labels via helper); tests added.
ExpectedMachine Activity Refactoring
workflow/pkg/activity/expectedmachine/expectedmachine.go, workflow/pkg/activity/expectedmachine/expectedmachine_test.go
Replaces manual proto field extraction with reported.FromProto(...), removes local label helper, and updates create/update reconciliation to use reported (preserving nil→empty map semantics); tests updated.
ExpectedPowerShelf Activity Refactoring
workflow/pkg/activity/expectedpowershelf/expectedpowershelf.go, workflow/pkg/activity/expectedpowershelf/expectedpowershelf_test.go
Uses reported.FromProto in reconcile loop, removes local label helper, adds siteClientPool field to ManageExpectedPowerShelf, and updates create/update logic and tests to use reported-derived fields.
ExpectedRack Activity Refactoring
workflow/pkg/activity/expectedrack/expectedrack.go, workflow/pkg/activity/expectedrack/expectedrack_test.go
Uses reported.FromProto for create/update payloads, removes local label helper, and updates tests to centralized label extraction; retains nil-label clearing behavior.
ExpectedSwitch Activity Refactoring
workflow/pkg/activity/expectedswitch/expectedswitch.go, workflow/pkg/activity/expectedswitch/expectedswitch_test.go
Uses reported.FromProto, removes local label helper, and updates reconciliation to compare DB vs reported with nil→empty-map normalization to clear labels; tests updated.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.78% 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
Description check ✅ Passed The description is well-articulated, explaining the motivation (eliminating inline proto-field maps), implementation approach (FromProto receivers with nil-safety), and supporting changes (LabelsFromProtoMetadata helper, AGENTS.md documentation, comprehensive tests).
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 directly and specifically describes the main change: adding FromProto receiver methods for four Expected* DB model types, which is the primary objective of the changeset.

✏️ 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 and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

🔐 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-05-07 05:49:17 UTC | Commit: 5261ebe

@chet chet changed the title refactor: Add FromProto receivers for ExpectedMachine, ExpectedPowerShelf, ExpectedSwitch chore: Add FromProto receivers for ExpectedMachine, ExpectedPowerShelf, ExpectedSwitch May 7, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
db/pkg/db/model/common_test.go (1)

104-113: 💤 Low value

assert.Equal handles typed-nil maps — the explicit branch is redundant.

assert.Equal(t, tc.want, got) handles nil vs map[string]string(nil) correctly; the if tc.want == nil guard can be removed.

♻️ Simplification
-		if tc.want == nil {
-			assert.Nil(t, got)
-		} else {
-			assert.Equal(t, tc.want, got)
-		}
+		assert.Equal(t, tc.want, got)
🤖 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 `@db/pkg/db/model/common_test.go` around lines 104 - 113, The test's explicit
nil-check branch is redundant because assert.Equal handles typed nil maps;
simplify the loop in the test by removing the if tc.want == nil branch and
always call assert.Equal(t, tc.want, got) inside the t.Run closure so
LabelsFromProtoMetadata behavior is still verified without special-casing nil;
update the table-driven test in common_test.go accordingly, referencing the test
loop that calls LabelsFromProtoMetadata and uses assert.Equal.
🤖 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 `@db/pkg/db/model/expectedmachine.go`:
- Around line 185-188: The FromProto conversion in ExpectedMachine (method
ExpectedMachine.FromProto) fails to clear em.RackID when proto.RackId is nil,
leading to stale RackID values; change the logic so that if proto.RackId != nil
you set em.RackID = &proto.RackId.Id, otherwise explicitly set em.RackID = nil,
and add a unit test mirroring the fix in expectedswitch.go that verifies RackID
is cleared when proto.RackId is nil (use the same test pattern and assertions as
ExpectedSwitch.FromProto's test).

In `@db/pkg/db/model/expectedpowershelf.go`:
- Around line 176-179: The FromProto implementation for ExpectedPowerShelf
leaves eps.RackID unchanged when proto.RackId is nil, causing old values to
persist; update ExpectedPowerShelf.FromProto so that if proto.RackId is nil it
explicitly sets eps.RackID = nil, and if non-nil sets eps.RackID to a pointer to
proto.RackId.Id (mirroring the pattern used in ExpectedSwitch.FromProto and
ExpectedMachine.FromProto) to ensure the field is correctly cleared or assigned
based on the proto.

In `@db/pkg/db/model/expectedswitch.go`:
- Around line 183-186: The FromProto method for ExpectedSwitch currently only
assigns es.RackID when proto.RackId != nil, leaving old values intact; update
FromProto so that when proto.RackId is nil it explicitly sets es.RackID = nil
(mirror how other optional fields are handled), i.e., in the code handling
proto.RackId ensure an else branch that clears es.RackID; also add the suggested
test ("nil RackId clears a previously-set RackID") to verify a pre-populated
ExpectedSwitch with RackID gets cleared after FromProto is called with a nil
RackId.

---

Nitpick comments:
In `@db/pkg/db/model/common_test.go`:
- Around line 104-113: The test's explicit nil-check branch is redundant because
assert.Equal handles typed nil maps; simplify the loop in the test by removing
the if tc.want == nil branch and always call assert.Equal(t, tc.want, got)
inside the t.Run closure so LabelsFromProtoMetadata behavior is still verified
without special-casing nil; update the table-driven test in common_test.go
accordingly, referencing the test loop that calls LabelsFromProtoMetadata and
uses assert.Equal.
🪄 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: e360d92b-6bae-464f-bddb-0de91b8ba048

📥 Commits

Reviewing files that changed from the base of the PR and between 67a466b and 5261ebe.

📒 Files selected for processing (15)
  • AGENTS.md
  • db/pkg/db/model/common.go
  • db/pkg/db/model/common_test.go
  • db/pkg/db/model/expectedmachine.go
  • db/pkg/db/model/expectedmachine_test.go
  • db/pkg/db/model/expectedpowershelf.go
  • db/pkg/db/model/expectedpowershelf_test.go
  • db/pkg/db/model/expectedswitch.go
  • db/pkg/db/model/expectedswitch_test.go
  • workflow/pkg/activity/expectedmachine/expectedmachine.go
  • workflow/pkg/activity/expectedmachine/expectedmachine_test.go
  • workflow/pkg/activity/expectedpowershelf/expectedpowershelf.go
  • workflow/pkg/activity/expectedpowershelf/expectedpowershelf_test.go
  • workflow/pkg/activity/expectedswitch/expectedswitch.go
  • workflow/pkg/activity/expectedswitch/expectedswitch_test.go

Comment thread db/pkg/db/model/expectedmachine.go
Comment thread db/pkg/db/model/expectedpowershelf.go
Comment thread db/pkg/db/model/expectedswitch.go
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
nico-nsm 64 2 20 33 9 0
nico-psm 56 4 29 13 2 8
nico-rest-api 57 4 30 13 2 8
nico-rest-cert-manager 54 4 28 13 1 8
nico-rest-db 55 4 28 13 2 8
nico-rest-site-agent 54 4 28 13 1 8
nico-rest-site-manager 54 4 28 13 1 8
nico-rest-workflow 56 4 29 13 2 8
nico-rla 55 4 28 13 2 8
TOTAL 505 34 248 137 22 64

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

@chet chet changed the title chore: Add FromProto receivers for ExpectedMachine, ExpectedPowerShelf, ExpectedSwitch chore: Add FromProto receivers for Expected components May 7, 2026
…h, Rack

Mirrors the existing `ToProto` receivers on the aforementioned DB models so that the inventory-reconciliation activities (across workflow/pkg/activity/expected*) no longer build proto-derived field maps inline. Each `FromProto`:

- Treats a nil proto as a no-op.
- Copies every persisted field that has a proto counterpart, so the receiver and `ToProto` stay symmetric.
- Leaves the receiver's existing ID untouched on missing/invalid proto.Id (callers pre-validate the UUID before calling).
- Accepts non-persisted side inputs as additional args (e.g. `linkedMachineID` for `ExpectedMachine`, since BMC-MAC to Machine resolution lives in the activity).

The duplicated `getLabelsMapFromProto` helper that lived in three sites is replaced by a new `LabelsFromProtoMetadata` in `db/pkg/db/model`, used by `FromProto` (and in tests). In this function, empty/nil distinction is preserved: nil metadata or nil labels yield nil map; empty labels yield an empty map (not nil), so callers can still distinguish "no labels reported" from "labels explicitly cleared".

I'm also dropping in an update to `AGENTS.md` that talks about "*Proto conversion methods*", so agent-assisted code changes going into the REST API adhere/support the modeling here: `ToProto`/`FromProto` receiver methods on DB and API models, plus the carve-outs for entities that map to multiple proto request types (e.g. `Tenant`) or produce reusable sub-messages (e.g. `RackFilter.ToTargetSpec` and `APIRackGetAllRequest.ToFilters`).

Tests added!

Signed-off-by: Chet Nichols III <chetn@nvidia.com>
@chet chet force-pushed the proto-expected-fromproto-receivers branch from 5261ebe to f2e884f Compare May 7, 2026 06:43
@chet chet changed the title chore: Add FromProto receivers for Expected components chore: Add FromProto receivers for ExpectedMachine, PowerShelf, Switch, Rack May 7, 2026
Copy link
Copy Markdown
Contributor

@thossain-nv thossain-nv left a comment

Choose a reason for hiding this comment

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

This looks good, thanks @chet

@chet chet merged commit f02eabc into NVIDIA:main May 7, 2026
50 checks passed
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