Skip to content

OSAC-3629: add storage_tier to proto and CRD definitions - #159

Merged
omer-vishlitzky merged 3 commits into
osac-project:mainfrom
clobrano:feat/OSAC-3629-storage-tier-proto-crd
Aug 11, 2026
Merged

OSAC-3629: add storage_tier to proto and CRD definitions#159
omer-vishlitzky merged 3 commits into
osac-project:mainfrom
clobrano:feat/OSAC-3629-storage-tier-proto-crd

Conversation

@clobrano

@clobrano clobrano commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

OSAC-3629: add storage_tier to proto and CRD definitions

Jira: OSAC-3629
Story type: [DEV]
Epic: OSAC-3627 — Per-Disk Storage Tier Selection
Feature: OSAC-1710 — ComputeInstance StorageTier Selection

Summary

Adds storage_tier field to ComputeInstanceDisk in both private and public proto definitions, and StorageTier to DiskSpec in the CRD type. This enables tenants to specify a storage tier per disk when creating ComputeInstances. The CRD enforces validation (required, pattern, max length) and immutability (inherited from existing self == oldSelf XValidation rules).

Changes

fulfillment-service (proto):

  • Added optional string storage_tier = 2 to ComputeInstanceDisk in both private and public protos
  • Regenerated Go code via buf generate

osac-operator (CRD):

  • Added StorageTier string to DiskSpec with kubebuilder markers: Required, MinLength=1, MaxLength=63, Pattern=^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$
  • Regenerated CRD manifests, DeepCopy, and Helm CRDs
  • Updated sample CR with storageTier: standard

Tests:

  • Updated all existing DiskSpec test fixtures (3 files, 17 literals) to include StorageTier: "standard"
  • Added 13 new envtest validation tests: 6 valid patterns, 4 invalid patterns, 1 maxLength, 2 immutability

Testing

  • Unit tests: 13 new CRD validation tests (envtest) covering pattern acceptance/rejection, maxLength, and immutability
  • Integration tests: N/A — story adds a data model field without component interactions
  • Coverage: All behavioral paths of the new field are tested through the CRD's public interface

Acceptance Criteria

  • AC-1: A ComputeInstance created via the API can include a storage_tier string on each disk and the value is persisted and returned
  • AC-2: The CRD rejects a storageTier value that is empty, exceeds 63 characters, or does not match the pattern
  • AC-3: Proto linting passes with no new violations
  • AC-4: An attempt to change the storageTier on an existing ComputeInstance is rejected by CRD validation

Summary by CodeRabbit

  • New Features

    • Added optional storage tier configuration for boot and additional disks.
    • Storage tier values are validated for format and length.
    • Storage tier settings are now carried through when compute instances are created.
    • Updated API schemas and configuration samples to support the new option.
  • Bug Fixes

    • Added validation coverage for missing, valid, invalid, oversized, and changed storage tier values.

@openshift-ci-robot

openshift-ci-robot commented Aug 5, 2026

Copy link
Copy Markdown

@clobrano: This pull request references OSAC-3629 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:

OSAC-3629: add storage_tier to proto and CRD definitions

Jira: OSAC-3629
Story type: [DEV]
Epic: OSAC-3627 — Per-Disk Storage Tier Selection
Feature: OSAC-1710 — ComputeInstance StorageTier Selection

Summary

Adds storage_tier field to ComputeInstanceDisk in both private and public proto definitions, and StorageTier to DiskSpec in the CRD type. This enables tenants to specify a storage tier per disk when creating ComputeInstances. The CRD enforces validation (required, pattern, max length) and immutability (inherited from existing self == oldSelf XValidation rules).

Changes

fulfillment-service (proto):

  • Added optional string storage_tier = 2 to ComputeInstanceDisk in both private and public protos
  • Regenerated Go code via buf generate

osac-operator (CRD):

  • Added StorageTier string to DiskSpec with kubebuilder markers: Required, MinLength=1, MaxLength=63, Pattern=^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$
  • Regenerated CRD manifests, DeepCopy, and Helm CRDs
  • Updated sample CR with storageTier: standard

Tests:

  • Updated all existing DiskSpec test fixtures (3 files, 17 literals) to include StorageTier: "standard"
  • Added 13 new envtest validation tests: 6 valid patterns, 4 invalid patterns, 1 maxLength, 2 immutability

