Skip to content

chore: Implementing layered proto conversion for VPC handlers#505

Open
chet wants to merge 1 commit intoNVIDIA:mainfrom
chet:proto-vpc-receivers-followup
Open

chore: Implementing layered proto conversion for VPC handlers#505
chet wants to merge 1 commit intoNVIDIA:mainfrom
chet:proto-vpc-receivers-followup

Conversation

@chet
Copy link
Copy Markdown
Contributor

@chet chet commented May 7, 2026

Description

Implements a layered convention for proto-conversion methods that the rest of the proto handling rollout will adopt. This was already done for Expected* components, but VPC had some additional bits that I was fiddling with (I did #501 but that was some stuff to be shared across vpc, vpcprefix, and vpcpeering).

All said, this splits proto conversion into clear layers, and applies to vpc handlers:

  • A primary ToProto/FromProto on the DB entity.
  • Followed by ToProto on each API request type for request-shape conversion.
  • With entity-level methods for handlers with no API request body (e.g. delete).

AGENTS.md has been further updated to document this layering.

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

Implements a layered convention for proto-conversion methods that the rest of the proto handling rollout will adopt. This was already done for `Expected*` components, but VPC had some additional bits that I was fiddling with (I did NVIDIA#501 but that was some stuff to be shared across `vpc`, `vpcprefix`, and `vpcpeering`).

All said, this splits proto conversion into clear layers, and applies to `vpc` handlers:
- A primary `ToProto`/`FromProto` on the DB entity.
- Followed by `ToProto` on each API request type for request-shape conversion.
- With entity-level methods for handlers with no API request body (e.g. delete).

`AGENTS.md` has been further updated to document this layering.

Tests added!

Signed-off-by: Chet Nichols III <chetn@nvidia.com>
@chet chet requested a review from a team as a code owner May 7, 2026 23:17
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack

Summary by CodeRabbit

  • Refactor

    • Consolidated VPC creation and update request handling for improved consistency and maintainability.
  • Documentation

    • Enhanced proto conversion standards with detailed enumerated rules and reference implementation examples.
  • Tests

    • Expanded unit test coverage for VPC request conversion methods to ensure reliability.

Walkthrough

This PR refactors VPC proto conversion methods to follow a centralized, layered pattern: DB entities provide canonical entity ↔ proto conversion (ToProto/FromProto), API request models build workflow requests using the entity conversions, and handlers invoke handlers through API converters rather than inline request assembly.


Changes

VPC Proto Conversion Centralization

Layer / File(s) Summary
DB Model Entity ↔ Proto Conversion
db/pkg/db/model/vpc.go, db/pkg/db/model/vpc_test.go
Vpc.ToProto() provides canonical conversion to workflow proto, mapping IDs (with site scope), core fields, metadata, and conditional NVLink partition. Vpc.FromProto() implements inverse mapping with nil-proto no-op, parse-tolerant ID updates, and full replacement of optional metadata-derived fields. Removed ToUpdateRequestProto().
API Request Proto Conversion
api/pkg/api/model/vpc.go, api/pkg/api/model/vpc_test.go
APIVpcCreateRequest.ToProto(vpc, nwvt, vni, routingProfile) builds VpcCreationRequest from DB entity and handler-derived network/routing parameters. APIVpcUpdateRequest.ToProto(vpc) builds VpcUpdateRequest from DB entity. Both delegate entity serialization to Vpc.ToProto().
Handler Integration
api/pkg/api/handler/vpc.go
CreateVPC and UpdateVPC handlers now use apiRequest.ToProto() to construct Temporal workflow requests, removing inline request assembly, metadata population, and NVLink partition logic from handler code.
Proto Conversion Conventions
AGENTS.md
Documented proto conversion rules: receiver-based entity ↔ proto mappings, request-level ToProto methods, entity-only delete/maintenance request generation, side-input handling via credential structs, sub-message helper naming, and NewAPIX wrappers. Vpc identified as reference implementation for rules 1–3.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: implementing layered proto conversion methods for VPC handlers, which aligns with the primary refactoring focus across all modified files.
Description check ✅ Passed The description comprehensively explains the layered proto-conversion architecture being implemented, references prior related work (#501), documents the testing approach, and identifies affected services (API and DB).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 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 23:19:11 UTC | Commit: d14c97a

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: 2

🤖 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 `@AGENTS.md`:
- Around line 189-197: The doc overstates FromProto's “leave receiver unchanged
on parse failure” guarantee; update the AGENTS.md text for the ToProto/FromProto
contract to explicitly state that FromProto treats a nil proto as a no-op and
generally does not modify existing fields on parse errors, but that optional
pointer fields and other explicitly-cleared fields may be reset when the proto
contains invalid optional values (e.g., the Vpc reference implementation clears
NVLinkLogicalPartitionID on an invalid UUID). Mention FromProto and
Vpc/NVLinkLogicalPartitionID by name so implementers know which fields may be
cleared vs preserved.

In `@api/pkg/api/model/vpc.go`:
- Around line 232-247: The current APIVpcUpdateRequest.ToProto always takes
NetworkSecurityGroupId from the merged DB vpc, which loses explicit clears when
asur.NetworkSecurityGroupID is set to an empty string; modify
APIVpcUpdateRequest.ToProto so it prefers the API request override when
asur.NetworkSecurityGroupID != nil (using its value, which may be ""), and falls
back to vpc.ToProto().NetworkSecurityGroupId only when
asur.NetworkSecurityGroupID is nil; update the returned
cwssaws.VpcUpdateRequest.NetworkSecurityGroupId accordingly.
🪄 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: 694f1f3c-6dc8-4e3d-9f52-5d54788f2f2f

📥 Commits

Reviewing files that changed from the base of the PR and between f02eabc and d14c97a.

📒 Files selected for processing (6)
  • AGENTS.md
  • api/pkg/api/handler/vpc.go
  • api/pkg/api/model/vpc.go
  • api/pkg/api/model/vpc_test.go
  • db/pkg/db/model/vpc.go
  • db/pkg/db/model/vpc_test.go

Comment thread AGENTS.md
Comment on lines +189 to +197
1. **Primary entity ↔ proto entity** lives on the DB model:
`func (m *T) ToProto(...) *protoT` and
`func (m *T) FromProto(p *protoT, ...)` — symmetric pair, defined
together. `FromProto` mutates the receiver, treats a `nil` proto as a
no-op, and returns no error (callers pre-validate anything risky like
UUID strings, and the method leaves the receiver field unchanged on
parse failure). Optional pointer fields are explicitly cleared when
the proto omits them, so `FromProto` is a clean reset rather than a
partial merge.
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Tighten the FromProto parse-failure contract.

This section says parse failures leave receiver fields unchanged, but the new Vpc reference implementation clears NVLinkLogicalPartitionID when the proto carries an invalid UUID. Please narrow this wording to the fields that truly preserve prior state, or document invalid optional values as clears so future implementations do not inherit the wrong contract.

🤖 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 `@AGENTS.md` around lines 189 - 197, The doc overstates FromProto's “leave
receiver unchanged on parse failure” guarantee; update the AGENTS.md text for
the ToProto/FromProto contract to explicitly state that FromProto treats a nil
proto as a no-op and generally does not modify existing fields on parse errors,
but that optional pointer fields and other explicitly-cleared fields may be
reset when the proto contains invalid optional values (e.g., the Vpc reference
implementation clears NVLinkLogicalPartitionID on an invalid UUID). Mention
FromProto and Vpc/NVLinkLogicalPartitionID by name so implementers know which
fields may be cleared vs preserved.

Comment thread api/pkg/api/model/vpc.go
Comment on lines +232 to +247
// ToProto builds the workflow request that pushes this Update's
// merged-into-DB state to a Site. The persisted `vpc` is the source of
// the wire fields because the handler has already merged the request's
// (sparse) update fields into the entity by the time this is called;
// sending the post-merge state matches the pre-existing handler
// behaviour and keeps unchanged fields populated. The handler may
// further set `DefaultNvlinkLogicalPartitionId` on the returned
// request when the API request changes that field.
func (asur APIVpcUpdateRequest) ToProto(vpc *cdbm.Vpc) *cwssaws.VpcUpdateRequest {
vpcProto := vpc.ToProto()
return &cwssaws.VpcUpdateRequest{
Id: vpcProto.Id,
NetworkSecurityGroupId: vpcProto.NetworkSecurityGroupId,
Metadata: vpcProto.Metadata,
}
}
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve explicit NSG clears in the update proto.

ToProto currently serializes NetworkSecurityGroupId only from the post-merge DB vpc. On the networkSecurityGroupId: "" path, the handler clears that DB field before calling this helper, so the workflow request gets nil instead of "" and the Site never sees the detach. This helper needs to let the request override the DB value when asur.NetworkSecurityGroupID != nil.

Suggested fix
 func (asur APIVpcUpdateRequest) ToProto(vpc *cdbm.Vpc) *cwssaws.VpcUpdateRequest {
 	vpcProto := vpc.ToProto()
-	return &cwssaws.VpcUpdateRequest{
+	req := &cwssaws.VpcUpdateRequest{
 		Id:                     vpcProto.Id,
 		NetworkSecurityGroupId: vpcProto.NetworkSecurityGroupId,
 		Metadata:               vpcProto.Metadata,
 	}
+	if asur.NetworkSecurityGroupID != nil {
+		req.NetworkSecurityGroupId = asur.NetworkSecurityGroupID
+	}
+	return req
 }

Based on learnings: Per-API-request → proto request conversion lives on the API request type.

🤖 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 `@api/pkg/api/model/vpc.go` around lines 232 - 247, The current
APIVpcUpdateRequest.ToProto always takes NetworkSecurityGroupId from the merged
DB vpc, which loses explicit clears when asur.NetworkSecurityGroupID is set to
an empty string; modify APIVpcUpdateRequest.ToProto so it prefers the API
request override when asur.NetworkSecurityGroupID != nil (using its value, which
may be ""), and falls back to vpc.ToProto().NetworkSecurityGroupId only when
asur.NetworkSecurityGroupID is nil; update the returned
cwssaws.VpcUpdateRequest.NetworkSecurityGroupId accordingly.

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

Comment thread db/pkg/db/model/vpc.go
} else {
vpc.NVLinkLogicalPartitionID = nil
}
if proto.Metadata != nil {
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.

Can we check name from Metadata in case if proto.Name is nill or empty?

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