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

MGMT-23976: Add multi-tier storage types to Tenant CRD - #197

Merged
openshift-merge-bot[bot] merged 2 commits into
osac-project:mainfrom
zszabo-rh:feature/MGMT-23976-multi-tier-storage-types
Apr 24, 2026
Merged

openshift-merge-bot[bot] merged 2 commits into
osac-project:mainfrom
zszabo-rh:feature/MGMT-23976-multi-tier-storage-types

Conversation

@zszabo-rh

@zszabo-rh zszabo-rh commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add ResolvedStorageClass struct with name and tier fields to support multiple storage tiers per tenant (EP #32)
  • Replace singular status.storageClass (string) with status.storageClasses (list of ResolvedStorageClass)
  • Add osac.openshift.io/storage-tier label constant
  • Update printer column from single StorageClass name to resolved tier names

Notes

The controller is minimally adapted to write the existing single-tier result as a one-element list with tier: "default". Full multi-tier resolution logic will follow in a separate PR once EP #32 is finalized.

Test plan

  • make test passes — existing tenant controller tests adapted for the new list format
  • make manifests regenerates CRD YAML with correct schema
  • go build ./... compiles cleanly

Jira: MGMT-23976

Summary by CodeRabbit

  • Enhancements
    • Tenant status now tracks multiple storage classes with tier information. The status field has been updated to display an array of storage class entries instead of a single value, each containing name and tier details.
    • Kubebuilder printer columns now display storage tiers for improved visibility.

@openshift-ci-robot

openshift-ci-robot commented Apr 23, 2026

Copy link
Copy Markdown

@zszabo-rh: This pull request references MGMT-23976 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 sub-task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Add ResolvedStorageClass struct with name and tier fields to support multiple storage tiers per tenant (EP #32)
  • Replace singular status.storageClass (string) with status.storageClasses (list of ResolvedStorageClass)
  • Add osac.openshift.io/storage-tier label constant
  • Update printer column from single StorageClass name to resolved tier names

Notes

The controller is minimally adapted to write the existing single-tier result as a one-element list with tier: "default". Full multi-tier resolution logic will follow in a separate PR once EP #32 is finalized.

Test plan

  • make test passes — existing tenant controller tests adapted for the new list format
  • make manifests regenerates CRD YAML with correct schema
  • go build ./... compiles cleanly

Jira: MGMT-23976

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.

@openshift-ci
openshift-ci Bot requested a review from tzvatot April 23, 2026 12:00
@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@zszabo-rh has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 11 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 21 minutes and 11 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a95d7956-2c54-4a86-bdb3-cdca5963d327

📥 Commits

Reviewing files that changed from the base of the PR and between 8716b41 and 29db753.

📒 Files selected for processing (6)
  • api/v1alpha1/tenant_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • config/crd/bases/osac.openshift.io_tenants.yaml
  • internal/controller/tenant_controller.go
  • internal/controller/tenant_controller_test.go
  • internal/controller/tenant_names.go
📝 Walkthrough

Walkthrough

The Tenant API is refactored to replace a single storageClass string field with a storageClasses array of ResolvedStorageClass objects containing name and tier fields. Changes are reflected across type definitions, deep copy methods, CRD schema, controller reconciliation logic, and tests.

Changes

Cohort / File(s) Summary
Type Definitions
api/v1alpha1/tenant_types.go
Introduces ResolvedStorageClass type with name and tier fields; updates TenantStatus to use StorageClasses []ResolvedStorageClass instead of StorageClass string.
Deep Copy Implementation
api/v1alpha1/zz_generated.deepcopy.go
Adds DeepCopyInto and DeepCopy methods for ResolvedStorageClass; updates TenantStatus.DeepCopyInto to handle slice deep-copying of StorageClasses.
CRD Schema & Printer Columns
config/crd/bases/osac.openshift.io_tenants.yaml
Updates CRD status schema to replace single storageClass string with storageClasses array; changes printer column from status.storageClass to status.storageClasses[*].tier.
Controller Reconciliation
internal/controller/tenant_controller.go
Modifies reconciliation logic to populate Status.StorageClasses with resolved storage class name and hardcoded "default" tier instead of single StorageClass field.
Controller Tests
internal/controller/tenant_controller_test.go
Updates reconcileAndAssertStatus helper to assert tenant.Status.StorageClasses slice instead of single StorageClass field.
Constants
internal/controller/tenant_names.go
Adds unexported osacStorageTierLabel constant defining the storage tier label key format for StorageClass objects.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • mhrivnak
  • adriengentil
  • tzvatot
  • jhernand
  • eranco74

Poem

🐰 From single strings to tiers so grand,
StorageClasses multiply across the land,
Arrays of names with tiers aligned,
Deep copies made with careful mind,
The schema shifts to hold them tight,
A rabbit's refactor, done just right! 🎯

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding multi-tier storage types (ResolvedStorageClass) to the Tenant CRD, replacing single storageClass with storageClasses array.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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

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.

@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

🧹 Nitpick comments (1)
internal/controller/tenant_controller_test.go (1)

108-113: Assert the resolved tier as well as the name.

Tier is required by the new status type and is what the printer column displays. The helper should verify the controller writes the expected interim "default" tier, not just the StorageClass name.

Proposed test assertion
 					} else {
 						g.Expect(tenant.Status.StorageClasses).To(HaveLen(1))
 						g.Expect(tenant.Status.StorageClasses[0].Name).To(Equal(expectedSCName))
+						g.Expect(tenant.Status.StorageClasses[0].Tier).To(Equal("default"))
 					}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/controller/tenant_controller_test.go` around lines 108 - 113, The
test currently only asserts StorageClasses name but must also assert the
resolved Tier; when expectedSCName is non-empty update the assertions in the
test helper (where tenant.Status.StorageClasses and expectedSCName are used) to
also check the StorageClasses[0].Tier equals the interim value ("default") so
the controller wrote the required Tier field that the printer column relies on.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@api/v1alpha1/tenant_types.go`:
- Around line 84-87: The StorageClasses field in tenant_types.go allows
duplicate tiers because the CRD lacks list-map annotations; update the
StorageClasses declaration (the field of type []ResolvedStorageClass) to include
kubebuilder markers to make the list a map keyed by the tier (e.g., add
kubebuilder:validation:ListType=map and
kubebuilder:validation:ListMapKeys={"tier"} immediately above the StorageClasses
field), then run make manifests to regenerate the CRD and confirm the generated
schema includes x-kubernetes-list-type: map and x-kubernetes-list-map-keys:
["tier"].

---

Nitpick comments:
In `@internal/controller/tenant_controller_test.go`:
- Around line 108-113: The test currently only asserts StorageClasses name but
must also assert the resolved Tier; when expectedSCName is non-empty update the
assertions in the test helper (where tenant.Status.StorageClasses and
expectedSCName are used) to also check the StorageClasses[0].Tier equals the
interim value ("default") so the controller wrote the required Tier field that
the printer column relies on.
🪄 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 UI

Review profile: CHILL

Plan: Pro

Run ID: 9f8f39af-3985-47fb-8fe9-1499ae04a424

📥 Commits

Reviewing files that changed from the base of the PR and between c802d05 and 8716b41.

📒 Files selected for processing (6)
  • api/v1alpha1/tenant_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • config/crd/bases/osac.openshift.io_tenants.yaml
  • internal/controller/tenant_controller.go
  • internal/controller/tenant_controller_test.go
  • internal/controller/tenant_names.go

Comment thread api/v1alpha1/tenant_types.go
Add ResolvedStorageClass struct with name and tier fields to support
multiple storage tiers per tenant. Replace the singular
status.storageClass string with a status.storageClasses list.

Add osac.openshift.io/storage-tier label constant for StorageClass
tier identification. Update printer column to show resolved tier names.

The controller is minimally adapted to write the existing single-tier
result as a one-element list. Full multi-tier resolution logic will
follow once the enhancement proposal (EP osac-project#32) is finalized.

Signed-off-by: Zoltan Szabo <zszabo@redhat.com>
Generated-By: Claude Code (Anthropic)
@zszabo-rh
zszabo-rh force-pushed the feature/MGMT-23976-multi-tier-storage-types branch from 8716b41 to 6867ffe Compare April 23, 2026 12:14
…dicate

Add listType=map and listMapKey=tier to StorageClasses field so the
CRD schema enforces one entry per tier and enables server-side apply
merge semantics.

Use osacStorageTierLabel in the StorageClass watch predicate so
StorageClasses without the storage-tier label are filtered out before
triggering reconciliation.

Signed-off-by: Zoltan Szabo <zszabo@redhat.com>
Generated-By: Claude Code (Anthropic)

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

(Reposted as inline comment on lines 385-392)

Comment on lines 385 to 392
func storageClassTenantPredicate() predicate.Predicate {
return predicate.NewPredicateFuncs(func(obj client.Object) bool {
_, exists := obj.GetLabels()[osacTenantAnnotation]
return exists
labels := obj.GetLabels()
_, hasTenant := labels[osacTenantAnnotation]
_, hasTier := labels[osacStorageTierLabel]
return hasTenant && hasTier
})
}

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.

The predicate requires both labels, but getTenantStorageClass (line 206) still queries by tenant label only. This is intentionally ahead of the resolution logic until the full multi-tier work lands (EP #32). Consider adding a brief code comment noting that StorageClasses without the storage-tier label won't trigger reconciliation, so developers working on this area understand the mismatch is intentional while multi-tier resolution is in progress.

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

Left a minor comment. You can address in a follow-up PR in case it will be a while until the watch and reconciliation logic matches.

LGTM

@openshift-ci

openshift-ci Bot commented Apr 24, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: akshaynadkarni, zszabo-rh

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

@openshift-merge-bot
openshift-merge-bot Bot merged commit 525facb into osac-project:main Apr 24, 2026
8 checks passed
akshaynadkarni added a commit to akshaynadkarni/osac-operator that referenced this pull request Apr 24, 2026
…MT-23976-multi-tier-storage-types"

This reverts commit 525facb, reversing
changes made to 1743a55.
wgordon17 pushed a commit to wgordon17/osac-operator that referenced this pull request May 7, 2026
…MT-23976-multi-tier-storage-types"

This reverts commit 525facb, reversing
changes made to 1743a55.
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