Testing

  • Unit tests: 13 new CRD validation tests (envtest) covering pattern acceptance/rejection, maxLength, and immutability
  • Integration tests: N/A — story adds a data model field without component interactions
  • Coverage: All behavioral paths of the new field are tested through the CRD's public interface

Acceptance Criteria

  • AC-1: A ComputeInstance created via the API can include a storage_tier string on each disk and the value is persisted and returned
  • AC-2: The CRD rejects a storageTier value that is empty, exceeds 63 characters, or does not match the pattern
  • AC-3: Proto linting passes with no new violations
  • AC-4: An attempt to change the storageTier on an existing ComputeInstance is rejected by CRD validation

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 Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: a7e13f62-f29d-404d-8728-edd056901aae

📥 Commits

Reviewing files that changed from the base of the PR and between 33055f9 and 4f4a18c.

⛔ Files ignored due to path filters (4)
  • fulfillment-service/internal/api/osac/private/v1/compute_instance_common_type.pb.go is excluded by !**/*.pb.go
  • fulfillment-service/internal/api/osac/private/v1/compute_instance_common_type_protoopaque.pb.go is excluded by !**/*.pb.go
  • fulfillment-service/internal/api/osac/public/v1/compute_instance_common_type.pb.go is excluded by !**/*.pb.go
  • fulfillment-service/internal/api/osac/public/v1/compute_instance_common_type_protoopaque.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (11)
  • fulfillment-service/internal/controllers/computeinstance/computeinstance_reconciler_function.go
  • fulfillment-service/proto/private/osac/private/v1/compute_instance_common_type.proto
  • fulfillment-service/proto/public/osac/public/v1/compute_instance_common_type.proto
  • osac-operator/api/v1alpha1/computeinstance_types.go
  • osac-operator/api/v1alpha1/computeinstance_types_test.go
  • osac-operator/charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • osac-operator/config/crd/bases/osac.openshift.io_computeinstances.yaml
  • osac-operator/config/samples/osac_v1alpha1_computeinstance.yaml
  • osac-operator/internal/controller/computeinstance_validation_test.go
  • osac-operator/internal/controller/suite_test.go
  • osac-operator/test/integration/console_proxy_test.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • fulfillment-service/internal/controllers/computeinstance/computeinstance_reconciler_function.go
  • osac-operator/internal/controller/suite_test.go
  • osac-operator/test/integration/console_proxy_test.go
  • osac-operator/config/crd/bases/osac.openshift.io_computeinstances.yaml
  • osac-operator/charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • osac-operator/api/v1alpha1/computeinstance_types.go
  • osac-operator/internal/controller/computeinstance_validation_test.go
  • osac-operator/config/samples/osac_v1alpha1_computeinstance.yaml
  • osac-operator/api/v1alpha1/computeinstance_types_test.go

Walkthrough

Compute instance disks now support an optional storageTier. The protobuf contracts, Kubernetes API, CRD schemas, reconciler mapping, samples, fixtures, and validation tests were updated for boot and additional disks.

Changes

Storage tier support

Layer / File(s) Summary
Disk storage tier contracts
fulfillment-service/proto/.../compute_instance_common_type.proto, osac-operator/api/v1alpha1/computeinstance_types.go
Added optional storage_tier API fields and the validated DiskSpec.StorageTier field.
CRD storage tier schema
osac-operator/charts/operator-crds/templates/..., osac-operator/config/crd/bases/..., osac-operator/config/samples/...
Added storageTier to boot and additional disks with 63-character and naming-pattern validation.
Storage tier reconciliation
fulfillment-service/internal/controllers/computeinstance/computeinstance_reconciler_function.go
Maps boot and additional disk storage tiers into Kubernetes DiskSpec resources.
Storage tier validation coverage
osac-operator/api/v1alpha1/computeinstance_types_test.go, osac-operator/internal/controller/*_test.go, osac-operator/test/integration/console_proxy_test.go
Updated fixtures and tests for valid, omitted, invalid, overlong, and immutable storage-tier values.

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

Sequence Diagram(s)

sequenceDiagram
  participant FulfillmentAPI
  participant ComputeInstanceReconciler
  participant KubernetesComputeInstance
  FulfillmentAPI->>ComputeInstanceReconciler: provide boot and additional disk storage tiers
  ComputeInstanceReconciler->>KubernetesComputeInstance: set DiskSpec.StorageTier values
Loading

Possibly related PRs

Suggested labels: storage

Suggested reviewers: jhernand, larsks, danielerez

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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 identifies the primary change: adding storage tier support to the proto and CRD definitions.
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 The feature diff contains no API keys, tokens, passwords, private keys, credential URLs, or secret-named literals; the only long value is an intentional overlength storageTier test fixture.
No-Weak-Crypto ✅ Passed PR-wide added-line and changed-file scans found no MD5, SHA1, DES, RC4, Blowfish, ECB, custom crypto, or secret-comparison code.
No-Injection-Vectors ✅ Passed The feature diff adds proto/CRD fields and direct struct propagation only; no listed SQL, shell, eval/exec, unsafe YAML, pickle, or HTML sinks use the new value.
Container-Privileges ✅ Passed The complete PR diff adds no privileged:true, host PID/network/IPC, SYS_ADMIN, allowPrivilegeEscalation:true, or root execution settings.
No-Sensitive-Data-In-Logs ✅ Passed No new logging calls or sensitive literals were added; the new field uses the non-sensitive value "standard", and reconciler logs only resource identifiers, names, and namespaces.
Ai-Attribution ✅ Passed All three OSAC-3629 commits identify AI use with an Assisted-by: Claude Code trailer; none uses an AI-related Co-Authored-By trailer.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 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.

@clobrano
clobrano force-pushed the feat/OSAC-3629-storage-tier-proto-crd branch from a56d608 to bf8ec8c Compare August 5, 2026 16:34
@clobrano
clobrano force-pushed the feat/OSAC-3629-storage-tier-proto-crd branch from bf8ec8c to 93b92c1 Compare August 5, 2026 17:22
@clobrano
clobrano force-pushed the feat/OSAC-3629-storage-tier-proto-crd branch from 93b92c1 to 61697e1 Compare August 6, 2026 07:38
@clobrano
clobrano force-pushed the feat/OSAC-3629-storage-tier-proto-crd branch from 61697e1 to 0a39cd5 Compare August 6, 2026 10:03

@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: 1

🤖 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 `@osac-operator/api/v1alpha1/computeinstance_types.go`:
- Around line 56-60: Update addExplicitFields to propagate GetStorageTier() when
mapping both the boot disk and additional disks, alongside the existing SizeGiB
mapping, so the requested tier reaches the ComputeInstance CR. Add conversion
tests covering StorageTier for both disk paths.
🪄 Autofix

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

Plan: Pro Plus

Run ID: 82a88b7e-133b-45f2-8208-db6b3da8ea34

📥 Commits

Reviewing files that changed from the base of the PR and between 946697d and 0a39cd5.

⛔ Files ignored due to path filters (4)
  • fulfillment-service/internal/api/osac/private/v1/compute_instance_type.pb.go is excluded by !**/*.pb.go
  • fulfillment-service/internal/api/osac/private/v1/compute_instance_type_protoopaque.pb.go is excluded by !**/*.pb.go
  • fulfillment-service/internal/api/osac/public/v1/compute_instance_type.pb.go is excluded by !**/*.pb.go
  • fulfillment-service/internal/api/osac/public/v1/compute_instance_type_protoopaque.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (10)
  • fulfillment-service/proto/private/osac/private/v1/compute_instance_type.proto
  • fulfillment-service/proto/public/osac/public/v1/compute_instance_type.proto
  • osac-operator/api/v1alpha1/computeinstance_types.go
  • osac-operator/api/v1alpha1/computeinstance_types_test.go
  • osac-operator/charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • osac-operator/config/crd/bases/osac.openshift.io_computeinstances.yaml
  • osac-operator/config/samples/osac_v1alpha1_computeinstance.yaml
  • osac-operator/internal/controller/computeinstance_validation_test.go
  • osac-operator/internal/controller/suite_test.go
  • osac-operator/test/integration/console_proxy_test.go

Comment thread osac-operator/api/v1alpha1/computeinstance_types.go
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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

/approve
/lgtm

@openshift-ci openshift-ci Bot added the lgtm label Aug 11, 2026
@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: clobrano, ygalblum

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

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Your Name <you@example.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Your Name <you@example.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Your Name <you@example.com>
@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/lgtm

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 11, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:31 PM UTC · Completed 2:50 PM UTC

Commit: c749b29 · View workflow run →

@fullsend-ai-review

Copy link
Copy Markdown

Review

Findings

Medium

  • [pattern-inconsistency] osac-operator/api/v1alpha1/computeinstance_types.go:57 — The new StorageTier field uses // +optional to mark it as optional, but every other optional spec field in this file (and in sub-structs like NetworkAttachment) uses // +kubebuilder:validation:Optional. While both markers work functionally, this breaks the established convention.
    Remediation: Replace // +optional with // +kubebuilder:validation:Optional.

Low

  • [api-contract] fulfillment-service/proto/private/osac/private/v1/compute_instance_common_type.proto:31 — The new storage_tier proto field has no buf.validate annotations. This is consistent with the existing size_gib field in the same message (which also lacks buf.validate), but adding validation at the proto layer would provide earlier error feedback for invalid values that the CRD would reject. Same applies to the public proto.

  • [breaking-schema] fulfillment-service/proto/private/osac/private/v1/compute_instance_common_type.proto:31 — The osac-operator and osac-metering pin to BSR versions that predate this change (v0.0.83 and v0.0.84 respectively). A new BSR version should be published and downstream pins bumped so the storage_tier field is usable end-to-end. Wire compatibility is preserved in the interim.

  • [missing-doc] osac-aap/collections/ansible_collections/osac/templates/README.md:68 — The ocp_virt_vm template spec table does not mention the new storageTier sub-field.

  • [missing-doc] fulfillment-service/docs/CATALOG_ITEMS.md:290 — The ComputeInstanceCatalogItem paths table does not include boot_disk.storage_tier.

  • [api-contract] fulfillment-service/internal/controllers/computeinstance/computeinstance_reconciler_function.go:728 — The proto optional string presence semantics (HasStorageTier()) are lost when mapped to the CRD's plain string with omitempty. This works correctly in practice.

  • [pr-description-accuracy] The PR description states the CRD uses "Required, MinLength=1" kubebuilder markers, but the actual code uses +optional with no MinLength constraint.


