Repository: rook/rook
Pull request #11975 (2023-03-24 10:12:51)

object: check obc provisioner for bucket notification


<!-- Please take a look at our [Contributing](https://rook.io/docs/rook/latest/Contributing/development-flow/)
documentation before submitting a Pull Request!
Thank you for contributing to Rook! -->

**Description of your changes:**
obc-label-controller needs to check only the obc provisioned by the Rook operator.
Check other OBCs result in errors from the controller and keep on reconcilling

**Which issue is resolved by this Pull Request:**
Resolves #

**Checklist:**

- [ ] **Commit Message Formatting**: Commit titles and messages follow guidelines in the [developer guide](https://rook.io/docs/rook/latest/Contributing/development-flow/#commit-structure)).
- [ ] **Skip Tests for Docs**: If this is only a documentation change, add the label `skip-ci` on the PR.
- [ ] Reviewed the developer guide on [Submitting a Pull Request](https://rook.io/docs/rook/latest/Contributing/development-flow/#submitting-a-pull-request)
- [ ] [Pending release notes](https://github.com/rook/rook/blob/master/PendingReleaseNotes.md) updated with breaking and/or notable changes for the next minor release.
- [ ] Documentation has been updated, if necessary.
- [ ] Unit tests have been added, if necessary.
- [ ] Integration tests have been added, if necessary.


yuvalif: @thotz maybe a simpler way is to use the error returned from the name parsing function as an indication that the bucket was provisioned by an external provisioner, and let the bucket notification controller ignore it without an error?
travisn: @thotz The object integration tests are failing with this error:
```
=== RUN   TestCephObjectSuite/TestWithTLS/perform_s3_operations_and_check_for_notifications/check_for_put_bucket_notification
2023-03-27 12:10:33.431665 D | exec: Running command: kubectl logs --selector=app=sample-http-server --tail 5
    ceph_bucket_notification_test.go:142: 
        	Error Trace:	/home/runner/work/rook/rook/tests/integration/ceph_bucket_notification_test.go:142
        	Error:      	Should be true
        	Test:       	TestCephObjectSuite/TestWithTLS/perform_s3_operations_and_check_for_notifications/check_for_put_bucket_notification
```
BlaineEXE: Thanks for the good test updates in the PR. I think it looks good other than the small integration test bug Travis pointed out
thotz: > @thotz The object integration tests are failing with this error:
> 
> ```
> === RUN   TestCephObjectSuite/TestWithTLS/perform_s3_operations_and_check_for_notifications/check_for_put_bucket_notification
> 2023-03-27 12:10:33.431665 D | exec: Running command: kubectl logs --selector=app=sample-http-server --tail 5
>     ceph_bucket_notification_test.go:142: 
>         	Error Trace:	/home/runner/work/rook/rook/tests/integration/ceph_bucket_notification_test.go:142
>         	Error:      	Should be true
>         	Test:       	TestCephObjectSuite/TestWithTLS/perform_s3_operations_and_check_for_notifications/check_for_put_bucket_notification
> ```

I thought the provisioner's name was the combination of Rook Operator Namespace and "ceph.rook.io/bucket". But the current code uses the ceph cluster namespace. I am confused about how to get that here. In the Bucketprovisioner the are finding the ceph cluster details using the following,
```golang
cephCluster := &cephv1.CephCluster{}
	err := r.client.Get(r.opManagerContext, request.NamespacedName, cephCluster)
	if err != nil {
		if kerrors.IsNotFound(err) {
			logger.Infof("no ceph cluster found in %+v. not deploying the bucket provisioner", request.NamespacedName)
			return reconcile.Result{}, nil
		}
		// Error reading the object - requeue the request.
		return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed to get the ceph cluster")
	}

	if !cephCluster.DeletionTimestamp.IsZero() {
		logger.Debug("ceph cluster is being deleted, no need to reconcile the bucket provisioner")
		return reconcile.Result{}, nil
	}

	if !cephCluster.Spec.External.Enable && cephCluster.Spec.CleanupPolicy.HasDataDirCleanPolicy() {
		logger.Debug("ceph cluster has cleanup policy, the cluster will soon go away, no need to reconcile the bucket provisioner")
		return reconcile.Result{}, nil
	}
```
The `request.NamespacedName` should be the name space of OBC right and AFAIK obc can exist  any namespace than the ceph objectstore
travisn: The namespace of the cephcluster is the same as the namespace of the object store. Would this method help? `getNSNameFromAdditionalState()`?
thotz: > The namespace of the cephcluster is the same as the namespace of the object store. Would this method help? `getNSNameFromAdditionalState()`?

That function was erroring out while handling OBC which were not provisioned by Rook. So I thought handling this check before fetching details about object store in the OBC

Patch:
diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml
index 71d98eb81..c56915e8a 100644
--- a/.github/workflows/helm-lint.yaml
+++ b/.github/workflows/helm-lint.yaml
@@ -40,7 +40,7 @@ jobs:
           python-version: 3.9
 
       - name: Set up chart-testing
-        uses: helm/chart-testing-action@v2.4.0
+        uses: helm/chart-testing-action@v2.3.1
 
       - name: Run chart-testing (lint)
         run: ct lint --charts=./deploy/charts/rook-ceph --validate-yaml=false --validate-maintainers=false
diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml
index d94d9e0c3..337ac1b2a 100644
--- a/.github/workflows/stale.yaml
+++ b/.github/workflows/stale.yaml
@@ -15,7 +15,7 @@ jobs:
     runs-on: ubuntu-20.04
     if: github.repository == 'rook/rook'
     steps:
-      - uses: actions/stale@v8
+      - uses: actions/stale@v7
         with:
           repo-token: ${{ secrets.GITHUB_TOKEN }}
           days-before-issue-stale: 60
diff --git a/go.mod b/go.mod
index bf21aad77..caa2a25fa 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
 	github.com/go-ini/ini v1.67.0
 	github.com/google/go-cmp v0.5.9
 	github.com/google/uuid v1.3.0
-	github.com/hashicorp/vault v1.13.1
+	github.com/hashicorp/vault v1.13.0
 	github.com/hashicorp/vault-plugin-secrets-kv v0.14.3
 	github.com/hashicorp/vault/api v1.9.0
 	github.com/hashicorp/vault/sdk v0.8.1
diff --git a/go.sum b/go.sum
index e55826aa5..e927c3738 100644
--- a/go.sum
+++ b/go.sum
@@ -952,8 +952,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
 github.com/hashicorp/serf v0.8.3/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k=
 github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
 github.com/hashicorp/vault v1.4.2/go.mod h1:500fLOj7p92Ys4X265LizqF78MzmHJUf1jV1zNJt060=
-github.com/hashicorp/vault v1.13.1 h1:4Q31hCWCwD2XRCwGL+9gsrCwxn6+ngToBgjT0FCTG+M=
-github.com/hashicorp/vault v1.13.1/go.mod h1:aD5a/VHOADe8hiMHx4rYJwv6W6+1WYlco/hf8MWbYaw=
+github.com/hashicorp/vault v1.13.0 h1:/J/ldGnqRHKDlaSznOQAXy4STah76tCYy2fsUSsvYwk=
+github.com/hashicorp/vault v1.13.0/go.mod h1:W1VOUMJ1klrGAHFnTJYDw2N2RlBh+kdwmCyYZTSGap0=
 github.com/hashicorp/vault-plugin-auth-alicloud v0.5.5/go.mod h1:sQ+VNwPQlemgXHXikYH6onfH9gPwDZ1GUVRLz0ZvHx8=
 github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 h1:O6tNk0s/arubLUbLeCyaRs5xGo9VwmbQazISY/BfPK4=
 github.com/hashicorp/vault-plugin-auth-azure v0.5.6-0.20200422235613-1b5c70f9ef68/go.mod h1:RCVBsf8AJndh4c6iGZtvVZFui9SG0Bj9fnF0SodNIkw=
@@ -975,7 +975,7 @@ github.com/hashicorp/vault-plugin-auth-oci v0.5.4/go.mod h1:j05O2b9fw2Q82NxDPhHM
 github.com/hashicorp/vault-plugin-auth-oci v0.13.1 h1:xThaZC9jzZoqqccfxTk11hfwgqwN3yEZ3kYOnY2v2Fs=
 github.com/hashicorp/vault-plugin-database-couchbase v0.9.0 h1:hJOHJ9yZ9kt1/DuRaU5Sa339j3/QcPL4esT9JLQonYA=
 github.com/hashicorp/vault-plugin-database-elasticsearch v0.5.4/go.mod h1:QjGrrxcRXv/4XkEZAlM0VMZEa3uxKAICFqDj27FP/48=
-github.com/hashicorp/vault-plugin-database-elasticsearch v0.13.1 h1:nVO6F8V69E2fAQklh/Ds+EypVMutN4iIlt3sat9qW9M=
+github.com/hashicorp/vault-plugin-database-elasticsearch v0.13.0 h1:NwcbzQB529WtB/m7tZKxKiB6pQc0IyD3L80tk3mtBl8=
 github.com/hashicorp/vault-plugin-database-mongodbatlas v0.1.2-0.20200520204052-f840e9d4895c/go.mod h1:MP3kfr0N+7miOTZFwKv952b9VkXM4S2Q6YtQCiNKWq8=
 github.com/hashicorp/vault-plugin-database-mongodbatlas v0.9.0 h1:wlWrg1z5Pyx+FTUCOzA9yh0FTI+pfA9tMrsFPFBcjjA=
 github.com/hashicorp/vault-plugin-database-redis v0.2.0 h1:Fg1inevnDhj58+/y5SY1CihLftytG1D+3QqbUJbHYUM=
@@ -999,7 +999,7 @@ github.com/hashicorp/vault-plugin-secrets-kv v0.14.3/go.mod h1:tQ87Y0wm1JhliWuiX
 github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.1.2/go.mod h1:YRW9zn9NZNitRlPYNAWRp/YEdKCF/X8aOg8IYSxFT5Y=
 github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.9.1 h1:WkW8fyHxEdz1wGSTxCnSCrzXvgLXqXr8Iqp7upa/s4E=
 github.com/hashicorp/vault-plugin-secrets-openldap v0.1.3-0.20200518214608-746aba5fead6/go.mod h1:9Cy4Jp779BjuIOhYLjEfH3M3QCUxZgPnvJ3tAOOmof4=
-github.com/hashicorp/vault-plugin-secrets-openldap v0.10.1 h1:EN3/iEjPPmcpX9yihybQNHvewc+YoJw7aoKsio1WK5s=
+github.com/hashicorp/vault-plugin-secrets-openldap v0.10.0 h1:Q3nKBbHQ6E/kOa3amKvcbhYTbkz4U25BBTwH66LnF+0=
 github.com/hashicorp/vault-plugin-secrets-terraform v0.7.0 h1:jgJpVKhV0Eh6EjpUEIf7VYH2D6D0xW2Lry9/3PI8hy0=
 github.com/hashicorp/vault/api v1.0.1/go.mod h1:AV/+M5VPDpB90arloVX0rVDUIHkONiwz5Uza9HRtpUE=
 github.com/hashicorp/vault/api v1.0.5-0.20190730042357-746c0b111519/go.mod h1:i9PKqwFko/s/aihU1uuHGh/FaQS+Xcgvd9dvnfAvQb0=
diff --git a/pkg/daemon/ceph/client/config.go b/pkg/daemon/ceph/client/config.go
index f2cc6119b..8d4148b0d 100644
--- a/pkg/daemon/ceph/client/config.go
+++ b/pkg/daemon/ceph/client/config.go
@@ -261,8 +261,7 @@ func PopulateMonHostMembers(clusterInfo *ClusterInfo) ([]string, []string) {
 		currentMonPort := cephutil.GetPortFromEndpoint(monitor.Endpoint)
 
 		if currentMonPort == Msgr2port {
-			msgr2Endpoint := net.JoinHostPort(monIP, strconv.Itoa(int(Msgr2port)))
-			monHosts = append(monHosts, "[v2:"+msgr2Endpoint+"]")
+			monHosts = append(monHosts, fmt.Sprintf("[v2:%s:%d]", monIP, Msgr2port))
 		} else {
 			msgr2Endpoint := net.JoinHostPort(monIP, strconv.Itoa(int(Msgr2port)))
 			msgr1Endpoint := net.JoinHostPort(monIP, strconv.Itoa(int(currentMonPort)))
diff --git a/pkg/daemon/ceph/osd/daemon.go b/pkg/daemon/ceph/osd/daemon.go
index 99a85b744..8bf087203 100644
--- a/pkg/daemon/ceph/osd/daemon.go
+++ b/pkg/daemon/ceph/osd/daemon.go
@@ -531,7 +531,19 @@ func getAvailableDevices(context *clusterd.Context, agent *OsdAgent) (*DeviceOsd
 
 				if matched {
 					matchedDevice = desiredDevice
-					matchedDevice.UpdateDeviceClass(agent, device)
+					if matchedDevice.DeviceClass == "" {
+						classNotSet := true
+						if agent.pvcBacked {
+							crushDeviceClass := os.Getenv(oposd.CrushDeviceClassVarName)
+							if crushDeviceClass != "" {
+								matchedDevice.DeviceClass = crushDeviceClass
+								classNotSet = false
+							}
+						}
+						if classNotSet {
+							matchedDevice.DeviceClass = sys.GetDiskDeviceClass(device)
+						}
+					}
 					break
 				}
 			}
diff --git a/pkg/daemon/ceph/osd/device.go b/pkg/daemon/ceph/osd/device.go
index 3c4676762..152666502 100644
--- a/pkg/daemon/ceph/osd/device.go
+++ b/pkg/daemon/ceph/osd/device.go
@@ -18,9 +18,7 @@ package osd
 
 import (
 	"encoding/json"
-	"os"
 
-	oposd "github.com/rook/rook/pkg/operator/ceph/cluster/osd"
 	"github.com/rook/rook/pkg/util/sys"
 )
 
@@ -69,29 +67,3 @@ func (m *DeviceOsdMapping) String() string {
 	b, _ := json.Marshal(m)
 	return string(b)
 }
-
-func (d *DesiredDevice) UpdateDeviceClass(agent *OsdAgent, device *sys.LocalDisk) {
-	// Rook sets the storage class of a device with the following priority.
-	//
-	// 1. the device-level configuration
-	// 2. the global or node-local configuration
-	// 3. the default value estimated from sysfs.
-	if d.DeviceClass != "" {
-		return
-	}
-
-	if agent.pvcBacked {
-		crushDeviceClass := os.Getenv(oposd.CrushDeviceClassVarName)
-		if crushDeviceClass != "" {
-			d.DeviceClass = crushDeviceClass
-			return
-		}
-	} else {
-		if agent.storeConfig.DeviceClass != "" {
-			d.DeviceClass = agent.storeConfig.DeviceClass
-			return
-		}
-	}
-
-	d.DeviceClass = sys.GetDiskDeviceClass(device)
-}
diff --git a/pkg/operator/ceph/csi/cluster_config.go b/pkg/operator/ceph/csi/cluster_config.go
index a9d62aa0e..043b094e6 100644
--- a/pkg/operator/ceph/csi/cluster_config.go
+++ b/pkg/operator/ceph/csi/cluster_config.go
@@ -108,10 +108,13 @@ func MonEndpoints(mons map[string]*cephclient.MonInfo, requireMsgr2 bool) []stri
 		endpoint := m.Endpoint
 		if requireMsgr2 {
 			logger.Debugf("evaluating mon %q for msgr1 on endpoint %q", m.Name, m.Endpoint)
-			msgr1Suffix := fmt.Sprintf(":%d", client.Msgr1port)
-			if strings.HasSuffix(m.Endpoint, msgr1Suffix) {
-				address := m.Endpoint[0:strings.LastIndex(m.Endpoint, msgr1Suffix)]
-				endpoint = fmt.Sprintf("%s:%d", address, client.Msgr2port)
+			if strings.HasSuffix(m.Endpoint, fmt.Sprintf(":%d", client.Msgr1port)) {
+				parts := strings.Split(m.Endpoint, ":")
+				if len(parts) != 2 {
+					logger.Errorf("endpoint %q does not contain two parts to extract the port", m.Endpoint)
+					continue
+				}
+				endpoint = fmt.Sprintf("%s:%d", parts[0], client.Msgr2port)
 				logger.Debugf("mon %q will use the msgrv2 port: %q", m.Name, endpoint)
 			}
 		}
diff --git a/pkg/operator/ceph/object/notification/obc_label_controller.go b/pkg/operator/ceph/object/notification/obc_label_controller.go
index 1a5f0d8cc..4aa07ca33 100644
--- a/pkg/operator/ceph/object/notification/obc_label_controller.go
+++ b/pkg/operator/ceph/object/notification/obc_label_controller.go
@@ -44,7 +44,9 @@ import (
 )
 
 const (
-	notificationLabelPrefix = "bucket-notification-"
+	notificationLabelPrefix   = "bucket-notification-"
+	bucketProvisionerLabelKey = "bucket-provisioner"
+	bucketProvisionerLabelVal = "ceph.rook.io-bucket"
 )
 
 // ReconcileOBCLabels reconciles a ObjectBucketClaim labels
@@ -119,11 +121,18 @@ func (r *ReconcileOBCLabels) reconcile(request reconcile.Request) (reconcile.Res
 	if err := r.client.Get(r.opManagerContext, bucketName, &ob); err != nil {
 		return reconcile.Result{}, errors.Wrapf(err, "failed to retrieve ObjectBucket %q", bucketName)
 	}
+
+	// validate if the bucket is provisioned by the ceph provisioner
+	if !strings.Contains(ob.Labels[bucketProvisionerLabelKey], bucketProvisionerLabelVal) {
+		logger.Debugf("ObjectBucket %q was not provisioned by the ceph object store provisioner and tagged with provisioner %q. ignoring",
+			bucketName, ob.Labels[bucketProvisionerLabelKey])
+		return reconcile.Result{}, nil
+	}
+	// validate object store name
 	objectStoreName, err := getCephObjectStoreName(ob)
 	if err != nil {
 		return reconcile.Result{}, errors.Wrapf(err, "failed to get object store from ObjectBucket %q", bucketName)
 	}
-
 	// Populate clusterInfo during each reconcile
 	clusterInfo, clusterSpec, err := getReadyCluster(r.client, r.opManagerContext, *r.context, objectStoreName.Namespace)
 	if err != nil {


Test patch:
diff --git a/pkg/daemon/ceph/osd/device_test.go b/pkg/daemon/ceph/osd/device_test.go
index bf445904d..312d7245e 100644
--- a/pkg/daemon/ceph/osd/device_test.go
+++ b/pkg/daemon/ceph/osd/device_test.go
@@ -23,9 +23,7 @@ import (
 
 	"github.com/rook/rook/pkg/clusterd"
 	"github.com/rook/rook/pkg/daemon/ceph/client"
-	"github.com/rook/rook/pkg/operator/ceph/cluster/osd"
 	exectest "github.com/rook/rook/pkg/util/exec/test"
-	"github.com/rook/rook/pkg/util/sys"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -49,36 +47,3 @@ func TestOSDBootstrap(t *testing.T) {
 	assert.NotEqual(t, -1, strings.Index(string(contents), "key = mysecurekey"))
 	assert.NotEqual(t, -1, strings.Index(string(contents), "caps mon = \"allow profile bootstrap-osd\""))
 }
-
-func TestUpdateDeviceClass(t *testing.T) {
-	d := &DesiredDevice{}
-	agent := &OsdAgent{}
-	disk := &sys.LocalDisk{}
-
-	d.DeviceClass = "test"
-	d.UpdateDeviceClass(agent, disk)
-	assert.Equal(t, "test", d.DeviceClass)
-
-	d.DeviceClass = ""
-	agent.pvcBacked = true
-	t.Setenv(osd.CrushDeviceClassVarName, "test")
-	d.UpdateDeviceClass(agent, disk)
-	assert.Equal(t, "test", d.DeviceClass)
-
-	d.DeviceClass = ""
-	t.Setenv(osd.CrushDeviceClassVarName, "")
-	d.UpdateDeviceClass(agent, disk)
-	t.Log(d)
-	t.Log(disk)
-	assert.Equal(t, "ssd", d.DeviceClass)
-
-	d.DeviceClass = ""
-	agent.pvcBacked = false
-	d.UpdateDeviceClass(agent, disk)
-	assert.Equal(t, "ssd", d.DeviceClass)
-
-	d.DeviceClass = ""
-	agent.storeConfig.DeviceClass = "test"
-	d.UpdateDeviceClass(agent, disk)
-	assert.Equal(t, "test", d.DeviceClass)
-}
diff --git a/pkg/operator/ceph/csi/cluster_config_test.go b/pkg/operator/ceph/csi/cluster_config_test.go
index 5f778a16d..dc64ed60f 100644
--- a/pkg/operator/ceph/csi/cluster_config_test.go
+++ b/pkg/operator/ceph/csi/cluster_config_test.go
@@ -369,20 +369,15 @@ func TestMonEndpoints(t *testing.T) {
 		verifyEndpointPort(t, endpoints, "3300")
 	})
 
-	t.Run("ipv6 endpoint conversion", func(t *testing.T) {
+	t.Run("bad endpoint", func(t *testing.T) {
 		monInfo := map[string]*cephclient.MonInfo{
-			"a": {Name: "a", Endpoint: "[fd07:aaaa:bbbb:cccc::11]:6789"},
-			"b": {Name: "a", Endpoint: "[1234:6789:bbbb:cccc::11]:6789"},
+			"a": {Name: "a", Endpoint: "1.2.3.4:5:6789"},
+			"b": {Name: "b", Endpoint: "1.2.3.5:6789"},
+			"c": {Name: "c", Endpoint: "1.2.3.6:6789"},
 		}
 		endpoints := MonEndpoints(monInfo, true)
 		assert.Equal(t, 2, len(endpoints))
 		verifyEndpointPort(t, endpoints, "3300")
-		for _, endpoint := range endpoints {
-			// Verify that the v1 port inside the ipv6 address will not be replaced
-			if strings.HasPrefix(endpoint, "[1234") {
-				assert.True(t, strings.HasPrefix(endpoint, "[1234:6789"))
-			}
-		}
 	})
 }
 
diff --git a/pkg/operator/ceph/object/notification/controller_test.go b/pkg/operator/ceph/object/notification/controller_test.go
index e31ea8abc..0b720f45e 100644
--- a/pkg/operator/ceph/object/notification/controller_test.go
+++ b/pkg/operator/ceph/object/notification/controller_test.go
@@ -57,6 +57,7 @@ var (
 	multipleCreateBucketName = "multi-create"
 	multipleDeleteBucketName = "multi-delete"
 	multipleBothBucketName   = "multi-both"
+	otherClusterBucketName   = "other-cluster"
 	startEvent               = string(cephv1.ReconcileStarted)
 	finishedEvent            = string(cephv1.ReconcileSucceeded)
 	failedEvent              = string(cephv1.ReconcileFailed)
diff --git a/pkg/operator/ceph/object/notification/obc_label_controller_test.go b/pkg/operator/ceph/object/notification/obc_label_controller_test.go
index 6a2425258..aa421a933 100644
--- a/pkg/operator/ceph/object/notification/obc_label_controller_test.go
+++ b/pkg/operator/ceph/object/notification/obc_label_controller_test.go
@@ -30,11 +30,16 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
-func createOBResources(name string) (*bktv1alpha1.ObjectBucketClaim, *bktv1alpha1.ObjectBucket) {
+const (
+	testProvisionerOtherCluster = "other-provisioner.io-bucket"
+)
+
+func createOBResources(name, provisioner string) (*bktv1alpha1.ObjectBucketClaim, *bktv1alpha1.ObjectBucket) {
 	return &bktv1alpha1.ObjectBucketClaim{
 			ObjectMeta: metav1.ObjectMeta{
 				Name:      name,
 				Namespace: testNamespace,
+				Labels:    map[string]string{bucketProvisionerLabelKey: provisioner},
 			},
 			TypeMeta: metav1.TypeMeta{
 				Kind: "ObjectBucketClaim",
@@ -50,6 +55,7 @@ func createOBResources(name string) (*bktv1alpha1.ObjectBucketClaim, *bktv1alpha
 			ObjectMeta: metav1.ObjectMeta{
 				Name:      name,
 				Namespace: testNamespace,
+				Labels:    map[string]string{bucketProvisionerLabelKey: provisioner},
 			},
 			TypeMeta: metav1.TypeMeta{
 				Kind: "ObjectBucket",
@@ -130,7 +136,7 @@ func TestCephBucketNotificationOBCLabelController(t *testing.T) {
 		},
 	}
 
-	obc, ob := createOBResources(testBucketName)
+	obc, ob := createOBResources(testBucketName, bucketProvisionerLabelVal)
 	obc.Labels = setNotificationLabels([]string{testNotificationName})
 
 	t.Run("provision OBC with notification label with no ob", func(t *testing.T) {
@@ -226,7 +232,7 @@ func TestCephBucketNotificationOBCLabelController(t *testing.T) {
 
 	t.Run("reconcile with already existing label for the obc", func(t *testing.T) {
 		resetValues()
-		noChangeOBC, noChangeOB := createOBResources(noChangeBucketName)
+		noChangeOBC, noChangeOB := createOBResources(noChangeBucketName, bucketProvisionerLabelVal)
 		noChangeOBC.Labels = setNotificationLabels([]string{testNotificationName})
 		noChangeOBC.Spec.ObjectBucketName = noChangeBucketName
 		noChangeOBC.Status.Phase = bktv1alpha1.ObjectBucketClaimStatusPhaseBound
@@ -249,7 +255,7 @@ func TestCephBucketNotificationOBCLabelController(t *testing.T) {
 
 	t.Run("delete notification from the obc", func(t *testing.T) {
 		resetValues()
-		deleteOBC, deleteOB := createOBResources(deleteBucketName)
+		deleteOBC, deleteOB := createOBResources(deleteBucketName, bucketProvisionerLabelVal)
 		deleteOBC.Spec.GenerateBucketName = deleteBucketName
 		deleteOBC.Spec.ObjectBucketName = deleteBucketName
 		deleteOBC.Status.Phase = bktv1alpha1.ObjectBucketClaimStatusPhaseBound
@@ -271,7 +277,7 @@ func TestCephBucketNotificationOBCLabelController(t *testing.T) {
 
 	t.Run("provision OBC with multiple notification labels", func(t *testing.T) {
 		resetValues()
-		multipleCreateOBC, multipleCreateOB := createOBResources(multipleCreateBucketName)
+		multipleCreateOBC, multipleCreateOB := createOBResources(multipleCreateBucketName, bucketProvisionerLabelVal)
 		multipleCreateOBC.Labels = setNotificationLabels([]string{testNotificationName + "-1", testNotificationName + "-2"})
 		multipleCreateOBC.Spec.ObjectBucketName = multipleCreateBucketName
 		multipleCreateOBC.Status.Phase = bktv1alpha1.ObjectBucketClaimStatusPhaseBound
@@ -298,7 +304,7 @@ func TestCephBucketNotificationOBCLabelController(t *testing.T) {
 
 	t.Run("delete multiple notifications from the obc", func(t *testing.T) {
 		resetValues()
-		multipleDeleteOBC, multipleDeleteOB := createOBResources(multipleDeleteBucketName)
+		multipleDeleteOBC, multipleDeleteOB := createOBResources(multipleDeleteBucketName, bucketProvisionerLabelVal)
 		multipleDeleteOBC.Spec.GenerateBucketName = multipleDeleteBucketName
 		multipleDeleteOBC.Spec.ObjectBucketName = multipleDeleteBucketName
 		multipleDeleteOBC.Status.Phase = bktv1alpha1.ObjectBucketClaimStatusPhaseBound
@@ -319,7 +325,7 @@ func TestCephBucketNotificationOBCLabelController(t *testing.T) {
 	})
 	t.Run("provision OBC with multiple delete and create of notifications", func(t *testing.T) {
 		resetValues()
-		multipleBothOBC, multipleBothOB := createOBResources(multipleBothBucketName)
+		multipleBothOBC, multipleBothOB := createOBResources(multipleBothBucketName, bucketProvisionerLabelVal)
 		multipleBothOBC.Labels = setNotificationLabels([]string{testNotificationName + "-1", testNotificationName + "-2"})
 		multipleBothOBC.Spec.ObjectBucketName = multipleBothBucketName
 		multipleBothOBC.Status.Phase = bktv1alpha1.ObjectBucketClaimStatusPhaseBound
@@ -346,4 +352,25 @@ func TestCephBucketNotificationOBCLabelController(t *testing.T) {
 			[]string{multipleDeleteBucketName + testNotificationName + "-1", multipleDeleteBucketName + testNotificationName + "-2"})
 		verifyEvents(t, []string{startEvent, finishedEvent})
 	})
+
+	t.Run("OBC does not belong to the ceph cluster", func(t *testing.T) {
+		resetValues()
+		otherClusterOBC, otherClusterOB := createOBResources(otherClusterBucketName, testProvisionerOtherCluster)
+		otherClusterOBC.Labels = setNotificationLabels([]string{testNotificationName})
+		otherClusterOBC.Spec.ObjectBucketName = otherClusterBucketName
+		otherClusterOBC.Status.Phase = bktv1alpha1.ObjectBucketClaimStatusPhaseBound
+		objects := []runtime.Object{
+			cephCluster,
+			otherClusterOBC,
+			otherClusterOB,
+		}
+
+		res, err := testOBCLabelReconciler(objects, otherClusterBucketName)
+		assert.NoError(t, err)
+		assert.False(t, res.Requeue)
+		assert.False(t, getWasInvoked)
+		assert.Equal(t, 0, len(createdNotifications))
+		assert.Equal(t, 0, len(deletedNotifications))
+		verifyEvents(t, []string{startEvent, finishedEvent})
+	})
 }
diff --git a/pkg/util/sys/device_test.go b/pkg/util/sys/device_test.go
index 01023c0ff..10342f857 100644
--- a/pkg/util/sys/device_test.go
+++ b/pkg/util/sys/device_test.go
@@ -196,13 +196,3 @@ func TestListDevicesChildListDevicesChild(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Equal(t, 3, len(child))
 }
-
-func TestGetDiskDeviceClass(t *testing.T) {
-	d := &LocalDisk{}
-	assert.Equal(t, "ssd", GetDiskDeviceClass(d))
-	d.Rotational = true
-	assert.Equal(t, "hdd", GetDiskDeviceClass(d))
-	d.Rotational = false
-	d.RealPath = "nvme"
-	assert.Equal(t, "nvme", GetDiskDeviceClass(d))
-}