Repository: rook/rook
Pull request #12437 (2023-06-27 17:51:56)

Multus Validation : Added verbs "deletecollection" 
Fix for Issue : https://github.com/rook/rook/issues/12435

Added verbs "deletecollection" to the "daemonsets" resource in role "rook-ceph-system"

<!-- Please take a look at our Contributing documentation before submitting a Pull Request!
https://rook.io/docs/rook/latest/Contributing/development-flow/

Thank you for contributing to Rook! -->

**Description of your changes:**

**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.


BlaineEXE: Would you update the commit message to follow our contributing guidelines here: https://rook.io/docs/rook/v1.11/Contributing/development-flow/#commit-structure?

You'll need a prefix, and please be specific in the subject and body about what changes and why. The commit body you have is good, just make sure to add that it is for the validation tool.

e.g.,

```
multus: add deletecollection capability for validation tool

<commit body>

Signed-off-by: ...
```
sudharsanomprakash: @BlaineEXE Updated the commit message. Thank you
travisn: @sudharsanomprakash Please [squash](https://rook.io/docs/rook/latest/Contributing/development-flow/#commit-history) to a single commit, thanks!

Patch:
diff --git a/.commitlintrc.json b/.commitlintrc.json
index 427dcd7ea..05b430a34 100644
--- a/.commitlintrc.json
+++ b/.commitlintrc.json
@@ -15,7 +15,6 @@
         "core",
         "csi",
         "docs",
-        "exporter",
         "external",
         "file",
         "helm",
diff --git a/Documentation/Helm-Charts/operator-chart.md b/Documentation/Helm-Charts/operator-chart.md
index 99f28c66f..70e909471 100644
--- a/Documentation/Helm-Charts/operator-chart.md
+++ b/Documentation/Helm-Charts/operator-chart.md
@@ -58,13 +58,13 @@ The following table lists the configurable parameters of the rook-operator chart
 | `csi.cephFSFSGroupPolicy` | Policy for modifying a volume's ownership or permissions when the CephFS PVC is being mounted. supported values are documented at https://kubernetes-csi.github.io/docs/support-fsgroup.html | `"File"` |
 | `csi.cephFSKernelMountOptions` | Set CephFS Kernel mount options to use https://docs.ceph.com/en/latest/man/8/mount.ceph/#options. Set to "ms_mode=secure" when connections.encrypted is enabled in CephCluster CR | `nil` |
 | `csi.cephFSPluginUpdateStrategy` | CSI CephFS plugin daemonset update strategy, supported values are OnDelete and RollingUpdate | `RollingUpdate` |
-| `csi.cephcsi.image` | Ceph CSI image | `quay.io/cephcsi/cephcsi:v3.9.0` |
+| `csi.cephcsi.image` | Ceph CSI image | `quay.io/cephcsi/cephcsi:v3.8.0` |
 | `csi.cephfsGrpcMetricsPort` | CSI CephFS driver GRPC metrics port | `9091` |
 | `csi.cephfsLivenessMetricsPort` | CSI CephFS driver metrics port | `9081` |
 | `csi.cephfsPodLabels` | Labels to add to the CSI CephFS Deployments and DaemonSets Pods | `nil` |
 | `csi.clusterName` | Cluster name identifier to set as metadata on the CephFS subvolume and RBD images. This will be useful in cases like for example, when two container orchestrator clusters (Kubernetes/OCP) are using a single ceph cluster | `nil` |
 | `csi.csiAddons.enabled` | Enable CSIAddons | `false` |
-| `csi.csiAddons.image` | CSIAddons Sidecar image | `"quay.io/csiaddons/k8s-sidecar:v0.7.0"` |
+| `csi.csiAddons.image` | CSIAddons Sidecar image | `"quay.io/csiaddons/k8s-sidecar:v0.5.0"` |
 | `csi.csiAddonsPort` | CSI Addons server port | `9070` |
 | `csi.csiCephFSPluginResource` | CEPH CSI CephFS plugin resource requirement list | see values.yaml |
 | `csi.csiCephFSPluginVolume` | The volume of the CephCSI CephFS plugin DaemonSet | `nil` |
diff --git a/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md b/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md
index 4bab0c1b8..c934a0720 100644
--- a/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md
+++ b/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md
@@ -123,9 +123,9 @@ The CSI-Addons Controller handles the requests from users to initiate an operati
 Users can deploy the controller by running the following commands:
 
 ```console
-kubectl create -f https://raw.githubusercontent.com/csi-addons/kubernetes-csi-addons/v0.7.0/deploy/controller/crds.yaml
-kubectl create -f https://raw.githubusercontent.com/csi-addons/kubernetes-csi-addons/v0.7.0/deploy/controller/rbac.yaml
-kubectl create -f https://raw.githubusercontent.com/csi-addons/kubernetes-csi-addons/v0.7.0/deploy/controller/setup-controller.yaml
+kubectl create -f https://raw.githubusercontent.com/csi-addons/kubernetes-csi-addons/v0.5.0/deploy/controller/crds.yaml
+kubectl create -f https://raw.githubusercontent.com/csi-addons/kubernetes-csi-addons/v0.5.0/deploy/controller/rbac.yaml
+kubectl create -f https://raw.githubusercontent.com/csi-addons/kubernetes-csi-addons/v0.5.0/deploy/controller/setup-controller.yaml
 ```
 
 This creates the required crds and configure permissions.
@@ -157,15 +157,14 @@ kubectl patch cm rook-ceph-operator-config -nrook-ceph -p $'data:\n "CSI_ENABLE_
 CSI-Addons supports the following operations:
 
 * Reclaim Space
-  * [Creating a ReclaimSpaceJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.7.0/docs/reclaimspace.md#reclaimspacejob)
-  * [Creating a ReclaimSpaceCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.7.0/docs/reclaimspace.md#reclaimspacecronjob)
-  * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.7.0/docs/reclaimspace.md#annotating-perstentvolumeclaims)
-  * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.7.0/docs/reclaimspace.md#annotating-namespace)
+  * [Creating a ReclaimSpaceJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.5.0/docs/reclaimspace.md#reclaimspacejob)
+  * [Creating a ReclaimSpaceCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.5.0/docs/reclaimspace.md#reclaimspacecronjob)
+  * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.5.0/docs/reclaimspace.md#annotating-perstentvolumeclaims)
 * Network Fencing
-  * [Creating a NetworkFence](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.7.0/docs/networkfence.md)
+  * [Creating a NetworkFence](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.5.0/docs/networkfence.md)
 * Volume Replication
-  * [Creating VolumeReplicationClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.7.0/docs/volumereplicationclass.md)
-  * [Creating VolumeReplication CR](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.7.0/docs/volumereplication.md)
+  * [Creating VolumeReplicationClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.5.0/docs/volumereplicationclass.md)
+  * [Creating VolumeReplication CR](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.5.0/docs/volumereplication.md)
 
 ## Enable RBD Encryption Support
 
diff --git a/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md b/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md
index 46eb31f54..22e1faa38 100644
--- a/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md
+++ b/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md
@@ -18,13 +18,13 @@ kubectl -n $ROOK_OPERATOR_NAMESPACE edit configmap rook-ceph-operator-config
 The default upstream images are included below, which you can change to your desired images.
 
 ```yaml
-ROOK_CSI_CEPH_IMAGE: "quay.io/cephcsi/cephcsi:v3.9.0"
+ROOK_CSI_CEPH_IMAGE: "quay.io/cephcsi/cephcsi:v3.8.0"
 ROOK_CSI_REGISTRAR_IMAGE: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.7.0"
 ROOK_CSI_PROVISIONER_IMAGE: "registry.k8s.io/sig-storage/csi-provisioner:v3.4.0"
 ROOK_CSI_ATTACHER_IMAGE: "registry.k8s.io/sig-storage/csi-attacher:v4.1.0"
 ROOK_CSI_RESIZER_IMAGE: "registry.k8s.io/sig-storage/csi-resizer:v1.7.0"
 ROOK_CSI_SNAPSHOTTER_IMAGE: "registry.k8s.io/sig-storage/csi-snapshotter:v6.2.1"
-ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.7.0"
+ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.5.0"
 ```
 
 ### **Use private repository**
@@ -32,7 +32,7 @@ ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.7.0"
 If image version is not passed along with the image name in any of the variables above,
 Rook will add the corresponding default version to that image.
 Example: if `ROOK_CSI_CEPH_IMAGE: "quay.io/private-repo/cephcsi"` is passed,
-Rook will add internal default version and consume it as `"quay.io/private-repo/cephcsi:v3.9.0"`.
+Rook will add internal default version and consume it as `"quay.io/private-repo/cephcsi:v3.8.0"`.
 
 ### **Use default images**
 
diff --git a/Documentation/Storage-Configuration/NFS/nfs-csi-driver.md b/Documentation/Storage-Configuration/NFS/nfs-csi-driver.md
index 22b2b21f9..88234da57 100644
--- a/Documentation/Storage-Configuration/NFS/nfs-csi-driver.md
+++ b/Documentation/Storage-Configuration/NFS/nfs-csi-driver.md
@@ -5,6 +5,9 @@ title: CSI provisioner and driver
 !!! attention
     This feature is experimental and will not support upgrades to future versions.
 
+In version 1.9.1, Rook is able to deploy the experimental NFS Ceph CSI driver. This requires Ceph
+CSI version 3.7.0 or above. We recommend Ceph v16.2.7 or above.
+
 For this section, we will refer to Rook's deployment examples in the
 [deploy/examples](https://github.com/rook/rook/tree/master/deploy/examples) directory.
 
diff --git a/Documentation/Upgrade/rook-upgrade.md b/Documentation/Upgrade/rook-upgrade.md
index 3e7b26e6c..f59fc2828 100644
--- a/Documentation/Upgrade/rook-upgrade.md
+++ b/Documentation/Upgrade/rook-upgrade.md
@@ -189,7 +189,7 @@ kubectl -n $ROOK_OPERATOR_NAMESPACE set image deploy/rook-ceph-operator rook-cep
     If have not customized the CSI image versions, this is automatically updated.
 
 !!! important
-    The minimum supported version of Ceph-CSI is v3.8.0.
+    The minimum supported version of Ceph-CSI is v3.7.0.
 
 If you have specified custom CSI images, we recommended you update to the latest Ceph-CSI drivers.
 See the [CSI Custom Images](../Storage-Configuration/Ceph-CSI/custom-images.md) documentation.
diff --git a/deploy/charts/rook-ceph/templates/role.yaml b/deploy/charts/rook-ceph/templates/role.yaml
index 4e1debf24..d128d630f 100644
--- a/deploy/charts/rook-ceph/templates/role.yaml
+++ b/deploy/charts/rook-ceph/templates/role.yaml
@@ -38,6 +38,7 @@ rules:
   - create
   - update
   - delete
+  - deletecollection
 - apiGroups:
   - batch
   resources:
diff --git a/deploy/charts/rook-ceph/values.yaml b/deploy/charts/rook-ceph/values.yaml
index 3d751c353..7b71ffeaa 100644
--- a/deploy/charts/rook-ceph/values.yaml
+++ b/deploy/charts/rook-ceph/values.yaml
@@ -470,7 +470,7 @@ csi:
 
   cephcsi:
     # -- Ceph CSI image
-    # @default -- `quay.io/cephcsi/cephcsi:v3.9.0`
+    # @default -- `quay.io/cephcsi/cephcsi:v3.8.0`
     image:
 
   registrar:
@@ -514,7 +514,7 @@ csi:
     # -- Enable CSIAddons
     enabled: false
     # -- CSIAddons Sidecar image
-    image: "quay.io/csiaddons/k8s-sidecar:v0.7.0"
+    image: "quay.io/csiaddons/k8s-sidecar:v0.5.0"
 
   nfs:
     # -- Enable the nfs csi driver
diff --git a/deploy/examples/common.yaml b/deploy/examples/common.yaml
index 6254dfc7b..742c8a49f 100644
--- a/deploy/examples/common.yaml
+++ b/deploy/examples/common.yaml
@@ -896,6 +896,7 @@ rules:
       - create
       - update
       - delete
+      - deletecollection
   - apiGroups:
       - batch
     resources:
diff --git a/deploy/examples/images.txt b/deploy/examples/images.txt
index 81266a2cc..ed7487651 100644
--- a/deploy/examples/images.txt
+++ b/deploy/examples/images.txt
@@ -1,6 +1,6 @@
  quay.io/ceph/ceph:v17.2.6
- quay.io/cephcsi/cephcsi:v3.9.0
- quay.io/csiaddons/k8s-sidecar:v0.7.0
+ quay.io/cephcsi/cephcsi:v3.8.0
+ quay.io/csiaddons/k8s-sidecar:v0.5.0
  registry.k8s.io/sig-storage/csi-attacher:v4.1.0
  registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.7.0
  registry.k8s.io/sig-storage/csi-provisioner:v3.4.0
diff --git a/deploy/examples/import-external-cluster.sh b/deploy/examples/import-external-cluster.sh
index b8e1be010..c988a50a6 100644
--- a/deploy/examples/import-external-cluster.sh
+++ b/deploy/examples/import-external-cluster.sh
@@ -76,124 +76,87 @@ function importClusterID() {
 }
 
 function importSecret() {
-  secret=$(kubectl -n "$NAMESPACE" get secret "$MON_SECRET_NAME")
-  if [ $? != 0 ]; then
-    kubectl -n "$NAMESPACE" \
-      create \
-      secret \
-      generic \
-      --type="kubernetes.io/rook" \
-      "$MON_SECRET_NAME" \
-      --from-literal="$MON_SECRET_CLUSTER_NAME_KEYNAME"="$ROOK_EXTERNAL_CLUSTER_NAME" \
-      --from-literal="$MON_SECRET_FSID_KEYNAME"="$ROOK_EXTERNAL_FSID" \
-      --from-literal="$MON_SECRET_ADMIN_KEYRING_KEYNAME"="$ROOK_EXTERNAL_ADMIN_SECRET" \
-      --from-literal="$MON_SECRET_MON_KEYRING_KEYNAME"="$ROOK_EXTERNAL_MONITOR_SECRET" \
-      --from-literal="$MON_SECRET_CEPH_USERNAME_KEYNAME"="$ROOK_EXTERNAL_USERNAME" \
-      --from-literal="$MON_SECRET_CEPH_SECRET_KEYNAME"="$ROOK_EXTERNAL_USER_SECRET"
-  else
-    echo "secret $secret already exists"
-  fi
+  kubectl -n "$NAMESPACE" \
+    create \
+    secret \
+    generic \
+    --type="kubernetes.io/rook" \
+    "$MON_SECRET_NAME" \
+    --from-literal="$MON_SECRET_CLUSTER_NAME_KEYNAME"="$ROOK_EXTERNAL_CLUSTER_NAME" \
+    --from-literal="$MON_SECRET_FSID_KEYNAME"="$ROOK_EXTERNAL_FSID" \
+    --from-literal="$MON_SECRET_ADMIN_KEYRING_KEYNAME"="$ROOK_EXTERNAL_ADMIN_SECRET" \
+    --from-literal="$MON_SECRET_MON_KEYRING_KEYNAME"="$ROOK_EXTERNAL_MONITOR_SECRET" \
+    --from-literal="$MON_SECRET_CEPH_USERNAME_KEYNAME"="$ROOK_EXTERNAL_USERNAME" \
+    --from-literal="$MON_SECRET_CEPH_SECRET_KEYNAME"="$ROOK_EXTERNAL_USER_SECRET"
 }
 
 function importConfigMap() {
-  configmap=$(kubectl -n "$NAMESPACE" get configmap "$MON_ENDPOINT_CONFIGMAP_NAME")
-  if [ $? != 0 ]; then
-    kubectl -n "$NAMESPACE" \
-      create \
-      configmap \
-      "$MON_ENDPOINT_CONFIGMAP_NAME" \
-      --from-literal=data="$ROOK_EXTERNAL_CEPH_MON_DATA" \
-      --from-literal=mapping="$ROOK_EXTERNAL_MAPPING" \
-      --from-literal=maxMonId="$ROOK_EXTERNAL_MAX_MON_ID"
-  else
-    echo "configmap $configmap already exists"
-  fi
+  kubectl -n "$NAMESPACE" \
+    create \
+    configmap \
+    "$MON_ENDPOINT_CONFIGMAP_NAME" \
+    --from-literal=data="$ROOK_EXTERNAL_CEPH_MON_DATA" \
+    --from-literal=mapping="$ROOK_EXTERNAL_MAPPING" \
+    --from-literal=maxMonId="$ROOK_EXTERNAL_MAX_MON_ID"
 }
 
 function importCsiRBDNodeSecret() {
-  secret=$(kubectl -n "$NAMESPACE" get secret "rook-""$CSI_RBD_NODE_SECRET_NAME")
-  if [ $? != 0 ]; then
-    kubectl -n "$NAMESPACE" \
-      create \
-      secret \
-      generic \
-      --type="kubernetes.io/rook" \
-      "rook-""$CSI_RBD_NODE_SECRET_NAME" \
-      --from-literal=userID="$CSI_RBD_NODE_SECRET_NAME" \
-      --from-literal=userKey="$CSI_RBD_NODE_SECRET"
-  else
-    echo "secret $secret already exists"
-  fi
+  kubectl -n "$NAMESPACE" \
+    create \
+    secret \
+    generic \
+    --type="kubernetes.io/rook" \
+    "rook-""$CSI_RBD_NODE_SECRET_NAME" \
+    --from-literal=userID="$CSI_RBD_NODE_SECRET_NAME" \
+    --from-literal=userKey="$CSI_RBD_NODE_SECRET"
 }
 
 function importCsiRBDProvisionerSecret() {
-  secret=$(kubectl -n "$NAMESPACE" get secret "rook-""$CSI_RBD_PROVISIONER_SECRET_NAME")
-  if [ $? != 0 ]; then
-    kubectl -n "$NAMESPACE" \
-      create \
-      secret \
-      generic \
-      --type="kubernetes.io/rook" \
-      "rook-""$CSI_RBD_PROVISIONER_SECRET_NAME" \
-      --from-literal=userID="$CSI_RBD_PROVISIONER_SECRET_NAME" \
-      --from-literal=userKey="$CSI_RBD_PROVISIONER_SECRET"
-  else
-    echo "secret $secret already exists"
-  fi
+  kubectl -n "$NAMESPACE" \
+    create \
+    secret \
+    generic \
+    --type="kubernetes.io/rook" \
+    "rook-""$CSI_RBD_PROVISIONER_SECRET_NAME" \
+    --from-literal=userID="$CSI_RBD_PROVISIONER_SECRET_NAME" \
+    --from-literal=userKey="$CSI_RBD_PROVISIONER_SECRET"
 }
 
 function importCsiCephFSNodeSecret() {
-  secret=$(kubectl -n "$NAMESPACE" get secret "rook-""$CSI_CEPHFS_NODE_SECRET_NAME")
-  if [ $? != 0 ]; then
-    kubectl -n "$NAMESPACE" \
-      create \
-      secret \
-      generic \
-      --type="kubernetes.io/rook" \
-      "rook-""$CSI_CEPHFS_NODE_SECRET_NAME" \
-      --from-literal=adminID="$CSI_CEPHFS_NODE_SECRET_NAME" \
-      --from-literal=adminKey="$CSI_CEPHFS_NODE_SECRET"
-  else
-    echo "secret $secret already exists"
-  fi
+  kubectl -n "$NAMESPACE" \
+    create \
+    secret \
+    generic \
+    --type="kubernetes.io/rook" \
+    "rook-""$CSI_CEPHFS_NODE_SECRET_NAME" \
+    --from-literal=adminID="$CSI_CEPHFS_NODE_SECRET_NAME" \
+    --from-literal=adminKey="$CSI_CEPHFS_NODE_SECRET"
 }
 
 function importCsiCephFSProvisionerSecret() {
-  secret=$(kubectl -n "$NAMESPACE" get secret "rook-""$CSI_CEPHFS_PROVISIONER_SECRET_NAME")
-  if [ $? != 0 ]; then
-    kubectl -n "$NAMESPACE" \
-      create \
-      secret \
-      generic \
-      --type="kubernetes.io/rook" \
-      "rook-""$CSI_CEPHFS_PROVISIONER_SECRET_NAME" \
-      --from-literal=adminID="$CSI_CEPHFS_PROVISIONER_SECRET_NAME" \
-      --from-literal=adminKey="$CSI_CEPHFS_PROVISIONER_SECRET"
-  else
-    echo "secret $secret already exists"
-  fi
+  kubectl -n "$NAMESPACE" \
+    create \
+    secret \
+    generic \
+    --type="kubernetes.io/rook" \
+    "rook-""$CSI_CEPHFS_PROVISIONER_SECRET_NAME" \
+    --from-literal=adminID="$CSI_CEPHFS_PROVISIONER_SECRET_NAME" \
+    --from-literal=adminKey="$CSI_CEPHFS_PROVISIONER_SECRET"
 }
 
 function importRGWAdminOpsUser() {
-  secret=$(kubectl -n "$NAMESPACE" get secret "$RGW_ADMIN_OPS_USER_SECRET_NAME")
-  if [ $? != 0 ]; then
-    kubectl -n "$NAMESPACE" \
-      create \
-      secret \
-      generic \
-      --type="kubernetes.io/rook" \
-      "$RGW_ADMIN_OPS_USER_SECRET_NAME" \
-      --from-literal=accessKey="$RGW_ADMIN_OPS_USER_ACCESS_KEY" \
-      --from-literal=secretKey="$RGW_ADMIN_OPS_USER_SECRET_KEY"
-  else
-    echo "secret $secret already exists"
-  fi
+  kubectl -n "$NAMESPACE" \
+    create \
+    secret \
+    generic \
+    --type="kubernetes.io/rook" \
+    "$RGW_ADMIN_OPS_USER_SECRET_NAME" \
+    --from-literal=accessKey="$RGW_ADMIN_OPS_USER_ACCESS_KEY" \
+    --from-literal=secretKey="$RGW_ADMIN_OPS_USER_SECRET_KEY"
 }
 
 function createECRBDStorageClass() {
-  storageclass=$(kubectl -n "$NAMESPACE" get storageclass $RBD_STORAGE_CLASS_NAME)
-  if [ $? != 0 ]; then
-    cat <<eof | kubectl create -f -
+  cat <<eof | kubectl create -f -
 apiVersion: storage.k8s.io/v1
 kind: StorageClass
 metadata:
@@ -215,15 +178,10 @@ parameters:
 allowVolumeExpansion: true
 reclaimPolicy: Delete
 eof
-  else
-    echo "storageclass $storageclass already exists"
-  fi
 }
 
 function createRBDStorageClass() {
-  storageclass=$(kubectl -n "$NAMESPACE" get storageclass $RBD_STORAGE_CLASS_NAME)
-  if [ $? != 0 ]; then
-    cat <<eof | kubectl create -f -
+  cat <<eof | kubectl create -f -
 apiVersion: storage.k8s.io/v1
 kind: StorageClass
 metadata:
@@ -244,15 +202,10 @@ parameters:
 allowVolumeExpansion: true
 reclaimPolicy: Delete
 eof
-  else
-    echo "storageclass $storageclass already exists"
-  fi
 }
 
 function createCephFSStorageClass() {
-  storageclass=$(kubectl -n "$NAMESPACE" get storageclass $CEPHFS_STORAGE_CLASS_NAME)
-  if [ $? != 0 ]; then
-    cat <<eof | kubectl create -f -
+  cat <<eof | kubectl create -f -
 apiVersion: storage.k8s.io/v1
 kind: StorageClass
 metadata:
@@ -271,9 +224,6 @@ parameters:
 allowVolumeExpansion: true
 reclaimPolicy: Delete
 eof
-  else
-    echo "storageclass $storageclass already exists"
-  fi
 }
 
 ########
diff --git a/deploy/examples/operator-openshift.yaml b/deploy/examples/operator-openshift.yaml
index d310d4b6e..e3af8bffc 100644
--- a/deploy/examples/operator-openshift.yaml
+++ b/deploy/examples/operator-openshift.yaml
@@ -190,7 +190,7 @@ data:
   # The default version of CSI supported by Rook will be started. To change the version
   # of the CSI driver to something other than what is officially supported, change
   # these images to the desired release of the CSI driver.
-  # ROOK_CSI_CEPH_IMAGE: "quay.io/cephcsi/cephcsi:v3.9.0"
+  # ROOK_CSI_CEPH_IMAGE: "quay.io/cephcsi/cephcsi:v3.8.0"
   # ROOK_CSI_REGISTRAR_IMAGE: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.7.0"
   # ROOK_CSI_RESIZER_IMAGE: "registry.k8s.io/sig-storage/csi-resizer:v1.7.0"
   # ROOK_CSI_PROVISIONER_IMAGE: "registry.k8s.io/sig-storage/csi-provisioner:v3.4.0"
diff --git a/deploy/examples/operator.yaml b/deploy/examples/operator.yaml
index 16e01eec9..2b38033d5 100644
--- a/deploy/examples/operator.yaml
+++ b/deploy/examples/operator.yaml
@@ -107,7 +107,7 @@ data:
   # The default version of CSI supported by Rook will be started. To change the version
   # of the CSI driver to something other than what is officially supported, change
   # these images to the desired release of the CSI driver.
-  # ROOK_CSI_CEPH_IMAGE: "quay.io/cephcsi/cephcsi:v3.9.0"
+  # ROOK_CSI_CEPH_IMAGE: "quay.io/cephcsi/cephcsi:v3.8.0"
   # ROOK_CSI_REGISTRAR_IMAGE: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.7.0"
   # ROOK_CSI_RESIZER_IMAGE: "registry.k8s.io/sig-storage/csi-resizer:v1.7.0"
   # ROOK_CSI_PROVISIONER_IMAGE: "registry.k8s.io/sig-storage/csi-provisioner:v3.4.0"
@@ -497,7 +497,7 @@ data:
   ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS: "15"
   # Enable the csi addons sidecar.
   CSI_ENABLE_CSIADDONS: "false"
-  # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.7.0"
+  # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.5.0"
   # The CSI GRPC timeout value (in seconds). It should be >= 120. If this variable is not set or is an invalid value, it's default to 150.
   CSI_GRPC_TIMEOUT_SECONDS: "150"
 
diff --git a/pkg/operator/ceph/cluster/mgr/mgr.go b/pkg/operator/ceph/cluster/mgr/mgr.go
index 1af927658..5cd51151a 100644
--- a/pkg/operator/ceph/cluster/mgr/mgr.go
+++ b/pkg/operator/ceph/cluster/mgr/mgr.go
@@ -515,7 +515,7 @@ func (c *Cluster) EnableServiceMonitor() error {
 
 	applyMonitoringLabels(c, serviceMonitor)
 
-	if _, err = k8sutil.CreateOrUpdateServiceMonitor(c.context, c.clusterInfo.Context, serviceMonitor); err != nil {
+	if _, err = k8sutil.CreateOrUpdateServiceMonitor(c.clusterInfo.Context, serviceMonitor); err != nil {
 		return errors.Wrap(err, "service monitor could not be enabled")
 	}
 	return nil
diff --git a/pkg/operator/ceph/cluster/nodedaemon/exporter.go b/pkg/operator/ceph/cluster/nodedaemon/exporter.go
index e8d8573db..2e289535b 100644
--- a/pkg/operator/ceph/cluster/nodedaemon/exporter.go
+++ b/pkg/operator/ceph/cluster/nodedaemon/exporter.go
@@ -24,7 +24,6 @@ import (
 	"github.com/pkg/errors"
 	monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
 	cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
-	"github.com/rook/rook/pkg/clusterd"
 	"github.com/rook/rook/pkg/operator/ceph/config"
 	"github.com/rook/rook/pkg/operator/ceph/config/keyring"
 	"github.com/rook/rook/pkg/operator/ceph/controller"
@@ -220,7 +219,7 @@ func MakeCephExporterMetricsService(cephCluster cephv1.CephCluster, servicePortM
 }
 
 // EnableCephExporterServiceMonitor add a servicemonitor that allows prometheus to scrape from the monitoring endpoint of the exporter
-func EnableCephExporterServiceMonitor(context *clusterd.Context, cephCluster cephv1.CephCluster, scheme *runtime.Scheme, opManagerContext context.Context) error {
+func EnableCephExporterServiceMonitor(cephCluster cephv1.CephCluster, scheme *runtime.Scheme, opManagerContext context.Context) error {
 	serviceMonitor := k8sutil.GetServiceMonitor(cephExporterAppName, cephCluster.Namespace)
 	cephv1.GetCephExporterLabels(cephCluster.Spec.Labels).OverwriteApplyToObjectMeta(&serviceMonitor.ObjectMeta)
 
@@ -231,7 +230,7 @@ func EnableCephExporterServiceMonitor(context *clusterd.Context, cephCluster cep
 	serviceMonitor.Spec.Selector.MatchLabels = controller.AppLabels(cephExporterAppName, cephCluster.Namespace)
 	applyCephExporterLabels(cephCluster, serviceMonitor)
 
-	if _, err = k8sutil.CreateOrUpdateServiceMonitor(context, opManagerContext, serviceMonitor); err != nil {
+	if _, err = k8sutil.CreateOrUpdateServiceMonitor(opManagerContext, serviceMonitor); err != nil {
 		return errors.Wrap(err, "service monitor could not be enabled")
 	}
 	return nil
diff --git a/pkg/operator/ceph/cluster/nodedaemon/reconcile.go b/pkg/operator/ceph/cluster/nodedaemon/reconcile.go
index d9c30c9a0..7a2ff3a26 100644
--- a/pkg/operator/ceph/cluster/nodedaemon/reconcile.go
+++ b/pkg/operator/ceph/cluster/nodedaemon/reconcile.go
@@ -86,9 +86,9 @@ func (r *ReconcileNode) Reconcile(context context.Context, request reconcile.Req
 }
 
 func (r *ReconcileNode) cleanupExporterResources(clusterNamespace string, ns string, nodeName string) (reconcile.Result, error) {
-	err := k8sutil.DeleteServiceMonitor(r.context, r.opManagerContext, ns, cephExporterAppName)
+	err := k8sutil.DeleteServiceMonitor(r.opManagerContext, ns, cephExporterAppName)
 	if err != nil {
-		logger.Debugf("failed to delete service monitor for ceph exporter in namespace %q on node %q. %v", ns, nodeName, err)
+		logger.Debugf("failed to delete service monitor for ceph exporter in namespace %q on node %q", ns, nodeName)
 	}
 	err = k8sutil.DeleteService(r.opManagerContext, r.context.Clientset, r.opConfig.OperatorNamespace, cephExporterAppName)
 	if err != nil {
@@ -271,7 +271,7 @@ func (r *ReconcileNode) createOrUpdateNodeDaemons(node corev1.Node, tolerations
 				}
 
 				if cephCluster.Spec.Monitoring.Enabled {
-					if err := EnableCephExporterServiceMonitor(r.context, cephCluster, r.scheme, r.opManagerContext); err != nil {
+					if err := EnableCephExporterServiceMonitor(cephCluster, r.scheme, r.opManagerContext); err != nil {
 						return errors.Wrap(err, "failed to enable service monitor")
 					}
 					logger.Debug("service monitor for ceph exporter was enabled successfully")
diff --git a/pkg/operator/ceph/csi/betav1csidriver.go b/pkg/operator/ceph/csi/betav1csidriver.go
index e7304cce8..8ffd38539 100644
--- a/pkg/operator/ceph/csi/betav1csidriver.go
+++ b/pkg/operator/ceph/csi/betav1csidriver.go
@@ -39,11 +39,7 @@ type beta1CsiDriver struct {
 }
 
 // createCSIDriverInfo Registers CSI driver by creating a CSIDriver object
-func (d beta1CsiDriver) createCSIDriverInfo(
-	ctx context.Context,
-	clientset kubernetes.Interface,
-	name, fsGroupPolicy string,
-	attachRequired, seLinuxMountRequired bool) error {
+func (d beta1CsiDriver) createCSIDriverInfo(ctx context.Context, clientset kubernetes.Interface, name, fsGroupPolicy string, attachRequired bool) error {
 	mountInfo := false
 	// Create CSIDriver object
 	csiDriver := &betav1k8scsi.CSIDriver{
diff --git a/pkg/operator/ceph/csi/csi.go b/pkg/operator/ceph/csi/csi.go
index 51d9ac8a1..0ced8b3f4 100644
--- a/pkg/operator/ceph/csi/csi.go
+++ b/pkg/operator/ceph/csi/csi.go
@@ -157,15 +157,10 @@ func (r *ReconcileCSI) setParams(ver *version.Info) error {
 
 	// SA token projection is stable only from kubernetes version 1.20.
 	CSIParam.EnableOIDCTokenProjection = false
-	if ver.Major == kubeMinMajor && ver.Minor >= kubeMinVerForOIDCTokenProjection {
+	if ver.Major == KubeMinMajor && ver.Minor >= KubeMinVerForOIDCTokenProjection {
 		CSIParam.EnableOIDCTokenProjection = true
 	}
 
-	// CSIDriver SeLinuxMount option is only available from kubernetes version 1.25.
-	if ver.Major == kubeMinMajor && ver.Minor >= kubeMinVerForCSIDriverSeLinuxMount {
-		CSIParam.EnableCSIDriverSeLinuxMount = true
-	}
-
 	CSIParam.EnableRBDSnapshotter = true
 	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_RBD_SNAPSHOTTER", "true"), "false") {
 		CSIParam.EnableRBDSnapshotter = false
diff --git a/pkg/operator/ceph/csi/csidriver.go b/pkg/operator/ceph/csi/csidriver.go
index 1a11d1767..1159fd098 100644
--- a/pkg/operator/ceph/csi/csidriver.go
+++ b/pkg/operator/ceph/csi/csidriver.go
@@ -28,7 +28,7 @@ import (
 )
 
 type csiDriver interface {
-	createCSIDriverInfo(ctx context.Context, clientset kubernetes.Interface, name, fsGroupPolicy string, attachRequired, seLinuxMountRequired bool) error
+	createCSIDriverInfo(ctx context.Context, clientset kubernetes.Interface, name, fsGroupPolicy string, attachRequired bool) error
 	reCreateCSIDriverInfo(ctx context.Context) error
 	deleteCSIDriverInfo(ctx context.Context, clientset kubernetes.Interface, name string) error
 }
@@ -39,11 +39,7 @@ type v1CsiDriver struct {
 }
 
 // createCSIDriverInfo Registers CSI driver by creating a CSIDriver object
-func (d v1CsiDriver) createCSIDriverInfo(
-	ctx context.Context,
-	clientset kubernetes.Interface,
-	name, fsGroupPolicy string,
-	attachRequired, seLinuxMountRequired bool) error {
+func (d v1CsiDriver) createCSIDriverInfo(ctx context.Context, clientset kubernetes.Interface, name, fsGroupPolicy string, attachRequired bool) error {
 	mountInfo := false
 	// Create CSIDriver object
 	csiDriver := &v1k8scsi.CSIDriver{
@@ -55,10 +51,6 @@ func (d v1CsiDriver) createCSIDriverInfo(
 			PodInfoOnMount: &mountInfo,
 		},
 	}
-	if seLinuxMountRequired {
-		selinuxMount := true
-		csiDriver.Spec.SELinuxMount = &selinuxMount
-	}
 	if fsGroupPolicy != "" {
 		policy := v1k8scsi.FSGroupPolicy(fsGroupPolicy)
 		csiDriver.Spec.FSGroupPolicy = &policy
diff --git a/pkg/operator/ceph/csi/spec.go b/pkg/operator/ceph/csi/spec.go
index 8bc483f98..1886373fb 100644
--- a/pkg/operator/ceph/csi/spec.go
+++ b/pkg/operator/ceph/csi/spec.go
@@ -74,7 +74,6 @@ type Param struct {
 	EnableCSIAddonsSideCar                bool
 	MountCustomCephConf                   bool
 	EnableOIDCTokenProjection             bool
-	EnableCSIDriverSeLinuxMount           bool
 	EnableCSIEncryption                   bool
 	EnableCSITopology                     bool
 	EnableLiveness                        bool
@@ -138,13 +137,13 @@ var (
 // manually challenging.
 var (
 	// image names
-	DefaultCSIPluginImage   = "quay.io/cephcsi/cephcsi:v3.9.0"
+	DefaultCSIPluginImage   = "quay.io/cephcsi/cephcsi:v3.8.0"
 	DefaultRegistrarImage   = "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.7.0"
 	DefaultProvisionerImage = "registry.k8s.io/sig-storage/csi-provisioner:v3.4.0"
 	DefaultAttacherImage    = "registry.k8s.io/sig-storage/csi-attacher:v4.1.0"
 	DefaultSnapshotterImage = "registry.k8s.io/sig-storage/csi-snapshotter:v6.2.1"
 	DefaultResizerImage     = "registry.k8s.io/sig-storage/csi-resizer:v1.7.0"
-	DefaultCSIAddonsImage   = "quay.io/csiaddons/k8s-sidecar:v0.7.0"
+	DefaultCSIAddonsImage   = "quay.io/csiaddons/k8s-sidecar:v0.5.0"
 
 	// image pull policy
 	DefaultCSIImagePullPolicy = string(v1.PullIfNotPresent)
@@ -179,10 +178,9 @@ var (
 )
 
 const (
-	kubeMinMajor                       = "1"
-	kubeMinVerForOIDCTokenProjection   = "20"
-	kubeMaxVerForBeta1csiDriver        = "21"
-	kubeMinVerForCSIDriverSeLinuxMount = "25"
+	KubeMinMajor                     = "1"
+	KubeMinVerForOIDCTokenProjection = "20"
+	kubeMaxVerForBeta1csiDriver      = "21"
 
 	// common tolerations and node affinity
 	provisionerTolerationsEnv  = "CSI_PROVISIONER_TOLERATIONS"
@@ -311,7 +309,9 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 	RBDDriverName = tp.DriverNamePrefix + rbdDriverSuffix
 	NFSDriverName = tp.DriverNamePrefix + "nfs.csi.ceph.com"
 
-	tp.Param.MountCustomCephConf = CustomCSICephConfigExists
+	if CustomCSICephConfigExists {
+		tp.Param.MountCustomCephConf = v.SupportsCustomCephConf()
+	}
 
 	csiDriverobj = v1CsiDriver{}
 	// In case of an k8s version upgrade, delete the beta CSIDriver object;
@@ -424,6 +424,10 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 	pluginTolerations := getToleration(r.opConfig.Parameters, pluginTolerationsEnv, []corev1.Toleration{})
 	pluginNodeAffinity := getNodeAffinity(r.opConfig.Parameters, pluginNodeAffinityEnv, &corev1.NodeAffinity{})
 
+	if holderEnabled && !v.SupportsNsenter() {
+		return errors.Errorf("multus/csi pod networking is applied but the csi version %q does not support it, need at least %q", v.String(), nsenterSupportedVersion.String())
+	}
+
 	// Deploy the CSI Holder DaemonSet if Multus is enabled or
 	// EnableCSIHostNetwork is disabled.
 	err = r.configureHolders(enabledDrivers, tp, pluginTolerations, pluginNodeAffinity)
@@ -643,27 +647,19 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 	}
 
 	if EnableRBD {
-		err = csiDriverobj.createCSIDriverInfo(
-			r.opManagerContext, r.context.Clientset,
-			RBDDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_RBD_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
-			tp.Param.RBDAttachRequired, CSIParam.EnableCSIDriverSeLinuxMount)
+		err = csiDriverobj.createCSIDriverInfo(r.opManagerContext, r.context.Clientset, RBDDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_RBD_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)), tp.Param.RBDAttachRequired)
 		if err != nil {
 			return errors.Wrapf(err, "failed to create CSI driver object for %q", RBDDriverName)
 		}
 	}
 	if EnableCephFS {
-		err = csiDriverobj.createCSIDriverInfo(
-			r.opManagerContext, r.context.Clientset,
-			CephFSDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
-			tp.Param.CephFSAttachRequired, CSIParam.EnableCSIDriverSeLinuxMount)
+		err = csiDriverobj.createCSIDriverInfo(r.opManagerContext, r.context.Clientset, CephFSDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)), tp.Param.CephFSAttachRequired)
 		if err != nil {
 			return errors.Wrapf(err, "failed to create CSI driver object for %q", CephFSDriverName)
 		}
 	}
 	if EnableNFS {
-		err = csiDriverobj.createCSIDriverInfo(r.opManagerContext, r.context.Clientset,
-			NFSDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_NFS_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
-			tp.Param.NFSAttachRequired, CSIParam.EnableCSIDriverSeLinuxMount)
+		err = csiDriverobj.createCSIDriverInfo(r.opManagerContext, r.context.Clientset, NFSDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_NFS_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)), tp.Param.NFSAttachRequired)
 		if err != nil {
 			return errors.Wrapf(err, "failed to create CSI driver object for %q", NFSDriverName)
 		}
diff --git a/pkg/operator/ceph/csi/version.go b/pkg/operator/ceph/csi/version.go
index 3153b202a..fc44e9325 100644
--- a/pkg/operator/ceph/csi/version.go
+++ b/pkg/operator/ceph/csi/version.go
@@ -25,16 +25,22 @@ import (
 )
 
 var (
-	//minimum supported version is 3.8.0
-	minimum = CephCSIVersion{3, 8, 0}
+	//minimum supported version is 3.7.0
+	minimum = CephCSIVersion{3, 7, 0}
 	//supportedCSIVersions are versions that rook supports
-	releasev390 = CephCSIVersion{3, 9, 0}
+	releasev380 = CephCSIVersion{3, 8, 0}
 
 	supportedCSIVersions = []CephCSIVersion{
 		minimum,
-		releasev390,
+		releasev380,
 	}
 
+	// custom ceph.conf is supported in v3.5.0+
+	cephConfSupportedVersion = CephCSIVersion{3, 5, 0}
+
+	// pod networking fix with the extra holder pod is supported with at least v3.6.1
+	nsenterSupportedVersion = CephCSIVersion{3, 6, 1}
+
 	// for parsing the output of `cephcsi`
 	versionCSIPattern = regexp.MustCompile(`v(\d+)\.(\d+)\.(\d+)`)
 )
@@ -112,3 +118,24 @@ func extractCephCSIVersion(src string) (*CephCSIVersion, error) {
 
 	return &CephCSIVersion{major, minor, bugfix}, nil
 }
+
+// SupportsCustomCephConf checks if the detected version supports custom ceph.conf
+func (v *CephCSIVersion) SupportsCustomCephConf() bool {
+	// if AllowUnsupported is set also a csi-image greater than the supported ones are allowed
+	if AllowUnsupported {
+		return true
+	}
+
+	return v.isAtLeast(&cephConfSupportedVersion)
+}
+
+// SupportsNsenter checks if the csi image has support for calling "nsenter" while executing
+// mount/map commands. This is needed for Multus scenarios.
+func (v *CephCSIVersion) SupportsNsenter() bool {
+	// if AllowUnsupported is set also a csi-image greater than the supported ones are allowed
+	if AllowUnsupported {
+		return true
+	}
+
+	return v.isAtLeast(&nsenterSupportedVersion)
+}
diff --git a/pkg/operator/k8sutil/prometheus.go b/pkg/operator/k8sutil/prometheus.go
index fe9bd664e..ae745b287 100644
--- a/pkg/operator/k8sutil/prometheus.go
+++ b/pkg/operator/k8sutil/prometheus.go
@@ -21,17 +21,20 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/pkg/errors"
 	monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
 	monitoringclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
-	"github.com/rook/rook/pkg/clusterd"
 	kerror "k8s.io/apimachinery/pkg/api/errors"
 	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/tools/clientcmd"
 )
 
-func getMonitoringClient(context *clusterd.Context) (*monitoringclient.Clientset, error) {
-	client, err := monitoringclient.NewForConfig(context.KubeConfig)
+func getMonitoringClient() (*monitoringclient.Clientset, error) {
+	cfg, err := clientcmd.BuildConfigFromFlags("", "")
+	if err != nil {
+		return nil, fmt.Errorf("failed to build config. %v", err)
+	}
+	client, err := monitoringclient.NewForConfig(cfg)
 	if err != nil {
 		return nil, fmt.Errorf("failed to get monitoring client. %v", err)
 	}
@@ -72,11 +75,11 @@ func GetServiceMonitor(name string, namespace string) *monitoringv1.ServiceMonit
 }
 
 // CreateOrUpdateServiceMonitor creates serviceMonitor object or an error
-func CreateOrUpdateServiceMonitor(context *clusterd.Context, ctx context.Context, serviceMonitorDefinition *monitoringv1.ServiceMonitor) (*monitoringv1.ServiceMonitor, error) {
+func CreateOrUpdateServiceMonitor(ctx context.Context, serviceMonitorDefinition *monitoringv1.ServiceMonitor) (*monitoringv1.ServiceMonitor, error) {
 	name := serviceMonitorDefinition.GetName()
 	namespace := serviceMonitorDefinition.GetNamespace()
 	logger.Debugf("creating servicemonitor %s", name)
-	client, err := getMonitoringClient(context)
+	client, err := getMonitoringClient()
 	if err != nil {
 		return nil, fmt.Errorf("failed to get monitoring client. %v", err)
 	}
@@ -101,23 +104,16 @@ func CreateOrUpdateServiceMonitor(context *clusterd.Context, ctx context.Context
 }
 
 // DeleteServiceMonitor deletes a ServiceMonitor and returns the error if any
-func DeleteServiceMonitor(context *clusterd.Context, ctx context.Context, ns string, name string) error {
-	client, err := getMonitoringClient(context)
+func DeleteServiceMonitor(ctx context.Context, ns string, name string) error {
+	client, err := getMonitoringClient()
 	if err != nil {
 		return fmt.Errorf("failed to get monitoring client. %v", err)
 	}
-	_, err = client.MonitoringV1().ServiceMonitors(ns).Get(ctx, name, metav1.GetOptions{})
-	if err != nil {
-		// Either the service monitor does not exist or there are no privileges to detect it
-		// so we ignore any errors
-		return nil
-	}
 	err = client.MonitoringV1().ServiceMonitors(ns).Delete(ctx, name, metav1.DeleteOptions{})
 	if err != nil {
 		if kerror.IsNotFound(err) {
 			return nil
 		}
-		return errors.Wrapf(err, "failed to delete service monitor %q", name)
 	}
-	return nil
+	return err
 }


Test patch:
diff --git a/pkg/operator/ceph/csi/util_test.go b/pkg/operator/ceph/csi/util_test.go
index 6f87c01ff..20eba9359 100644
--- a/pkg/operator/ceph/csi/util_test.go
+++ b/pkg/operator/ceph/csi/util_test.go
@@ -268,7 +268,7 @@ func Test_getImage(t *testing.T) {
 			args: args{
 				data:         map[string]string{},
 				settingName:  "ROOK_CSI_CEPH_IMAGE",
-				defaultImage: "quay.io/cephcsi/cephcsi:v3.9.0",
+				defaultImage: "quay.io/cephcsi/cephcsi:v3.8.0",
 			},
 			want: DefaultCSIPluginImage,
 		},
@@ -279,7 +279,7 @@ func Test_getImage(t *testing.T) {
 					"ROOK_CSI_CEPH_IMAGE": "registry.io/private/cephcsi:v8",
 				},
 				settingName:  "ROOK_CSI_CEPH_IMAGE",
-				defaultImage: "quay.io/cephcsi/cephcsi:v3.9.0",
+				defaultImage: "quay.io/cephcsi/cephcsi:v3.8.0",
 			},
 			want: "registry.io/private/cephcsi:v8",
 		},
@@ -290,9 +290,9 @@ func Test_getImage(t *testing.T) {
 					"ROOK_CSI_CEPH_IMAGE": "registry.io/private/cephcsi",
 				},
 				settingName:  "ROOK_CSI_CEPH_IMAGE",
-				defaultImage: "quay.io/cephcsi/cephcsi:v3.9.0",
+				defaultImage: "quay.io/cephcsi/cephcsi:v3.8.0",
 			},
-			want: "registry.io/private/cephcsi:v3.9.0",
+			want: "registry.io/private/cephcsi:v3.8.0",
 		},
 	}
 	for _, tt := range tests {
diff --git a/pkg/operator/ceph/csi/version_test.go b/pkg/operator/ceph/csi/version_test.go
index bd38c93f4..a5d0db134 100644
--- a/pkg/operator/ceph/csi/version_test.go
+++ b/pkg/operator/ceph/csi/version_test.go
@@ -23,13 +23,14 @@ import (
 )
 
 var (
-	testMinVersion  = CephCSIVersion{3, 8, 0}
+	testMinVersion  = CephCSIVersion{3, 7, 0}
+	testReleaseV350 = CephCSIVersion{3, 5, 0}
+	testReleaseV360 = CephCSIVersion{3, 6, 0}
+	testReleaseV361 = CephCSIVersion{3, 6, 1}
 	testReleaseV370 = CephCSIVersion{3, 7, 0}
 	testReleaseV371 = CephCSIVersion{3, 7, 1}
 	testReleaseV380 = CephCSIVersion{3, 8, 0}
 	testReleaseV381 = CephCSIVersion{3, 8, 1}
-	testReleaseV390 = CephCSIVersion{3, 9, 0}
-	testReleaseV391 = CephCSIVersion{3, 9, 1}
 
 	testVersionUnsupported = CephCSIVersion{4, 0, 0}
 )
@@ -44,22 +45,25 @@ func TestIsAtLeast(t *testing.T) {
 	ret = testMinVersion.isAtLeast(&testMinVersion)
 	assert.Equal(t, true, ret)
 
+	// Test for 3.6.0
+	ret = testReleaseV360.isAtLeast(&testReleaseV360)
+	assert.Equal(t, true, ret)
+
 	// Test for 3.7.0
-	ret = testReleaseV370.isAtLeast(&testMinVersion)
-	assert.Equal(t, false, ret)
+	ret = testReleaseV370.isAtLeast(&testReleaseV360)
+	assert.Equal(t, true, ret)
 
 	// Test for 3.7.1
-	ret = testReleaseV371.isAtLeast(&testMinVersion)
-	assert.Equal(t, false, ret)
-
-	// Test for 3.9.0
-	ret = testReleaseV390.isAtLeast(&testReleaseV380)
+	ret = testReleaseV371.isAtLeast(&testReleaseV360)
 	assert.Equal(t, true, ret)
 
-	// Test for 3.9.1
-	ret = testReleaseV391.isAtLeast(&testReleaseV381)
+	// Test for 3.8.0
+	ret = testReleaseV380.isAtLeast(&testReleaseV370)
 	assert.Equal(t, true, ret)
 
+	// Test for 3.8.1
+	ret = testReleaseV381.isAtLeast(&testReleaseV371)
+	assert.Equal(t, true, ret)
 }
 
 func TestSupported(t *testing.T) {
@@ -70,23 +74,20 @@ func TestSupported(t *testing.T) {
 	ret = testVersionUnsupported.Supported()
 	assert.Equal(t, false, ret)
 
-	// 3.7.x is not supported after 3.9.0 release
-	ret = testReleaseV370.Supported()
-	assert.Equal(t, false, ret)
-
-	ret = testReleaseV371.Supported()
+	// 3.6 is not supported after 3.8.0 release
+	ret = testReleaseV360.Supported()
 	assert.Equal(t, false, ret)
 
-	ret = testReleaseV380.Supported()
+	ret = testReleaseV370.Supported()
 	assert.Equal(t, true, ret)
 
-	ret = testReleaseV381.Supported()
+	ret = testReleaseV371.Supported()
 	assert.Equal(t, true, ret)
 
-	ret = testReleaseV390.Supported()
+	ret = testReleaseV380.Supported()
 	assert.Equal(t, true, ret)
 
-	ret = testReleaseV391.Supported()
+	ret = testReleaseV381.Supported()
 	assert.Equal(t, true, ret)
 }
 
@@ -114,3 +115,42 @@ func Test_extractCephCSIVersion(t *testing.T) {
 	assert.Nil(t, version)
 	assert.Contains(t, err.Error(), "failed to parse version from")
 }
+
+func TestSupportsCustomCephConf(t *testing.T) {
+	AllowUnsupported = true
+	ret := testMinVersion.SupportsCustomCephConf()
+	assert.True(t, ret)
+
+	AllowUnsupported = false
+	ret = testMinVersion.SupportsCustomCephConf()
+	assert.True(t, ret)
+
+	ret = testReleaseV360.SupportsCustomCephConf()
+	assert.True(t, ret)
+
+	ret = testReleaseV370.SupportsCustomCephConf()
+	assert.True(t, ret)
+
+	ret = testReleaseV371.SupportsCustomCephConf()
+	assert.True(t, ret)
+}
+
+func TestSupportsNsenter(t *testing.T) {
+	t.Run("AllowUnsupported=true regardless of the version", func(t *testing.T) {
+		AllowUnsupported = true
+		ret := testMinVersion.SupportsNsenter()
+		assert.True(t, ret)
+	})
+
+	t.Run("AllowUnsupported=false and version 3.5 is too old", func(t *testing.T) {
+		AllowUnsupported = false
+		ret := testReleaseV350.SupportsNsenter()
+		assert.False(t, ret)
+	})
+
+	t.Run("AllowUnsupported=false and version 3.6.1 is fine", func(t *testing.T) {
+		AllowUnsupported = false
+		ret := testReleaseV361.SupportsNsenter()
+		assert.True(t, ret)
+	})
+}