Labels: PR adds storage_tier field to ComputeInstanceDisk proto and CRD, directly related to storage tier selection feature

@fullsend-ai-review fullsend-ai-review 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.

See the review comment for full details.

SizeGiB int32 `json:"sizeGiB"`

// StorageTier is the name of the storage tier for this disk
// +kubebuilder:validation:MaxLength=63

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] pattern-inconsistency

The new StorageTier field uses // +optional to mark it as optional, but every other optional spec field in this file uses // +kubebuilder:validation:Optional. While both markers work, this breaks the established convention.

Suggested fix: Replace // +optional with // +kubebuilder:validation:Optional.

message ComputeInstanceDisk {
// Disk size in GiB.
int32 size_gib = 1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] api-contract

The new storage_tier proto field has no buf.validate annotations. This is consistent with the existing size_gib field in the same message, but adding validation at the proto layer would provide earlier error feedback for invalid values. Same applies to the public proto.

Suggested fix: Add buf.validate annotations matching the CRD constraints.

message ComputeInstanceDisk {
// Disk size in GiB.
int32 size_gib = 1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] breaking-schema

The osac-operator and osac-metering pin to BSR versions that predate this change. A new BSR version should be published and downstream pins bumped so the field is usable end-to-end. Wire compatibility is preserved in the interim.

Suggested fix: Publish a new BSR version and bump downstream pins.

spec.BootDisk = osacv1alpha1.DiskSpec{
SizeGiB: ciSpec.GetBootDisk().GetSizeGib(),
SizeGiB: ciSpec.GetBootDisk().GetSizeGib(),
StorageTier: ciSpec.GetBootDisk().GetStorageTier(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] api-contract

The proto optional string presence semantics (HasStorageTier()) are lost when mapped to the CRD's plain string with omitempty. This works correctly in practice.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment storage labels Aug 11, 2026
@omer-vishlitzky
omer-vishlitzky added this pull request to the merge queue Aug 11, 2026
Merged via the queue into osac-project:main with commit 3e9b25c Aug 11, 2026
117 of 118 checks passed
@clobrano
clobrano deleted the feat/OSAC-3629-storage-tier-proto-crd branch August 12, 2026 06:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants