Repository: red-hat-storage/ocs-operator
Pull request #3152: add day2 *classes to storageconsumer distribution list
Author: login: leelavg
Labels: name: lgtm
description: Indicates that a PR is ready to be merged.
name: approved
description: Indicates a PR has been approved by an approver from all required OWNERS files.
Created: 2025-04-10T07:49:35Z | Merged: 2025-04-15T11:14:21Z

in addition to the default storageclasses, volume[group]snapshotclasses add the day2 resources created by user for distribution to connected client clusters.


Diff:
diff --git a/controllers/storagecluster/storageconsumer.go b/controllers/storagecluster/storageconsumer.go
index 3a8253720c..a09d519541 100644
--- a/controllers/storagecluster/storageconsumer.go
+++ b/controllers/storagecluster/storageconsumer.go
@@ -1,14 +1,20 @@
 package storagecluster
 
 import (
+	"context"
 	"fmt"
+	"maps"
+	"slices"
 
 	ocsv1 "github.com/red-hat-storage/ocs-operator/api/v4/v1"
 	ocsv1a1 "github.com/red-hat-storage/ocs-operator/api/v4/v1alpha1"
 	"github.com/red-hat-storage/ocs-operator/v4/controllers/defaults"
 	"github.com/red-hat-storage/ocs-operator/v4/controllers/util"
 
+	groupsnapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1beta1"
+	snapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
 	corev1 "k8s.io/api/core/v1"
+	storagev1 "k8s.io/api/storage/v1"
 	extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	ctrl "sigs.k8s.io/controller-runtime"
@@ -20,12 +26,33 @@ const (
 	localStorageConsumerConfigMapName = "storageconsumer-internal"
 )
 
+var (
+	supportedCsiDrivers = []string{
+		util.RbdDriverName,
+		util.CephFSDriverName,
+		util.NfsDriverName,
+	}
+)
+
 type storageConsumer struct{}
 
 var _ resourceManager = &storageConsumer{}
 
 func (s *storageConsumer) ensureCreated(r *StorageClusterReconciler, storageCluster *ocsv1.StorageCluster) (ctrl.Result, error) {
 
+	storageClassesSpec, err := getLocalStorageClassNames(r.ctx, r.Client, storageCluster)
+	if err != nil {
+		return ctrl.Result{}, fmt.Errorf("failed to generate storageclasses list for distribution: %v", err)
+	}
+	volumeSnapshotClassesSpec, err := getLocalVolumeSnapshotClassNames(r.ctx, r.Client, storageCluster)
+	if err != nil {
+		return ctrl.Result{}, fmt.Errorf("failed to generate volumesnapshotclasses list for distribution: %v", err)
+	}
+	volumeGroupSnapshotClassesSpec, err := getLocalVolumeGroupSnapshotClassNames(r.ctx, r.Client, storageCluster)
+	if err != nil {
+		return ctrl.Result{}, fmt.Errorf("failed to generate volumegroupsnapshotclasses list for distribution: %v", err)
+	}
+
 	storageConsumer := &ocsv1a1.StorageConsumer{}
 	storageConsumer.Name = defaults.LocalStorageConsumerName
 	storageConsumer.Namespace = storageCluster.Namespace
@@ -34,59 +61,10 @@ func (s *storageConsumer) ensureCreated(r *StorageClusterReconciler, storageClus
 			return err
 		}
 		spec := &storageConsumer.Spec
-		// will be filled by the consumer controller based on defaults
 		spec.ResourceNameMappingConfigMap.Name = localStorageConsumerConfigMapName
-		spec.StorageClasses = []ocsv1a1.StorageClassSpec{
-			// TODO: after finding virt availability need to send corresponding sc
-			{Name: util.GenerateNameForCephBlockPoolStorageClass(storageCluster)},
-			{Name: util.GenerateNameForCephFilesystemStorageClass(storageCluster)},
-		}
-		spec.VolumeSnapshotClasses = []ocsv1a1.VolumeSnapshotClassSpec{
-			{Name: util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)},
-			{Name: util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)},
-		}
-		spec.VolumeGroupSnapshotClasses = []ocsv1a1.VolumeGroupSnapshotClassSpec{
-			{Name: util.GenerateNameForGroupSnapshotClass(storageCluster, util.RbdGroupSnapshotter)},
-			{Name: util.GenerateNameForGroupSnapshotClass(storageCluster, util.CephfsGroupSnapshotter)},
-		}
-
-		crd := &metav1.PartialObjectMetadata{}
-		crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
-		crd.Name = VirtualMachineCrdName
-		if err := r.Client.Get(r.ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
-			return err
-		}
-
-		if crd.UID != "" {
-			spec.StorageClasses = append(
-				spec.StorageClasses,
-				ocsv1a1.StorageClassSpec{Name: util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)},
-			)
-		}
-
-		if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
-			spec.StorageClasses = append(
-				spec.StorageClasses,
-				ocsv1a1.StorageClassSpec{Name: util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)},
-			)
-		}
-
-		if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
-			spec.StorageClasses = append(
-				spec.StorageClasses,
-				ocsv1a1.StorageClassSpec{Name: util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)},
-			)
-			spec.VolumeSnapshotClasses = append(
-				spec.VolumeSnapshotClasses,
-				ocsv1a1.VolumeSnapshotClassSpec{Name: util.GenerateNameForSnapshotClass(storageCluster.Name, util.NfsSnapshotter)},
-			)
-		}
-		if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
-			spec.StorageClasses = append(
-				spec.StorageClasses,
-				ocsv1a1.StorageClassSpec{Name: util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)},
-			)
-		}
+		spec.StorageClasses = storageClassesSpec
+		spec.VolumeSnapshotClasses = volumeSnapshotClassesSpec
+		spec.VolumeGroupSnapshotClasses = volumeGroupSnapshotClassesSpec
 
 		return nil
 	}); err != nil {
@@ -130,3 +108,120 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getLocalStorageClassNames(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		if slices.Contains(supportedCsiDrivers, sc.Provisioner) {
+			storageClassNames[sc.Name] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, 0, len(storageClassNames))
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec = append(scSpec, ocsv1a1.StorageClassSpec{Name: scName})
+	}
+	return scSpec, nil
+}
+
+func getLocalVolumeSnapshotClassNames(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		if slices.Contains(supportedCsiDrivers, vsc.Driver) {
+			volumeSnapshotClassNames[vsc.Name] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, 0, len(volumeSnapshotClassNames))
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec = append(vscSpec, ocsv1a1.VolumeSnapshotClassSpec{Name: vscName})
+	}
+	return vscSpec, nil
+}
+
+func getLocalVolumeGroupSnapshotClassNames(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeGroupSnapshotClassSpec, error) {
+
+	volumeGroupSnapshotClassNames := map[string]bool{}
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.RbdGroupSnapshotter)] = true
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.CephfsGroupSnapshotter)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VolumeGroupSnapshotClassCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		// for day2 volumegroupsnapshotclasses
+		volumeGroupSnapshotClassesInCluster := &groupsnapapi.VolumeGroupSnapshotClassList{}
+		if err := kubeClient.List(ctx, volumeGroupSnapshotClassesInCluster); err != nil {
+			return nil, err
+		}
+		for idx := range volumeGroupSnapshotClassesInCluster.Items {
+			// TODO: skip volumegroupsnapshotclasses that are from external mode if both internal & external mode is enabled
+			vgsc := &volumeGroupSnapshotClassesInCluster.Items[idx]
+			if slices.Contains(supportedCsiDrivers, vgsc.Driver) {
+				volumeGroupSnapshotClassNames[vgsc.Name] = true
+			}
+		}
+	}
+
+	vgscSpec := make([]ocsv1a1.VolumeGroupSnapshotClassSpec, 0, len(volumeGroupSnapshotClassNames))
+	for vscName := range maps.Keys(volumeGroupSnapshotClassNames) {
+		vgscSpec = append(vgscSpec, ocsv1a1.VolumeGroupSnapshotClassSpec{Name: vscName})
+	}
+	return vgscSpec, nil
+}
diff --git a/services/provider/server/server.go b/services/provider/server/server.go
index 043164cb31..df021fa5c0 100644
--- a/services/provider/server/server.go
+++ b/services/provider/server/server.go
@@ -1886,8 +1886,8 @@ func (s *OCSProviderServer) appendVolumeSnapshotClassKubeResources(
 		snapshotClassName := consumer.Spec.VolumeSnapshotClasses[i].Name
 		vscGen := vscMap[snapshotClassName]
 		if vscGen != nil {
-			vsc := vscGen()
-			vsc.Name = snapshotClassName
+			snapshotClass = vscGen()
+			snapshotClass.Name = snapshotClassName
 		} else {
 			snapshotClass, err = util.VolumeSnapshotClassFromExisting(
 				ctx,
@@ -1951,8 +1951,8 @@ func (s *OCSProviderServer) appendVolumeGroupSnapshotClassKubeResources(
 		groupSnapshotClassName := consumer.Spec.VolumeGroupSnapshotClasses[i].Name
 		vgscGen := vgscMap[groupSnapshotClassName]
 		if vgscGen != nil {
-			vgsc := vgscGen()
-			vgsc.Name = groupSnapshotClassName
+			groupSnapshotClass = vgscGen()
+			groupSnapshotClass.Name = groupSnapshotClassName
 		} else {
 			groupSnapshotClass, err = util.VolumeGroupSnapshotClassFromExisting(
 				ctx,


Reviews:
user: login: nb-ohad
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-14T20:49:48Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:45:35Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:45:40Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:46:05Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:46:11Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:46:15Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:46:20Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:46:28Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:46:34Z
user: login: leelavg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T03:46:39Z

Review comments:
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: There is no reason to mention distribution as the list coming our of this function is only used for local storage classes.  
```suggestion
func getLocalStorageClassNames(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
```

created_at: 2025-04-14T20:39:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: As the wanted capacity is known there is no point in using an index. Using append is more idiomatic and with a known capacity will not re-allocate

```suggestion
	scSpec := make([]ocsv1a1.StorageClassSpec, 0, len(storageClassNames))
	for scName := range maps.Keys(storageClassNames) {
		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
		// not doing now as we only have name in the storageclassspec
		scSpec = append(scSpec, ocsv1a1.StorageClassSpec{Name: scName})
	}
```
created_at: 2025-04-14T20:42:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: There is no reason to mention distribution as the list coming our of this function is only used for local snapshot classes.
```suggestion
func getVolumeSnapshotClassNames(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
```
created_at: 2025-04-14T20:43:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: This can be simplified to use the name and provisioner only once:
```suggestion
		sc := &storageClassesInCluster.Items[idx]
		if slices.Contains(supportedCsiDrivers, sc.Provisioner) {
			storageClassNames[sc.Name] = true
		}
```
created_at: 2025-04-14T20:45:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: This can be simplified to use the name and driver only once:

```suggestion
	for idx := range volumeSnapshotClassesInCluster.Items {
		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
		vsc := &volumeSnapshotClassesInCluster.Items[idx]
		if slices.Contains(vscsupportedCsiDrivers, vsc.Driver) {
			volumeSnapshotClassNames[vsc.Name] = true
		}
	}
```
created_at: 2025-04-14T20:46:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, len(volumeSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec[idx] = ocsv1a1.VolumeSnapshotClassSpec{Name: vscName}
+		idx++
+	}
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: As the wanted capacity is known there is no point in using an index. Using append is more idiomatic and with a known capacity will not re-allocate

```suggestion
	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, 0, len(volumeSnapshotClassNames))
	for vscName := range maps.Keys(volumeSnapshotClassNames) {
		vscSpec = append(csvSpec, ocsv1a1.VolumeSnapshotClassSpec{Name: vscName})
	}
```
created_at: 2025-04-14T20:47:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, len(volumeSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec[idx] = ocsv1a1.VolumeSnapshotClassSpec{Name: vscName}
+		idx++
+	}
+	return vscSpec, nil
+}
+
+func getVolumeGroupSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: There is no reason to mention distribution as the list coming our of this function is only used for local snapshot classes.

```suggestion
func getVolumeGroupSnapshotClassNames(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
```
created_at: 2025-04-14T20:48:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, len(volumeSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec[idx] = ocsv1a1.VolumeSnapshotClassSpec{Name: vscName}
+		idx++
+	}
+	return vscSpec, nil
+}
+
+func getVolumeGroupSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeGroupSnapshotClassSpec, error) {
+
+	volumeGroupSnapshotClassNames := map[string]bool{}
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.RbdGroupSnapshotter)] = true
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.CephfsGroupSnapshotter)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VolumeGroupSnapshotClassCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		// for day2 volumegroupsnapshotclasses
+		volumeGroupSnapshotClassesInCluster := &groupsnapapi.VolumeGroupSnapshotClassList{}
+		if err := kubeClient.List(ctx, volumeGroupSnapshotClassesInCluster); err != nil {
+			return nil, err
+		}
+		for idx := range volumeGroupSnapshotClassesInCluster.Items {
+			// TODO: skip volumegroupsnapshotclasses that are from external mode if both internal & external mode is enabled
+			vgsc := &volumeGroupSnapshotClassesInCluster.Items[idx]
+			vgscName := vgsc.Name
+			vgscDriver := vgsc.Driver
+			if slices.Contains(supportedCsiDrivers, vgscDriver) && !volumeGroupSnapshotClassNames[vgscName] {
+				volumeGroupSnapshotClassNames[vgscName] = true
+			}
+		}
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: This can be simplified to use the name and driver only once:
```suggestion
		for idx := range volumeGroupSnapshotClassesInCluster.Items {
			// TODO: skip volumegroupsnapshotclasses that are from external mode if both internal & external mode is enabled
			vgsc := &volumeGroupSnapshotClassesInCluster.Items[idx]
			if slices.Contains(supportedCsiDrivers, vgsc.Driver)  {
				volumeGroupSnapshotClassNames[vgsc.Name] = true
			}
		}
```
created_at: 2025-04-14T20:48:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, len(volumeSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec[idx] = ocsv1a1.VolumeSnapshotClassSpec{Name: vscName}
+		idx++
+	}
+	return vscSpec, nil
+}
+
+func getVolumeGroupSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeGroupSnapshotClassSpec, error) {
+
+	volumeGroupSnapshotClassNames := map[string]bool{}
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.RbdGroupSnapshotter)] = true
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.CephfsGroupSnapshotter)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VolumeGroupSnapshotClassCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		// for day2 volumegroupsnapshotclasses
+		volumeGroupSnapshotClassesInCluster := &groupsnapapi.VolumeGroupSnapshotClassList{}
+		if err := kubeClient.List(ctx, volumeGroupSnapshotClassesInCluster); err != nil {
+			return nil, err
+		}
+		for idx := range volumeGroupSnapshotClassesInCluster.Items {
+			// TODO: skip volumegroupsnapshotclasses that are from external mode if both internal & external mode is enabled
+			vgsc := &volumeGroupSnapshotClassesInCluster.Items[idx]
+			vgscName := vgsc.Name
+			vgscDriver := vgsc.Driver
+			if slices.Contains(supportedCsiDrivers, vgscDriver) && !volumeGroupSnapshotClassNames[vgscName] {
+				volumeGroupSnapshotClassNames[vgscName] = true
+			}
+		}
+	}
+
+	vgscSpec := make([]ocsv1a1.VolumeGroupSnapshotClassSpec, len(volumeGroupSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeGroupSnapshotClassNames) {
+		vgscSpec[idx] = ocsv1a1.VolumeGroupSnapshotClassSpec{Name: vscName}
+		idx++
+	}
path: controllers/storagecluster/storageconsumer.go
user: login: nb-ohad
body: As the wanted capacity is known there is no point in using an index. Using append is more idiomatic and with a known capacity will not re-allocate
```suggestion
	vgscSpec := make([]ocsv1a1.VolumeGroupSnapshotClassSpec, 0, len(volumeGroupSnapshotClassNames))
	for vscName := range maps.Keys(volumeGroupSnapshotClassNames) {
		vgscSpec = append(vgscSpec, ocsv1a1.VolumeGroupSnapshotClassSpec{Name: vscName})
	}
```
created_at: 2025-04-14T20:49:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: done.
created_at: 2025-04-15T03:45:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: done.
created_at: 2025-04-15T03:45:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: aligned to `getLocalVolumeSnapshotClassNames` in the first comment.
created_at: 2025-04-15T03:46:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: done.
created_at: 2025-04-15T03:46:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: done.
created_at: 2025-04-15T03:46:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, len(volumeSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec[idx] = ocsv1a1.VolumeSnapshotClassSpec{Name: vscName}
+		idx++
+	}
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: done.
created_at: 2025-04-15T03:46:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, len(volumeSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec[idx] = ocsv1a1.VolumeSnapshotClassSpec{Name: vscName}
+		idx++
+	}
+	return vscSpec, nil
+}
+
+func getVolumeGroupSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: aligned to `getLocalVolumeGroupSnapshotClassNames` in the first comment.
created_at: 2025-04-15T03:46:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, len(volumeSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec[idx] = ocsv1a1.VolumeSnapshotClassSpec{Name: vscName}
+		idx++
+	}
+	return vscSpec, nil
+}
+
+func getVolumeGroupSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeGroupSnapshotClassSpec, error) {
+
+	volumeGroupSnapshotClassNames := map[string]bool{}
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.RbdGroupSnapshotter)] = true
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.CephfsGroupSnapshotter)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VolumeGroupSnapshotClassCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		// for day2 volumegroupsnapshotclasses
+		volumeGroupSnapshotClassesInCluster := &groupsnapapi.VolumeGroupSnapshotClassList{}
+		if err := kubeClient.List(ctx, volumeGroupSnapshotClassesInCluster); err != nil {
+			return nil, err
+		}
+		for idx := range volumeGroupSnapshotClassesInCluster.Items {
+			// TODO: skip volumegroupsnapshotclasses that are from external mode if both internal & external mode is enabled
+			vgsc := &volumeGroupSnapshotClassesInCluster.Items[idx]
+			vgscName := vgsc.Name
+			vgscDriver := vgsc.Driver
+			if slices.Contains(supportedCsiDrivers, vgscDriver) && !volumeGroupSnapshotClassNames[vgscName] {
+				volumeGroupSnapshotClassNames[vgscName] = true
+			}
+		}
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: done.
created_at: 2025-04-15T03:46:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -130,3 +108,132 @@ func (s *storageConsumer) ensureDeleted(_ *StorageClusterReconciler, _ *ocsv1.St
 	// cleaned up via owner references
 	return ctrl.Result{}, nil
 }
+
+func getStorageClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.StorageClassSpec, error) {
+
+	storageClassNames := map[string]bool{}
+	storageClassNames[util.GenerateNameForCephBlockPoolStorageClass(storageCluster)] = true
+	storageClassNames[util.GenerateNameForCephFilesystemStorageClass(storageCluster)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VirtualMachineCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		storageClassNames[util.GenerateNameForCephBlockPoolVirtualizationStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.ManagedResources.CephNonResilientPools.Enable {
+		storageClassNames[util.GenerateNameForNonResilientCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		storageClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	if storageCluster.Spec.Encryption.StorageClass && storageCluster.Spec.Encryption.KeyManagementService.Enable {
+		storageClassNames[util.GenerateNameForEncryptedCephBlockPoolStorageClass(storageCluster)] = true
+	}
+
+	// for day2 storageclasses
+	storageClassesInCluster := &storagev1.StorageClassList{}
+	if err := kubeClient.List(ctx, storageClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range storageClassesInCluster.Items {
+		// TODO: skip storageclasses that are from external mode if both internal & external mode is enabled
+		sc := &storageClassesInCluster.Items[idx]
+		scName := sc.Name
+		scProvisioner := sc.Provisioner
+		if slices.Contains(supportedCsiDrivers, scProvisioner) && !storageClassNames[scName] {
+			storageClassNames[scName] = true
+		}
+	}
+
+	scSpec := make([]ocsv1a1.StorageClassSpec, len(storageClassNames))
+	idx := 0
+	for scName := range maps.Keys(storageClassNames) {
+		// TODO: store the spec as the value which allows each value to be customizable corresponding to the name,
+		// not doing now as we only have name in the storageclassspec
+		scSpec[idx] = ocsv1a1.StorageClassSpec{Name: scName}
+		idx++
+	}
+	return scSpec, nil
+}
+
+func getVolumeSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeSnapshotClassSpec, error) {
+
+	volumeSnapshotClassNames := map[string]bool{}
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.RbdSnapshotter)] = true
+	volumeSnapshotClassNames[util.GenerateNameForSnapshotClass(storageCluster.Name, util.CephfsSnapshotter)] = true
+
+	if storageCluster.Spec.NFS != nil && storageCluster.Spec.NFS.Enable {
+		volumeSnapshotClassNames[util.GenerateNameForCephNetworkFilesystemStorageClass(storageCluster)] = true
+	}
+
+	// for day2 volumesnapshotclasses
+	volumeSnapshotClassesInCluster := &snapapi.VolumeSnapshotClassList{}
+	if err := kubeClient.List(ctx, volumeSnapshotClassesInCluster); err != nil {
+		return nil, err
+	}
+	for idx := range volumeSnapshotClassesInCluster.Items {
+		// TODO: skip volumesnapshotclasses that are from external mode if both internal & external mode is enabled
+		vsc := &volumeSnapshotClassesInCluster.Items[idx]
+		vscName := vsc.Name
+		vscDriver := vsc.Driver
+		if slices.Contains(supportedCsiDrivers, vscDriver) && !volumeSnapshotClassNames[vscName] {
+			volumeSnapshotClassNames[vscName] = true
+		}
+	}
+
+	vscSpec := make([]ocsv1a1.VolumeSnapshotClassSpec, len(volumeSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeSnapshotClassNames) {
+		vscSpec[idx] = ocsv1a1.VolumeSnapshotClassSpec{Name: vscName}
+		idx++
+	}
+	return vscSpec, nil
+}
+
+func getVolumeGroupSnapshotClassesForDistribution(ctx context.Context, kubeClient client.Client, storageCluster *ocsv1.StorageCluster) (
+	[]ocsv1a1.VolumeGroupSnapshotClassSpec, error) {
+
+	volumeGroupSnapshotClassNames := map[string]bool{}
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.RbdGroupSnapshotter)] = true
+	volumeGroupSnapshotClassNames[util.GenerateNameForGroupSnapshotClass(storageCluster, util.CephfsGroupSnapshotter)] = true
+
+	crd := &metav1.PartialObjectMetadata{}
+	crd.SetGroupVersionKind(extv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"))
+	crd.Name = VolumeGroupSnapshotClassCrdName
+	if err := kubeClient.Get(ctx, client.ObjectKeyFromObject(crd), crd); client.IgnoreNotFound(err) != nil {
+		return nil, err
+	}
+	if crd.UID != "" {
+		// for day2 volumegroupsnapshotclasses
+		volumeGroupSnapshotClassesInCluster := &groupsnapapi.VolumeGroupSnapshotClassList{}
+		if err := kubeClient.List(ctx, volumeGroupSnapshotClassesInCluster); err != nil {
+			return nil, err
+		}
+		for idx := range volumeGroupSnapshotClassesInCluster.Items {
+			// TODO: skip volumegroupsnapshotclasses that are from external mode if both internal & external mode is enabled
+			vgsc := &volumeGroupSnapshotClassesInCluster.Items[idx]
+			vgscName := vgsc.Name
+			vgscDriver := vgsc.Driver
+			if slices.Contains(supportedCsiDrivers, vgscDriver) && !volumeGroupSnapshotClassNames[vgscName] {
+				volumeGroupSnapshotClassNames[vgscName] = true
+			}
+		}
+	}
+
+	vgscSpec := make([]ocsv1a1.VolumeGroupSnapshotClassSpec, len(volumeGroupSnapshotClassNames))
+	idx := 0
+	for vscName := range maps.Keys(volumeGroupSnapshotClassNames) {
+		vgscSpec[idx] = ocsv1a1.VolumeGroupSnapshotClassSpec{Name: vscName}
+		idx++
+	}
path: controllers/storagecluster/storageconsumer.go
user: login: leelavg
body: done.
created_at: 2025-04-15T03:46:39Z
author_association: CONTRIBUTOR

PR comments:
user: login: leelavg
created_at: 2025-04-10T12:35:47Z
body: /retest-required
author_association: CONTRIBUTOR
user: login: nb-ohad
created_at: 2025-04-15T07:55:08Z
body: /lgtm

author_association: CONTRIBUTOR
user: login: leelavg
created_at: 2025-04-15T08:02:47Z
body: /test ocs-operator-bundle-e2e-aws
author_association: CONTRIBUTOR
user: login: leelavg
created_at: 2025-04-15T09:12:43Z
body: /cherrypick release-4.19
author_association: CONTRIBUTOR
user: login: openshift-cherrypick-robot
created_at: 2025-04-15T09:12:46Z
body: @leelavg: once the present PR merges, I will cherry-pick it on top of `release-4.19` in a new PR and assign it to you.

<details>

In response to [this](https://github.com/red-hat-storage/ocs-operator/pull/3152#issuecomment-2804377418):

>/cherrypick release-4.19


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
author_association: NONE
user: login: leelavg
created_at: 2025-04-15T10:37:43Z
body: /hold
author_association: CONTRIBUTOR
user: login: rewantsoni
created_at: 2025-04-15T10:47:48Z
body: /lgtm
author_association: MEMBER
user: login: openshift-ci[bot]
created_at: 2025-04-15T10:47:57Z
body: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/red-hat-storage/ocs-operator/pull/3152#" title="Author self-approved">leelavg</a>*, *<a href="https://github.com/red-hat-storage/ocs-operator/pull/3152#issuecomment-2804159287" title="LGTM">nb-ohad</a>*, *<a href="https://github.com/red-hat-storage/ocs-operator/pull/3152#issuecomment-2804636088" title="LGTM">rewantsoni</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=red-hat-storage%2Focs-operator).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/red-hat-storage/ocs-operator/blob/main/OWNERS)~~ [nb-ohad]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
author_association: CONTRIBUTOR
user: login: agarwal-mudit
created_at: 2025-04-15T10:54:36Z
body: /cherry-pick release-4.19
author_association: MEMBER
user: login: openshift-cherrypick-robot
created_at: 2025-04-15T10:54:40Z
body: @agarwal-mudit: once the present PR merges, I will cherry-pick it on top of `release-4.19` in a new PR and assign it to you.

<details>

In response to [this](https://github.com/red-hat-storage/ocs-operator/pull/3152#issuecomment-2804652081):

>/cherry-pick release-4.19


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
author_association: NONE
user: login: leelavg
created_at: 2025-04-15T11:02:06Z
body: Testing
```
> k get sc
NAME                                         PROVISIONER                             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
gp2-csi                                      ebs.csi.aws.com                         Delete          WaitForFirstConsumer   true                   33d
gp3-csi (default)                            ebs.csi.aws.com                         Delete          WaitForFirstConsumer   true                   33d
ocs-storagecluster-ceph-rbd                  openshift-storage.rbd.csi.ceph.com      Delete          Immediate              true                   38s
ocs-storagecluster-ceph-rbd-virtualization   openshift-storage.rbd.csi.ceph.com      Delete          Immediate              true                   38s
ocs-storagecluster-cephfs                    openshift-storage.cephfs.csi.ceph.com   Delete          Immediate              true                   37s
openshift-storage.noobaa.io                  openshift-storage.noobaa.io/obc         Delete          Immediate              false                  6d1h

> k get storageconsumer internal -oyaml | yq -r .spec.storageClasses
- name: ocs-storagecluster-ceph-rbd
- name: ocs-storagecluster-cephfs
- name: ocs-storagecluster-ceph-rbd-virtualization

------------- created a new sc
> cat /tmp/day2-sc.yaml | tee /dev/tty | k create -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: day2-sc
parameters:
  csi.storage.k8s.io/fstype: ext4
  imageFeatures: layering,deep-flatten,exclusive-lock,object-map,fast-diff
  imageFormat: "2"
  pool: ocs-storagecluster-cephblockpool
allowVolumeExpansion: true
provisioner: openshift-storage.rbd.csi.ceph.com
reclaimPolicy: Delete
volumeBindingMode: Immediate
storageclass.storage.k8s.io/day2-sc created

--------------- automatically picked by consumer
> k get storageconsumer internal -oyaml | yq -r .spec.storageClasses
- name: ocs-storagecluster-cephfs
- name: ocs-storagecluster-ceph-rbd-virtualization
- name: day2-sc
- name: ocs-storagecluster-ceph-rbd

--------------- fields corresponding to the consumer will be updated and
--------------- this follow is same for distributing to external clients
> k get sc day2-sc -oyaml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  creationTimestamp: "2025-04-15T11:01:01Z"
  labels:
    ramendr.openshift.io/storageid: c5bea2800817b44fb9454f4ba332244b
  name: day2-sc
  ownerReferences:
  - apiVersion: ocs.openshift.io/v1alpha1
    kind: StorageClient
    name: ocs-storagecluster
    uid: 86d867ca-da88-4974-9b3d-903b525df3c3
  resourceVersion: "22190497"
  uid: da5f1daf-e304-477d-b45a-e1e9647419ec
parameters:
  clusterID: openshift-storage
  csi.storage.k8s.io/controller-expand-secret-name: rbd-provisioner-1feeb002-c15c-4078-89bf-0a3440f21c01
  csi.storage.k8s.io/controller-expand-secret-namespace: openshift-storage
  csi.storage.k8s.io/fstype: ext4
  csi.storage.k8s.io/node-stage-secret-name: rbd-node-1feeb002-c15c-4078-89bf-0a3440f21c01
  csi.storage.k8s.io/node-stage-secret-namespace: openshift-storage
  csi.storage.k8s.io/provisioner-secret-name: rbd-provisioner-1feeb002-c15c-4078-89bf-0a3440f21c01
  csi.storage.k8s.io/provisioner-secret-namespace: openshift-storage
  imageFeatures: layering,deep-flatten,exclusive-lock,object-map,fast-diff
  imageFormat: "2"
  pool: ocs-storagecluster-cephblockpool
provisioner: openshift-storage.rbd.csi.ceph.com
reclaimPolicy: Delete
volumeBindingMode: Immediate

---- same for volumesnapshotclasses
> k get vsclass
NAME                                        DRIVER                                  DELETIONPOLICY   AGE
csi-aws-vsc                                 ebs.csi.aws.com                         Delete           33d
ocs-storagecluster-cephfsplugin-snapclass   openshift-storage.cephfs.csi.ceph.com   Delete           28s
ocs-storagecluster-rbdplugin-snapclass      openshift-storage.rbd.csi.ceph.com      Delete           28s

> k get storageconsumer internal -oyaml | yq -r .spec.volumeSnapshotClasses
- name: ocs-storagecluster-cephfsplugin-snapclass
- name: ocs-storagecluster-rbdplugin-snapclass

> cat /tmp/day2-vsclass.yaml | tee /dev/tty | k create -f -
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: day2-vsclass
deletionPolicy: Delete
driver: openshift-storage.cephfs.csi.ceph.com
volumesnapshotclass.snapshot.storage.k8s.io/day2-vsclass created

> k get storageconsumer internal -oyaml | yq -r .spec.volumeSnapshotClasses
- name: ocs-storagecluster-rbdplugin-snapclass
- name: ocs-storagecluster-cephfsplugin-snapclass
- name: day2-vsclass

> k get vsclass day2-vsclass -oyaml
apiVersion: snapshot.storage.k8s.io/v1
deletionPolicy: Delete
driver: openshift-storage.cephfs.csi.ceph.com
kind: VolumeSnapshotClass
metadata:
  creationTimestamp: "2025-04-15T11:14:01Z"
  generation: 1
  labels:
    ramendr.openshift.io/storageid: 86baad744c26cd8c16473e3ddc547605
  name: day2-vsclass
  ownerReferences:
  - apiVersion: ocs.openshift.io/v1alpha1
    kind: StorageClient
    name: ocs-storagecluster
    uid: 86d867ca-da88-4974-9b3d-903b525df3c3
  resourceVersion: "22197390"
  uid: d517004d-2ad0-4b77-91f1-e0fe7f50e12b
parameters:
  clusterID: openshift-storage
  csi.storage.k8s.io/snapshotter-secret-name: cephfs-provisioner-1feeb002-c15c-4078-89bf-0a3440f21c01
  csi.storage.k8s.io/snapshotter-secret-namespace: openshift-storage
```
author_association: CONTRIBUTOR
user: login: leelavg
created_at: 2025-04-15T11:10:07Z
body: /unhold

testing results are provided
author_association: CONTRIBUTOR
user: login: openshift-cherrypick-robot
created_at: 2025-04-15T11:15:02Z
body: @leelavg: new pull request created: #3164

<details>

In response to [this](https://github.com/red-hat-storage/ocs-operator/pull/3152#issuecomment-2804377418):

>/cherrypick release-4.19


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
author_association: NONE