Skip to content

feat(rest-api): Enhance get-all VPC peering filtering and peer tenant visibility#2867

Open
hwadekar-nv wants to merge 3 commits into
NVIDIA:mainfrom
hwadekar-nv:feat/enhance-vpc-peering
Open

feat(rest-api): Enhance get-all VPC peering filtering and peer tenant visibility#2867
hwadekar-nv wants to merge 3 commits into
NVIDIA:mainfrom
hwadekar-nv:feat/enhance-vpc-peering

Conversation

@hwadekar-nv

@hwadekar-nv hwadekar-nv commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

#2089

The get-all VPC peering endpoint only supported filtering by siteId and isMultiTenant, so users could not narrow results by status, a specific VPC, or a linked peer tenant. For multi-tenant peerings, the response also did not show which tenant owned each VPC.

  • Added status, vpcId, and peerTenantId query parameters on GET /v2/org/{org}/nico/vpc-peering, including a new PeerTenantIDs DB filter separate from authorization-scoped tenant filtering.
  • Exposed vpc1TenantId and vpc2TenantId in the API response so clients can identify peer tenants without extra lookups.
  • Unit test
  • Updated the OpenAPI spec and regenerated the Go SDK to match the new filters and response fields.

Type of Change

  • Add - New feature or capability

Testing

  • Unit tests added/updated

@hwadekar-nv hwadekar-nv requested a review from nvlitagaki June 25, 2026 00:04
@hwadekar-nv hwadekar-nv self-assigned this Jun 25, 2026
@hwadekar-nv hwadekar-nv requested a review from a team as a code owner June 25, 2026 00:04
@coderabbitai

coderabbitai Bot commented Jun 25, 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: 5a84ad79-199a-4ebf-b1eb-1e0cbdaaca0b

📥 Commits

Reviewing files that changed from the base of the PR and between d9962df and 2d724fe.

⛔ Files ignored due to path filters (4)
  • rest-api/sdk/standard/api_vpc_peering.go is excluded by !rest-api/sdk/standard/api_*.go
  • rest-api/sdk/standard/client.go is excluded by !rest-api/sdk/standard/client.go
  • rest-api/sdk/standard/model_interface.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_interface_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
📒 Files selected for processing (3)
  • rest-api/api/pkg/api/handler/vpcpeering.go
  • rest-api/api/pkg/api/handler/vpcpeering_test.go
  • rest-api/openapi/spec.yaml
✅ Files skipped from review due to trivial changes (1)
  • rest-api/openapi/spec.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • rest-api/api/pkg/api/handler/vpcpeering_test.go
  • rest-api/api/pkg/api/handler/vpcpeering.go

Summary by CodeRabbit

  • New Features
    • Added peering list query filters for status, vpcId, and peerTenantId.
    • Peering responses now include vpc1TenantId and vpc2TenantId (when available).
  • Bug Fixes
    • Improved filtering and validation behavior, returning correct error codes for invalid filter values and missing records.
    • Ensured peering results include both VPC sides for consistent filtering and response details.
  • Documentation
    • Updated the API specification with the new query parameters and response fields.
  • Tests
    • Expanded coverage for the new filters and response tenant-id fields.

Walkthrough

The PR adds VPC peering list filters for status, VPC ID, and peer tenant ID. It also returns tenant IDs for both peered VPCs and filters peerings by either side’s owning tenant.

Changes

VPC peering API and persistence updates

Layer / File(s) Summary
Contract and response model
rest-api/openapi/spec.yaml, rest-api/api/pkg/api/model/vpcpeering.go, rest-api/api/pkg/api/model/vpcpeering_test.go
status, vpcId, and peerTenantId are added to the peering query contract, and vpc1TenantId/vpc2TenantId are added to the peering response model and covered by model tests.
DAO peer-tenant filtering
rest-api/db/pkg/db/model/vpcpeering.go, rest-api/db/pkg/db/model/vpcpeering_test.go
VpcPeeringFilterInput gains PeerTenantIDs, and the SQL builder/test coverage filters peerings by either VPC owner tenant.
Handler filters and relation loading
rest-api/api/pkg/api/handler/vpcpeering.go, rest-api/api/pkg/api/handler/vpcpeering_test.go
The peering handlers validate the new query parameters, resolve VPC and tenant IDs, force Vpc1/Vpc2 relation loading, and the handler tests cover the new filters and tenant-id assertions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed The title clearly summarizes the main change: expanded VPC peering filtering and tenant visibility.
Description check ✅ Passed The description accurately describes the filtering and response-field updates in the change set.
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.

@hwadekar-nv hwadekar-nv force-pushed the feat/enhance-vpc-peering branch from 4c4191a to 55e5ce7 Compare June 25, 2026 00:05
@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

🔍 Container Scan Summary

No Grype artifacts were found to aggregate.

@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-06-25 00:07:22 UTC | Commit: 4c4191a

@nvlitagaki

nvlitagaki commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Exposing vpc1TenantId and vpc2TenantId is helpful so users know what filterable values are for VPC peerings, but these UUIDs are not easily understood by users. We need something more user-friendly to be shown additionally, like the orgDisplayName for the tenant. We could also fall back to just the org value if the tenant's org doesn't have the orgDisplayName populated.

@hwadekar-nv hwadekar-nv force-pushed the feat/enhance-vpc-peering branch from bfa3732 to d9962df Compare June 25, 2026 17:31

@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: 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 `@rest-api/api/pkg/api/handler/vpcpeering.go`:
- Around line 614-621: The relation preload logic in the VPC peering handler is
too narrowly gated by filterInput.VpcIDs and filterInput.PeerTenantIDs, which
can leave vpc1TenantId and vpc2TenantId unset in normal list responses. Update
the includeRelations handling in the vpc peering list path so Vpc1RelationName
and Vpc2RelationName are always loaded whenever the response includes tenant ID
fields, keeping the response consistent with the OpenAPI contract and preserving
compatibility.
- Around line 563-578: The peer tenant query handling in the VPC peering handler
only reads a single `peerTenantId`, so repeated query values are dropped and the
`PeerTenantIDs` filter is not populated consistently. Update the `Get`/query
parsing logic in `vpcpeering.go` to read all `peerTenantId` values from the
request, resolve each one through `common.GetTenantFromIDString`, and append
valid tenant IDs into `filterInput.PeerTenantIDs` while preserving the existing
invalid/not-found/error responses and `logger.Error` 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: 882a2acf-2c0d-4f35-a284-ff78d73528ab

📥 Commits

Reviewing files that changed from the base of the PR and between 55e5ce7 and d9962df.

⛔ Files ignored due to path filters (33)
  • rest-api/sdk/standard/api_vpc_peering.go is excluded by !rest-api/sdk/standard/api_*.go
  • rest-api/sdk/standard/client.go is excluded by !rest-api/sdk/standard/client.go
  • rest-api/sdk/standard/model_batch_instance_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_machine.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_machine_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_machine_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_power_shelf.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_power_shelf_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_power_shelf_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_rack.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_rack_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_rack_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_switch.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_switch_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_expected_switch_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_infini_band_partition.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_infini_band_partition_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_infini_band_partition_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_instance.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_instance_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_instance_type.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_instance_type_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_instance_type_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_instance_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_machine.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_machine_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_network_security_group.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_network_security_group_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_network_security_group_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_vpc.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_vpc_create_request.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_vpc_peering.go is excluded by !rest-api/sdk/standard/model_*.go
  • rest-api/sdk/standard/model_vpc_update_request.go is excluded by !rest-api/sdk/standard/model_*.go
📒 Files selected for processing (7)
  • rest-api/api/pkg/api/handler/vpcpeering.go
  • rest-api/api/pkg/api/handler/vpcpeering_test.go
  • rest-api/api/pkg/api/model/vpcpeering.go
  • rest-api/api/pkg/api/model/vpcpeering_test.go
  • rest-api/db/pkg/db/model/vpcpeering.go
  • rest-api/db/pkg/db/model/vpcpeering_test.go
  • rest-api/openapi/spec.yaml
🚧 Files skipped from review as they are similar to previous changes (6)
  • rest-api/db/pkg/db/model/vpcpeering_test.go
  • rest-api/openapi/spec.yaml
  • rest-api/api/pkg/api/handler/vpcpeering_test.go
  • rest-api/api/pkg/api/model/vpcpeering.go
  • rest-api/db/pkg/db/model/vpcpeering.go
  • rest-api/api/pkg/api/model/vpcpeering_test.go

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

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

Generally asking for small changes, but adding a more user-legible way of identifying the tenant is a must.

Comment on lines +548 to +554
vpc, verr := common.GetVpcFromIDString(ctx, nil, vpcIDStr, nil, gavph.dbSession)
if verr != nil {
if verr == common.ErrInvalidID {
return cutil.NewAPIErrorResponse(c, http.StatusBadRequest, fmt.Sprintf("Invalid VPC ID %v in query", vpcIDStr), nil)
}
if errors.Is(verr, cdb.ErrDoesNotExist) {
return cutil.NewAPIErrorResponse(c, http.StatusNotFound, fmt.Sprintf("Could not find VPC with ID %v specified in query", vpcIDStr), 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.

Please add logging for the first two error cases.

in: query
name: vpcId
required: false
description: Optional filter by VPC ID involved in the peering as either vpc1 or vpc2.

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.

For consistency, we should state that this can be repeated multiple times.

Comment on lines +568 to +572
if verr == common.ErrInvalidID {
return cutil.NewAPIErrorResponse(c, http.StatusBadRequest, fmt.Sprintf("Invalid peer tenant ID %v in query", peerTenantIDStr), nil)
}
if errors.Is(verr, cdb.ErrDoesNotExist) {
return cutil.NewAPIErrorResponse(c, http.StatusNotFound, fmt.Sprintf("Could not find tenant with ID %v specified in query", peerTenantIDStr), 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.

Please add logging here before these early returns

OrderBy: pageRequest.OrderBy,
}
vpcPeerings, total, err := vpcPeeringDAO.GetAll(ctx, nil, filterInput, vpcPeeringPageInput, qIncludeRelations)
includeRelations := vpcPeeringIncludeRelationsForTenantIDs(qIncludeRelations)

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.

Why are we sending the whole of vpc1 and vpc2 back in the response even when the client didn't ask for them? Agreed that we need to look at the VPCs to get the tenant values, but that doesn't mean we need to send all that extra information back unexpectedly.

expectedCount: 1,
},
{
name: "tenant admin 1 filters by pending status",

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.

It might be more useful to validate that filtering by multiple statuses works

Comment on lines +651 to +657
name: "tenant admin 1 filters by vpcId",
reqOrgName: tnOrg1,
queryParams: map[string]string{"vpcId": vpc1.ID.String()},
user: tnu1,
expectedStatus: http.StatusOK,
expectedCount: 3,
},

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.

Since all the created peerings have vpc1 as the first vpc, this doesn't really help test that the filter works regardless of whether the vpc specified in the filter is the first vpc or the second. It would be good to have a test case that covers that.

}

// Get peerTenantId from query param
if peerTenantIDStr := c.QueryParam("peerTenantId"); peerTenantIDStr != "" {

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.

Any particular reason for not supporting multiple peerTenantID values?

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