Skip to content
This repository was archived by the owner on Sep 9, 2026. It is now read-only.

OSAC-1346: add public gRPC servers and server wiring for bare metal instances - #707

Merged
openshift-merge-bot[bot] merged 5 commits into
osac-project:mainfrom
adriengentil:feat/OSAC-1343
Jun 19, 2026
Merged

openshift-merge-bot[bot] merged 5 commits into
osac-project:mainfrom
adriengentil:feat/OSAC-1343

Conversation

@adriengentil

@adriengentil adriengentil commented Jun 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Implements thin public wrappers over the private bare metal servers: BareMetalInstanceTemplatesServer (List/Get only, per EP), BareMetalInstanceCatalogItemsServer (full CRUD with published-visibility enforcement and tenant scoping on Create), and BareMetalInstancesServer (full CRUD with field-mask-aware Update)
  • Registers all three public servers in the main gRPC setup alongside the existing private servers
  • Adds unit tests for all three servers covering CRUD, published-visibility filter, immutability enforcement, and reference-blocked deletion

Jira

https://redhat.atlassian.net/browse/OSAC-1346

Test plan

  • ginkgo run internal/servers — 979/979 passed
  • go build ./... — clean
  • gofmt -s -w . — no drift

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added CLI command to create bare metal instances with configurable options (name, catalog item, SSH key, user data, run strategy).
    • Added CLI command to describe and retrieve bare metal instance details.
    • Introduced new gRPC API services for bare metal instance management, including templates and catalog items with full CRUD operations.
  • Security

    • Extended authorization policies to control access to bare metal instance operations, including tenant-admin-only creation and management of catalog items.

@openshift-ci

openshift-ci Bot commented Jun 16, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci-robot

openshift-ci-robot commented Jun 16, 2026 •

Copy link
Copy Markdown

@adriengentil: This pull request references OSAC-1346 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Implements thin public wrappers over the private bare metal servers: BareMetalInstanceTemplatesServer (List/Get only, per EP), BareMetalInstanceCatalogItemsServer (full CRUD with published-visibility enforcement and tenant scoping on Create), and BareMetalInstancesServer (full CRUD with field-mask-aware Update)
  • Registers all three public servers in the main gRPC setup alongside the existing private servers
  • Adds unit tests for all three servers covering CRUD, published-visibility filter, immutability enforcement, and reference-blocked deletion

Jira

https://redhat.atlassian.net/browse/OSAC-1346

Test plan

  • ginkgo run internal/servers — 979/979 passed
  • go build ./... — clean
  • gofmt -s -w . — no drift

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 67ecaa3d-9d3f-43e8-abba-35a3b90fcfca

📥 Commits

Reviewing files that changed from the base of the PR and between 90faf46 and 0d0af6b.

📒 Files selected for processing (18)
  • charts/service/templates/grpc-server/authconfig.yaml
  • internal/cmd/cli/create/baremetalinstance/create_bare_metal_instance_cmd.go
  • internal/cmd/cli/create/create_cmd.go
  • internal/cmd/cli/describe/baremetalinstance/describe_baremetalinstance_cmd.go
  • internal/cmd/cli/describe/describe_cmd.go
  • internal/cmd/service/start/grpcserver/start_grpc_server_cmd.go
  • internal/rendering/tables/osac.private.v1.BareMetalInstance.yaml
  • internal/rendering/tables/osac.private.v1.BareMetalInstanceCatalogItem.yaml
  • internal/rendering/tables/osac.private.v1.BareMetalInstanceTemplate.yaml
  • internal/rendering/tables/osac.public.v1.BareMetalInstance.yaml
  • internal/rendering/tables/osac.public.v1.BareMetalInstanceCatalogItem.yaml
  • internal/rendering/tables/osac.public.v1.BareMetalInstanceTemplate.yaml
  • internal/servers/baremetal_instance_catalog_items_server.go
  • internal/servers/baremetal_instance_catalog_items_server_test.go
  • internal/servers/baremetal_instance_templates_server.go
  • internal/servers/baremetal_instance_templates_server_test.go
  • internal/servers/baremetal_instances_server.go
  • internal/servers/baremetal_instances_server_test.go
 ______________________________________________________________________
< You used `any` like it's a life jacket. Spoiler: it's a pool noodle. >
 ----------------------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ

Walkthrough

