Skip to content

fix(rest-api): Treat instance status consistently across reporting, filtering, and statistics#2342

Merged
nvlitagaki merged 10 commits into
NVIDIA:mainfrom
nvlitagaki:fix/instance-status-filter
Jun 12, 2026
Merged

fix(rest-api): Treat instance status consistently across reporting, filtering, and statistics#2342
nvlitagaki merged 10 commits into
NVIDIA:mainfrom
nvlitagaki:fix/instance-status-filter

Conversation

@nvlitagaki

Copy link
Copy Markdown
Contributor

Description

Previously, when the status of an individual instance was reported, the value given was derived from both the status and powerStatus fields in the database. However, when the list of instances was filtered or the summary of instance counts by status was reported, only the status field was considered. I've updated logic so that the derived or 'aggregate' status is used in all places.

The summary of instances by status that we send as part of tenant statistics had gotten out of alignment with the set of statuses used for instances. To avoid future trouble, I introduced the more strongly typed InstanceStatusCounts at the db layer and just pass it directly to the API rather than having the API specific APIInstanceStats that had to be kept in sync with the logic of the Instance DAO function GetCountByStatus. I also updated the openAPI spec to match.

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

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

NVBug 5844304

@nvlitagaki nvlitagaki requested a review from a team as a code owner June 9, 2026 20:25
@nvlitagaki nvlitagaki marked this pull request as draft June 9, 2026 20:26
@copy-pr-bot

copy-pr-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 456c3376-b7a7-47de-8d35-6f1ecbd6fb3a

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
rest-api/db/pkg/db/model/instance.go (1)

654-669: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Search still matches the raw lifecycle status.

Statuses now filters on instanceAggregatedStatusSQL(), but the free-text path below still tokenizes and matches i.status. A ready instance with power_status='Rebooting' will therefore count/filter as Rebooting yet remain searchable as Ready, which keeps status handling inconsistent in the same endpoint.

🤖 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 `@rest-api/db/pkg/db/model/instance.go` around lines 654 - 669, The free-text
search still references the raw column i.status, causing inconsistencies with
the aggregated-status filtering; update the search clause in the
NormalizeSearchQuery handling (where searchQuery, searchTokens, ok are used) to
use the same instanceAggregatedStatusSQL() expression instead of i.status—ensure
both the to_tsvector concatenation and the WhereOr ILIKE checks replace i.status
with the aggregated-status SQL (or include the aggregated expression) so
full-text and ILIKE searches match the same lifecycle value used by the Statuses
filter.
rest-api/api/pkg/api/model/instance.go (1)

1904-1923: ⚠️ Potential issue | 🟡 Minor

Use aggregated instance status in NewAPIInstanceSummary
NewAPIInstanceSummary sets APIInstanceSummary.Status to dbist.Status (raw) while nearby logic uses cdbm.AggregatedInstanceStatus(dbinst.Status, dbinst.PowerStatus) (line ~1832). Update the summary to use the aggregated status as well (instead of the raw status) to keep list/detail reporting consistent.

🤖 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 `@rest-api/api/pkg/api/model/instance.go` around lines 1904 - 1923,
NewAPIInstanceSummary currently assigns APIInstanceSummary.Status directly from
dbist.Status; change this to compute and assign the aggregated status using
cdbm.AggregatedInstanceStatus(dbist.Status, dbist.PowerStatus) so list/detail
reporting matches other code paths. In function NewAPIInstanceSummary replace
the Status assignment to call cdbm.AggregatedInstanceStatus with dbist.Status
and dbist.PowerStatus and set ins.Status to that result (ensure the cdbm symbol
is in scope if needed).
🤖 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/db/pkg/db/model/instance.go`:
- Around line 209-221: Add a Terminated count to the API struct and handle the
terminated status in the counting function: extend the InstanceStatusCounts
struct with a Terminated int field and update GetCountByStatus to include an
InstanceStatusTerminated branch that increments the new Terminated field instead
of falling through to default/Unknown; ensure any callers that build or
serialize InstanceStatusCounts (and any tests) are updated to expect the new
field so terminated instances are correctly reported rather than lumped into
Unknown.

---

Outside diff comments:
In `@rest-api/api/pkg/api/model/instance.go`:
- Around line 1904-1923: NewAPIInstanceSummary currently assigns
APIInstanceSummary.Status directly from dbist.Status; change this to compute and
assign the aggregated status using cdbm.AggregatedInstanceStatus(dbist.Status,
dbist.PowerStatus) so list/detail reporting matches other code paths. In
function NewAPIInstanceSummary replace the Status assignment to call
cdbm.AggregatedInstanceStatus with dbist.Status and dbist.PowerStatus and set
ins.Status to that result (ensure the cdbm symbol is in scope if needed).

In `@rest-api/db/pkg/db/model/instance.go`:
- Around line 654-669: The free-text search still references the raw column
i.status, causing inconsistencies with the aggregated-status filtering; update
the search clause in the NormalizeSearchQuery handling (where searchQuery,
searchTokens, ok are used) to use the same instanceAggregatedStatusSQL()
expression instead of i.status—ensure both the to_tsvector concatenation and the
WhereOr ILIKE checks replace i.status with the aggregated-status SQL (or include
the aggregated expression) so full-text and ILIKE searches match the same
lifecycle value used by the Statuses filter.
🪄 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: 47d00d56-05e4-466d-acaa-5f9f03bc0089

📥 Commits

Reviewing files that changed from the base of the PR and between e867f98 and 61c9fe7.

📒 Files selected for processing (10)
  • rest-api/api/pkg/api/handler/tenant.go
  • rest-api/api/pkg/api/model/instance.go
  • rest-api/api/pkg/api/model/instance_test.go
  • rest-api/api/pkg/api/model/tenant.go
  • rest-api/db/pkg/db/model/instance.go
  • rest-api/db/pkg/db/model/instance_test.go
  • rest-api/docs/index.html
  • rest-api/openapi/spec.yaml
  • rest-api/sdk/standard/model_instance_count_by_status.go
  • rest-api/sdk/standard/model_tenant_identity_config_create_or_update_request.go
💤 Files with no reviewable changes (2)
  • rest-api/sdk/standard/model_tenant_identity_config_create_or_update_request.go
  • rest-api/api/pkg/api/model/instance_test.go

Comment thread rest-api/db/pkg/db/model/instance.go
Filter and count instances using aggregated lifecycle and power status so
list queries and tenant stats match the status returned by the API.

Signed-off-by: Leah Itagaki <litagaki@nvidia.com>
@nvlitagaki nvlitagaki force-pushed the fix/instance-status-filter branch from 61c9fe7 to 1caa5d2 Compare June 10, 2026 19:33
@nvlitagaki nvlitagaki marked this pull request as ready for review June 10, 2026 19:34
@github-actions

Copy link
Copy Markdown

@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-10 19:38:18 UTC | Commit: e026f18

@nvlitagaki nvlitagaki requested a review from thossain-nv June 10, 2026 19:38
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
nico-flow 126 14 55 44 5 8
nico-nsm 133 11 45 66 11 0
nico-psm 128 14 57 44 5 8
nico-rest-cert-manager 105 6 52 35 4 8
nico-rest-db 126 14 55 44 5 8
nico-rest-site-agent 125 14 55 44 4 8
nico-rest-site-manager 112 7 53 40 4 8
nico-rest-workflow 128 14 57 44 5 8
TOTAL 983 94 429 361 43 56

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

Comment thread rest-api/api/pkg/api/model/tenant.go Outdated
// Instance is the data structure to capture API representation of an Instance Stats associated with tenant
Instance APIInstanceStats `json:"instance"`
// Instance holds aggregated instance status counts for the tenant.
Instance cdbm.InstanceStatusCounts `json:"instance"`

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.

This will break existant pattern, cdbm.InstanceStatusCounts. Instead, we can have APIInstanceStats and inside we can have cdbm.InstanceStatusCounts

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated

@nvlitagaki nvlitagaki force-pushed the fix/instance-status-filter branch from dc2f56b to 2bfe41d Compare June 12, 2026 14:53
@nvlitagaki nvlitagaki force-pushed the fix/instance-status-filter branch from 57a5618 to 9f349c3 Compare June 12, 2026 15:06
@nvlitagaki nvlitagaki merged commit 8213a1a into NVIDIA:main Jun 12, 2026
94 checks passed

// AggregatedInstanceStatus returns the status reported by the API by
// combining lifecycle status with power status when the Instance is Ready.
func AggregatedInstanceStatus(status string, powerStatus *string) string {

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.

This would be better as GetAggregatedStatus receiver function of Instance struct.

// Counts reflect the same status values returned on individual Instance objects
// (lifecycle status with Ready+power overrides applied via instanceAggregatedStatusSQL).

type InstanceStatusCounts struct {

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.

InstanceCountByStatus might be better.

TotalCount int64 `bun:"total_count"`
}

func instanceAggregatedStatusSQL() string {

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.

Better as instanceAggregatedStatusQuery

Unknown int `json:"unknown"`
}

type instanceStatusCountRow struct {

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.

Better as instanceStatusCountQueryResult

}

var results InstanceStatusCounts
for _, row := range statusQueryResults {

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.

This can be FromQueryResults receiver function of InstanceCountByStatus

}

// APIInstanceStat holds aggregated instance status counts at the API layer.
type APIInstanceStat = cdbm.InstanceStatusCounts

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.

This should be called APIInstanceStats (missing s) and I'd leave it in the Instance model.

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.

3 participants