Skip to content

chore(core): tenant_organization_id for OS must be optional to allow clean ownership attribution to tenant or provider#3689

Open
pbreton wants to merge 3 commits into
NVIDIA:mainfrom
pbreton:chore/make-tenant_organization_id-optional
Open

chore(core): tenant_organization_id for OS must be optional to allow clean ownership attribution to tenant or provider#3689
pbreton wants to merge 3 commits into
NVIDIA:mainfrom
pbreton:chore/make-tenant_organization_id-optional

Conversation

@pbreton

@pbreton pbreton commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Initial implementation of templated OS assumed that any core-created OS (using gRPC API) not existing on the REST layer would be considered as 'owned' by provider (vs tenant). tenant_organization_id is effectively ignored during reconciliation when being OS is added to REST db.
This provides a cleaner model allowing for provider and tenant owned templated OS when created on the core side (instead of provider-only):

  • if tenant_organization_id is present then it is considered tenant owned during reconciliation
  • if tenant_organization_id is absent then it is provider owned during reconciliation

Type of Change

  • Change - Changes in existing functionality

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

This is just the core/Rust side.

…clear separation of tenant and provider owned OS in core

Signed-off-by: Patrice Breton <pbreton@nvidia.com>
@pbreton
pbreton requested a review from a team as a code owner July 17, 2026 19:57
@pbreton
pbreton marked this pull request as draft July 17, 2026 19:57
@copy-pr-bot

copy-pr-bot Bot commented Jul 17, 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 Jul 17, 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: 074d6f1a-42b5-4b75-9c74-932406fc268d

📥 Commits

Reviewing files that changed from the base of the PR and between eb18a6a and c7c556f.

⛔ Files ignored due to path filters (1)
  • rest-api/proto/core/gen/v1/nico_nico.pb.go is excluded by !**/*.pb.go, !**/gen/**, !rest-api/**/*.pb.go
📒 Files selected for processing (2)
  • crates/api-db/src/operating_system.rs
  • rest-api/proto/core/src/v1/nico_nico.proto
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/api-db/src/operating_system.rs
  • rest-api/proto/core/src/v1/nico_nico.proto

Summary by CodeRabbit

  • New Features

    • Operating system definitions can now be created without an owning organization, supporting provider-owned definitions.
    • Organization ownership is optional across API requests, responses, CLI commands, and persistence.
    • CLI output safely displays a blank value when no organization is assigned.
  • Bug Fixes

    • Empty organization values are rejected while omitted values are accepted.
    • Optional organization ownership is preserved correctly when stored and retrieved.

Walkthrough

Operating system organization ownership is now optional across protobuf contracts, database storage, API creation, CLI arguments, display adapters, iPXE rendering, and associated tests. Omitted organizations persist as NULL; provided empty strings remain invalid.

Changes

Nullable organization ownership

Layer / File(s) Summary
Optional organization contracts and storage
crates/rpc/proto/forge.proto, rest-api/proto/core/src/v1/nico_nico.proto, crates/api-model/..., crates/api-db/..., crates/api-db/migrations/...
Organization identifiers are optional in API contracts and models, and the database org column accepts NULL.
Nullable organization persistence
crates/api-db/src/operating_system.rs, crates/api-db/src/instance.rs
Database creation and retrieval preserve omitted organizations as NULL and provided organizations as values.
API creation and rendering flow
crates/api-core/src/handlers/..., crates/api-core/src/ipxe.rs, crates/api-core/src/tests/..., crates/api-core/tests/integration/...
Creation accepts omitted organizations, rejects provided empty strings, and propagates optional values through rendering and integration tests.
CLI and web adapters
crates/admin-cli/src/operating_system/..., crates/api-web/src/operating_system.rs
CLI creation permits omitted organizations, while CLI and web displays render absent values as empty strings.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AdminCLI
  participant create_operating_system
  participant OperatingSystemDB
  participant operating_system_row_to_ipxe_script
  AdminCLI->>create_operating_system: submit optional tenant_organization_id
  create_operating_system->>create_operating_system: reject provided empty organization
  create_operating_system->>OperatingSystemDB: persist organization or NULL
  OperatingSystemDB-->>create_operating_system: return optional organization
  create_operating_system->>operating_system_row_to_ipxe_script: render operating system row
  operating_system_row_to_ipxe_script-->>AdminCLI: return rendered script data
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: making OS tenant ownership optional for tenant or provider attribution.
Description check ✅ Passed The description matches the changeset and explains the optional ownership semantics and core-side scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@pbreton

pbreton commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@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-07-17 20:03:35 UTC | Commit: eb18a6a

@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

🧹 Nitpick comments (2)
crates/api-core/src/handlers/operating_system.rs (1)

273-280: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the shared NicoError path for this validation.

This new user-input validation branch returns tonic::Status directly. Core handler guidance calls for NicoError::InvalidArgument converted with .into(), keeping error mapping consistent across handlers.

As per path instructions, handler validation should use uniform NicoError errors and .into() rather than raw Status.

🤖 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 `@crates/api-core/src/handlers/operating_system.rs` around lines 273 - 280,
Update the tenant_organization_id validation branch in the relevant
operating-system handler to return NicoError::InvalidArgument and convert it
with .into(), replacing the direct Status::invalid_argument construction while
preserving the existing validation message.

Source: Path instructions

crates/admin-cli/src/operating_system/create/args.rs (1)

39-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add worked after_long_help examples for the optional --org contract.

This change introduces two meaningful modes: omit --org for provider-owned definitions or provide it for tenant-owned definitions. Add the required EXAMPLES: help section with realistic invocations for both modes.

As per path instructions, admin CLI argument structs must include realistic worked examples for meaningful command modes.

🤖 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 `@crates/admin-cli/src/operating_system/create/args.rs` around lines 39 - 44,
Add an after_long_help section to the org argument definition with an EXAMPLES:
heading and realistic worked command invocations showing both modes: omitting
--org for provider-owned OS definitions and supplying --org for tenant-owned
definitions. Keep the existing optional org behavior and help text unchanged.

Source: Path instructions

🤖 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 `@crates/api-db/src/operating_system.rs`:
- Around line 421-443: Combine test_create_persists_null_org and
test_create_persists_org into one table-driven persistence test covering both
None and Some("acme") organization cases. Define explicit input and expected
organization values, then iterate each case through the existing create/get flow
while preserving assertions for both created.org and fetched.org.

---

Nitpick comments:
In `@crates/admin-cli/src/operating_system/create/args.rs`:
- Around line 39-44: Add an after_long_help section to the org argument
definition with an EXAMPLES: heading and realistic worked command invocations
showing both modes: omitting --org for provider-owned OS definitions and
supplying --org for tenant-owned definitions. Keep the existing optional org
behavior and help text unchanged.

In `@crates/api-core/src/handlers/operating_system.rs`:
- Around line 273-280: Update the tenant_organization_id validation branch in
the relevant operating-system handler to return NicoError::InvalidArgument and
convert it with .into(), replacing the direct Status::invalid_argument
construction while preserving the existing validation message.
🪄 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: c96e07dd-8b3c-4706-b5dc-fb6601ab2e05

📥 Commits

Reviewing files that changed from the base of the PR and between 0dae3ca and eb18a6a.

⛔ Files ignored due to path filters (1)
  • rest-api/proto/core/gen/v1/nico_nico.pb.go is excluded by !**/*.pb.go, !**/gen/**, !rest-api/**/*.pb.go
📒 Files selected for processing (14)
  • crates/admin-cli/src/operating_system/common.rs
  • crates/admin-cli/src/operating_system/create/args.rs
  • crates/admin-cli/src/operating_system/show/cmd.rs
  • crates/api-core/src/handlers/operating_system.rs
  • crates/api-core/src/ipxe.rs
  • crates/api-core/src/tests/instance_os.rs
  • crates/api-core/tests/integration/operating_system.rs
  • crates/api-db/migrations/20260717120000_operating_systems_org_nullable.sql
  • crates/api-db/src/instance.rs
  • crates/api-db/src/operating_system.rs
  • crates/api-model/src/operating_system_definition.rs
  • crates/api-web/src/operating_system.rs
  • crates/rpc/proto/forge.proto
  • rest-api/proto/core/src/v1/nico_nico.proto

Comment thread crates/api-db/src/operating_system.rs Outdated
pbreton added 2 commits July 17, 2026 13:58
Signed-off-by: Patrice Breton <pbreton@nvidia.com>
Signed-off-by: Patrice Breton <pbreton@nvidia.com>
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 259 16 29 79 7 128
machine-a-tron 181 7 17 52 6 99
machine-validation-runner 532 39 113 184 15 181
machine_validation 532 39 113 184 15 181
machine_validation-aarch64 532 39 113 184 15 181
nvmetal-carbide 532 39 113 184 15 181
TOTAL 2574 179 498 873 73 951

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

@pbreton
pbreton marked this pull request as ready for review July 17, 2026 21:46
@pbreton

pbreton commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

/retest

1 similar comment
@pbreton

pbreton commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

/retest

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.

1 participant