Three new public gRPC servers (BareMetalInstanceTemplatesServer, BareMetalInstanceCatalogItemsServer, BareMetalInstancesServer) are added with builder patterns, CRUD handlers, and Ginkgo test suites. They are wired into gRPC server startup. OPA AuthConfig rules are extended to allow bare metal read methods for clients and CUD for tenant admins. CLI create and describe subcommands for bare metal instances are added.

Changes

Public Bare Metal Instance API Surface

Layer / File(s) Summary
BareMetalInstanceCatalogItemsServer: builder, CRUD, published-filter
internal/servers/baremetal_instance_catalog_items_server.go
Defines builder and server types; implements List/Get/Create/Update/Delete with public↔private type mapping; Get enforces published-state via a reference checker; addPublishedFilter injects a CEL this.published constraint and validates syntax.
BareMetalInstanceTemplatesServer: builder, List/Get
internal/servers/baremetal_instance_templates_server.go
Defines builder and server types; implements List and Get as private-delegate wrappers with non-strict GenericMapper output conversion.
BareMetalInstancesServer: builder, CRUD, field-mask update
internal/servers/baremetal_instances_server.go
Defines builder and server types; implements full CRUD with strict/non-strict mapper pair; Update applies field-mask semantics (fetch-existing or new-object) and rejects immutable spec.catalog_item changes.
Test suites for all three servers
internal/servers/baremetal_instance_catalog_items_server_test.go, internal/servers/baremetal_instance_templates_server_test.go, internal/servers/baremetal_instances_server_test.go
Ginkgo/Gomega suites covering builder validation, CRUD behavior, published-state filtering, referential integrity (delete blocked when referenced), field-mask updates, immutable field rejection, and gRPC error codes (NotFound, InvalidArgument, FailedPrecondition).
gRPC server startup wiring
internal/cmd/service/start/grpcserver/start_grpc_server_cmd.go
Initializes all three public bare metal servers using existing logger, notifier, attribution/tenancy logic, and metrics registerer; registers them with publicv1 before existing private bare metal setup.
OPA AuthConfig: client-permitted methods and tenant-admin CUD rule
charts/service/templates/grpc-server/authconfig.yaml
Adds Get/List for BareMetalInstanceCatalogItems, BareMetalInstanceTemplates, and BareMetalInstances to the has_client_permissions allow-list; adds a new allow if block granting tenant admins Create/Update/Delete on BareMetalInstanceCatalogItems.
CLI create baremetalinstance command
internal/cmd/cli/create/baremetalinstance/create_bare_metal_instance_cmd.go, internal/cmd/cli/create/create_cmd.go
Adds Cobra subcommand with --catalog-item (required), --ssh-key, --user-data, --run-strategy flags; validates run-strategy enum; calls Create RPC; prints instance ID on success; registered in create_cmd.go.
CLI describe baremetalinstance command
internal/cmd/cli/describe/baremetalinstance/describe_baremetalinstance_cmd.go, internal/cmd/cli/describe/describe_cmd.go
Adds Cobra subcommand using lookup.Find + List RPC for name/ID resolution; renders ID, catalog item, and trimmed state via tabwriter; registered in describe_cmd.go.

Sequence Diagram(s)

sequenceDiagram
  actor TenantAdmin
  participant CLI
  participant BareMetalInstancesServer
  participant BareMetalInstanceCatalogItemsServer
  participant PrivateDelegate
  participant ReferenceChecker

  rect rgba(255, 160, 0, 0.5)
    Note over TenantAdmin,CLI: create baremetalinstance --catalog-item <id>
    TenantAdmin->>CLI: run create command
    CLI->>BareMetalInstancesServer: Create(BareMetalInstance spec)
    BareMetalInstancesServer->>PrivateDelegate: Create(private object)
    PrivateDelegate-->>BareMetalInstancesServer: created private object
    BareMetalInstancesServer-->>CLI: instance ID
    CLI-->>TenantAdmin: print instance ID
  end

  rect rgba(0, 120, 255, 0.5)
    Note over TenantAdmin,BareMetalInstanceCatalogItemsServer: Get catalog item (published-state enforcement)
    TenantAdmin->>BareMetalInstanceCatalogItemsServer: Get(catalog item id)
    BareMetalInstanceCatalogItemsServer->>PrivateDelegate: Get(private id)
    PrivateDelegate-->>BareMetalInstanceCatalogItemsServer: private object (unpublished)
    BareMetalInstanceCatalogItemsServer->>ReferenceChecker: check reference exists
    alt no reference
      ReferenceChecker-->>BareMetalInstanceCatalogItemsServer: not found
      BareMetalInstanceCatalogItemsServer-->>TenantAdmin: NotFound
    else reference exists
      BareMetalInstanceCatalogItemsServer-->>TenantAdmin: mapped public object
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • osac-project/fulfillment-service#683: The new public bare metal servers (BareMetalInstanceCatalogItemsServer, BareMetalInstanceTemplatesServer, BareMetalInstancesServer) are thin wrappers around private delegate servers introduced in this PR, making the changes directly code-coupled.
  • osac-project/fulfillment-service#528: The describe baremetalinstance CLI command uses the lookup.Find helper added or refined in this PR for name/ID resolution via the List RPC.

Suggested reviewers

  • tzumainn
  • tzvatot
  • akshaynadkarni

Poem

⚙️ Three servers rise from builder's hand,
Public APIs now firmly planned.
OPA guards the tenant's gate—
CUD for admins, reads await! 🔐
The CLI speaks, the gRPC calls,
Bare metal lives within these halls. 🖥️

🚥 Pre-merge checks | ✅ 10 | ❌ 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 (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: implementing public gRPC servers for bare metal instances along with their wiring into the service.
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.
No-Hardcoded-Secrets ✅ Passed No hardcoded secrets, API keys, tokens, passwords, or private keys detected in any modified files. SSH keys and user data are properly accepted as user input, not hardcoded.
No-Weak-Crypto ✅ Passed No weak cryptography detected. Extensive pattern matching found no MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB usage, custom crypto implementations, or insecure secret comparisons across all modified...
No-Injection-Vectors ✅ Passed No SQL, shell, eval, pickle, or unsafe YAML injection vectors found. CEL filter injection properly protected via validateCELSyntax() before composition. Lookup filters safely escaped with fmt.Sprintf.
Container-Privileges ✅ Passed No container privilege escalation risks detected. PR modifies only Go source and OPA authorization config; existing Kubernetes deployments enforce allowPrivilegeEscalation:false with no privileged/...
No-Sensitive-Data-In-Logs ✅ Passed No sensitive data (passwords, tokens, API keys, PII, session IDs, internal hostnames, or customer data) is exposed in logging statements across new server implementations or CLI commands.
Ai-Attribution ✅ Passed AI tool use (Claude Code) is properly attributed in commit OSAC-1350 with "Assisted-by: Claude Code noreply@anthropic.com", a Red Hat-approved trailer format.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@adriengentil

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 16, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 `@internal/cmd/cli/create/baremetalinstance/create_bare_metal_instance_cmd.go`:
- Line 74: Remove the //nolint:errcheck comment from the
MarkFlagRequired("catalog-item") call on line 74 in the
create_bare_metal_instance_cmd.go file and properly handle the error return.
Check if the error is not nil after calling MarkFlagRequired and return the
error to the caller or handle it appropriately, ensuring that failures to mark
the flag as required are not silently ignored and comply with the project's
error handling security guidelines.
- Around line 126-136: The run-strategy validation in the if block has a case
sensitivity mismatch: the code concatenates c.args.runStrategy directly with the
prefix "BARE_METAL_INSTANCE_RUN_STRATEGY_", but the actual enum keys use
uppercase (ALWAYS, HALTED). To fix this, convert c.args.runStrategy to uppercase
using strings.ToUpper before concatenating it with the prefix. Also add
"strings" to the imports at the top of the file so the strings package is
available.
🪄 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: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: b85bd749-53d6-41a6-80be-83c8b5ee02c2

📥 Commits

Reviewing files that changed from the base of the PR and between c05068c and 90faf46.

📒 Files selected for processing (12)
  • charts/service/templates/grpc-server/authconfig.yaml
  • internal/cmd/cli/create/baremetalinstance/create_bare_metal_instance_cmd.go
  • internal/cmd/cli/create/create_cmd.go
  • internal/cmd/cli/describe/baremetalinstance/describe_baremetalinstance_cmd.go
  • internal/cmd/cli/describe/describe_cmd.go
  • internal/cmd/service/start/grpcserver/start_grpc_server_cmd.go
  • internal/servers/baremetal_instance_catalog_items_server.go
  • internal/servers/baremetal_instance_catalog_items_server_test.go
  • internal/servers/baremetal_instance_templates_server.go
  • internal/servers/baremetal_instance_templates_server_test.go
  • internal/servers/baremetal_instances_server.go
  • internal/servers/baremetal_instances_server_test.go

Comment thread internal/cmd/cli/create/baremetalinstance/create_bare_metal_instance_cmd.go Outdated
…nstances

Implements thin public wrappers over the private bare metal servers:
- BareMetalInstanceTemplatesServer: List/Get only (read-only for tenants
  per EP; Create/Update/Delete remain Unimplemented)
- BareMetalInstanceCatalogItemsServer: full CRUD with published filter on
  List, published+reference check on Get, and tenant scoping on Create
  handled transparently by the generic server
- BareMetalInstancesServer: full CRUD with field-mask-aware Update

Registers all three public servers in the main gRPC setup alongside the
existing private servers. Unit tests included for all three servers.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
Add BareMetalInstances (full CRUD), BareMetalInstanceTemplates (List/Get),
and BareMetalInstanceCatalogItems (Get/List) to the has_client_permissions
block. Add BareMetalInstanceCatalogItems (Create/Update/Delete) to the
is_tenant_admin block so tenant admins can manage tenant-scoped catalog items.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
Add `create baremetalinstance` with flags --catalog-item (required),
--name, --ssh-key, --user-data, and --run-strategy (Always|Halted).

Add `describe baremetalinstance` for looking up instances by ID or name,
displaying ID, catalog item, and state.

The generic `delete` command already supports bare metal instances via
the reflection helper.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
…sources

Add osac.{public,private}.v1.{BareMetalInstance,BareMetalInstanceCatalogItem,
BareMetalInstanceTemplate}.yaml table definitions so the CLI `get` command can
render these resources in tabular form.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@adriengentil
adriengentil marked this pull request as ready for review June 18, 2026 12:16
@openshift-ci
openshift-ci Bot requested review from akshaynadkarni and trewest June 18, 2026 12:16
@adriengentil

Copy link
Copy Markdown
Contributor Author

CLI output — bare metal resources

Private API (osac.private.v1)

BareMetalInstances

$ osac get baremetalinstances
ID                                    DELETING  NAME                        CATALOG ITEM                    STATE        HUB
019eda99-9161-70bc-b388-a434568cd635  -         default-baremetal-instance  default-baremetal-catalog-item  UNSPECIFIED  -
019edaa4-1860-788f-b410-204d3bb253bb  -         test                        default-baremetal-catalog-item  UNSPECIFIED  -

BareMetalInstanceTemplates

$ osac get baremetalinstancetemplates
ID                                    DELETING  NAME               TITLE
019eda94-b6c5-7ca0-902b-13e69494d1ef  -         default-baremetal  Default Bare Metal Instance Template

BareMetalInstanceCatalogItems

$ osac get baremetalinstancecatalogitems
ID                                    DELETING  NAME                            TITLE                        PUBLISHED  TENANT
019eda97-44b4-7e95-9ff0-30b7e52cb48c  -         default-baremetal-catalog-item  Default Bare Metal Instance  true       -

Public API (osac.public.v1)

BareMetalInstances

$ osac get osac.public.v1.BareMetalInstance
ID                                    DELETING  NAME                        CATALOG ITEM                    STATE
019eda99-9161-70bc-b388-a434568cd635  -         default-baremetal-instance  default-baremetal-catalog-item  UNSPECIFIED
019edaa4-1860-788f-b410-204d3bb253bb  -         test                        default-baremetal-catalog-item  UNSPECIFIED

BareMetalInstanceTemplates

$ osac get osac.public.v1.BareMetalInstanceTemplate
ID                                    DELETING  NAME               TITLE
019eda94-b6c5-7ca0-902b-13e69494d1ef  -         default-baremetal  Default Bare Metal Instance Template

BareMetalInstanceCatalogItems

$ osac get osac.public.v1.BareMetalInstanceCatalogItem
ID                                    DELETING  NAME                            TITLE                        PUBLISHED
019eda97-44b4-7e95-9ff0-30b7e52cb48c  -         default-baremetal-catalog-item  Default Bare Metal Instance  true

Note: the private API includes HUB on instances and TENANT on catalog items; the public API omits both.
HUB shows - because the bare-metal-fulfillment-operator CRDs are not yet installed on the hub cluster.

@adriengentil

Copy link
Copy Markdown
Contributor Author

/cc @carbonin

@openshift-ci
openshift-ci Bot requested a review from carbonin June 18, 2026 13:51
@openshift-ci

openshift-ci Bot commented Jun 18, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: adriengentil, carbonin

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@adriengentil

Copy link
Copy Markdown
Contributor Author

/retest

@openshift-merge-bot
openshift-merge-bot Bot merged commit 822b135 into osac-project:main Jun 19, 2026
14 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants