Repository: rook/rook
Pull request #10132 (2022-04-22 04:58:26)

helm: ingressClassName should be available for networking.k8s.io/v1
<!-- Please take a look at our [Contributing](https://rook.io/docs/rook/latest/development-flow.html)
documentation before submitting a Pull Request!
Thank you for contributing to Rook! -->

**Description of your changes:**
ingressClassName can't be set on clusters 1.20+ since it uses networking.k8s.io/v1

**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/development-flow.html#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/development-flow.html#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.



Patch:
diff --git a/deploy/charts/library/templates/_cluster-role.tpl b/deploy/charts/library/templates/_cluster-role.tpl
index d3fa2b049..1f23d09ce 100644
--- a/deploy/charts/library/templates/_cluster-role.tpl
+++ b/deploy/charts/library/templates/_cluster-role.tpl
@@ -27,14 +27,7 @@ metadata:
   namespace: {{ .Release.Namespace }} # namespace:cluster
 rules:
   # Placeholder role so the rgw service account will
-  # be generated in the csv. Remove this role and role binding
-  # when fixing https://github.com/rook/rook/issues/10141.
-  - apiGroups:
-      - ""
-    resources:
-      - configmaps
-    verbs:
-      - get
+  # be generated in the csv
 ---
 # Aspects of ceph-mgr that operate within the cluster's namespace
 kind: Role
diff --git a/deploy/charts/rook-ceph-cluster/templates/ingress.yaml b/deploy/charts/rook-ceph-cluster/templates/ingress.yaml
index ac14cc6ac..4cf4c42ca 100644
--- a/deploy/charts/rook-ceph-cluster/templates/ingress.yaml
+++ b/deploy/charts/rook-ceph-cluster/templates/ingress.yaml
@@ -31,10 +31,10 @@ spec:
               {{- else }}
               servicePort: http-dashboard
               {{- end }}
+{{- end }}
   {{- if .Values.ingress.dashboard.ingressClassName }}
   ingressClassName: {{ .Values.ingress.dashboard.ingressClassName }}
   {{- end }}
-{{- end }}
   {{- if .Values.ingress.dashboard.tls }}
   tls: {{- toYaml .Values.ingress.dashboard.tls | nindent 4 }}
   {{- end }}
diff --git a/deploy/examples/common.yaml b/deploy/examples/common.yaml
index a4615aca1..25c0ccb97 100644
--- a/deploy/examples/common.yaml
+++ b/deploy/examples/common.yaml
@@ -1011,15 +1011,8 @@ metadata:
   name: rook-ceph-rgw
   namespace: rook-ceph # namespace:cluster
 rules:
-  # Placeholder role so the rgw service account will
-  # be generated in the csv. Remove this role and role binding
-  # when fixing https://github.com/rook/rook/issues/10141.
-  - apiGroups:
-      - ""
-    resources:
-      - configmaps
-    verbs:
-      - get
+# Placeholder role so the rgw service account will
+# be generated in the csv
 ---
 # Allow the operator to manage resources in its own namespace
 apiVersion: rbac.authorization.k8s.io/v1
diff --git a/pkg/operator/ceph/cluster/cluster_external.go b/pkg/operator/ceph/cluster/cluster_external.go
index 8f67c7da8..bc960a7ae 100644
--- a/pkg/operator/ceph/cluster/cluster_external.go
+++ b/pkg/operator/ceph/cluster/cluster_external.go
@@ -114,7 +114,7 @@ func (c *ClusterController) configureExternalCephCluster(cluster *cluster) error
 	}
 
 	// Save CSI configmap
-	err = csi.SaveClusterConfig(c.context.Clientset, c.namespacedName.Namespace, cluster.ClusterInfo, &csi.CsiClusterConfigEntry{Namespace: cluster.ClusterInfo.Namespace, Monitors: csi.MonEndpoints(cluster.ClusterInfo.Monitors)})
+	err = csi.SaveClusterConfig(c.context.Clientset, c.namespacedName.Namespace, cluster.ClusterInfo, &csi.CsiClusterConfigEntry{Monitors: csi.MonEndpoints(cluster.ClusterInfo.Monitors)})
 	if err != nil {
 		return errors.Wrap(err, "failed to update csi cluster config")
 	}
diff --git a/pkg/operator/ceph/cluster/mon/mon.go b/pkg/operator/ceph/cluster/mon/mon.go
index efc9a4096..6c460c690 100644
--- a/pkg/operator/ceph/cluster/mon/mon.go
+++ b/pkg/operator/ceph/cluster/mon/mon.go
@@ -1050,7 +1050,7 @@ func (c *Cluster) saveMonConfig() error {
 		return errors.Wrap(err, "failed to write connection config for new mons")
 	}
 
-	if err := csi.SaveClusterConfig(c.context.Clientset, c.Namespace, c.ClusterInfo, &csi.CsiClusterConfigEntry{Namespace: c.ClusterInfo.Namespace, Monitors: csi.MonEndpoints(c.ClusterInfo.Monitors)}); err != nil {
+	if err := csi.SaveClusterConfig(c.context.Clientset, c.Namespace, c.ClusterInfo, &csi.CsiClusterConfigEntry{Monitors: csi.MonEndpoints(c.ClusterInfo.Monitors)}); err != nil {
 		return errors.Wrap(err, "failed to update csi cluster config")
 	}
 
diff --git a/pkg/operator/ceph/csi/cluster_config.go b/pkg/operator/ceph/csi/cluster_config.go
index 6f241acb2..7e665dbb8 100644
--- a/pkg/operator/ceph/csi/cluster_config.go
+++ b/pkg/operator/ceph/csi/cluster_config.go
@@ -40,7 +40,6 @@ var (
 type CsiClusterConfigEntry struct {
 	ClusterID      string         `json:"clusterID"`
 	Monitors       []string       `json:"monitors"`
-	Namespace      string         `json:"namespace"`
 	CephFS         *CsiCephFSSpec `json:"cephFS,omitempty"`
 	RadosNamespace string         `json:"radosNamespace,omitempty"`
 }
@@ -113,16 +112,6 @@ func updateCsiClusterConfig(curr, clusterKey string, newCsiClusterConfigEntry *C
 	// a lock is acquired for the update operation. So concurrent updates (rare event) will block and
 	// wait for the other update to complete. Monitors and Subvolumegroup will be updated
 	// independently and won't collide.
-	if newCsiClusterConfigEntry != nil {
-		for i, centry := range cc {
-			// If the clusterID belongs to the same cluster, update the entry.
-			// update default clusterID's entry
-			if clusterKey == centry.Namespace {
-				centry.Monitors = newCsiClusterConfigEntry.Monitors
-				cc[i] = centry
-			}
-		}
-	}
 	for i, centry := range cc {
 		if centry.ClusterID == clusterKey {
 			// If the new entry is nil, this means the entry is being deleted so remove it from the list
@@ -148,7 +137,6 @@ func updateCsiClusterConfig(curr, clusterKey string, newCsiClusterConfigEntry *C
 		// will fail with a dangling pointer
 		if newCsiClusterConfigEntry != nil {
 			centry.ClusterID = clusterKey
-			centry.Namespace = newCsiClusterConfigEntry.Namespace
 			centry.Monitors = newCsiClusterConfigEntry.Monitors
 			// Add a condition not to fill with empty values
 			if newCsiClusterConfigEntry.CephFS != nil && newCsiClusterConfigEntry.CephFS.SubvolumeGroup != "" {
diff --git a/pkg/operator/ceph/csi/csi.go b/pkg/operator/ceph/csi/csi.go
index 0efdc446e..9b9bc50aa 100644
--- a/pkg/operator/ceph/csi/csi.go
+++ b/pkg/operator/ceph/csi/csi.go
@@ -17,14 +17,10 @@ limitations under the License.
 package csi
 
 import (
-	"fmt"
 	"strconv"
-	"strings"
-	"time"
 
 	"github.com/pkg/errors"
 	"github.com/rook/rook/pkg/operator/k8sutil"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/version"
 )
 
@@ -34,7 +30,7 @@ func (r *ReconcileCSI) validateAndConfigureDrivers(serverVersion *version.Info,
 		err error
 	)
 
-	if err = r.setParams(serverVersion); err != nil {
+	if err = r.setParams(); err != nil {
 		return errors.Wrapf(err, "failed to configure CSI parameters")
 	}
 
@@ -60,7 +56,7 @@ func (r *ReconcileCSI) validateAndConfigureDrivers(serverVersion *version.Info,
 	return r.stopDrivers(serverVersion)
 }
 
-func (r *ReconcileCSI) setParams(ver *version.Info) error {
+func (r *ReconcileCSI) setParams() error {
 	var err error
 
 	if EnableRBD, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_ENABLE_RBD", "true")); err != nil {
@@ -82,154 +78,11 @@ func (r *ReconcileCSI) setParams(ver *version.Info) error {
 	if EnableCSIGRPCMetrics, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_ENABLE_GRPC_METRICS", "false")); err != nil {
 		return errors.Wrap(err, "unable to parse value for 'ROOK_CSI_ENABLE_GRPC_METRICS'")
 	}
-	CSIParam.EnableCSIGRPCMetrics = fmt.Sprintf("%t", EnableCSIGRPCMetrics)
 
 	if CSIParam.EnableCSIHostNetwork, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_HOST_NETWORK", "true")); err != nil {
 		return errors.Wrap(err, "failed to parse value for 'CSI_ENABLE_HOST_NETWORK'")
 	}
 
-	// If not set or set to anything but "false", the kernel client will be enabled
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_FORCE_CEPHFS_KERNEL_CLIENT", "true"), "false") {
-		CSIParam.ForceCephFSKernelClient = "false"
-	} else {
-		CSIParam.ForceCephFSKernelClient = "true"
-	}
-
-	// parse RPC timeout
-	timeout := k8sutil.GetValue(r.opConfig.Parameters, grpcTimeout, "150")
-	timeoutSeconds, err := strconv.Atoi(timeout)
-	if err != nil {
-		logger.Errorf("failed to parse %q. Defaulting to %d. %v", grpcTimeout, defaultGRPCTimeout, err)
-		timeoutSeconds = defaultGRPCTimeout
-	}
-	if timeoutSeconds < 120 {
-		logger.Warningf("%s is %q but it should be >= 120, setting the default value %d", grpcTimeout, timeout, defaultGRPCTimeout)
-		timeoutSeconds = defaultGRPCTimeout
-	}
-	CSIParam.GRPCTimeout = time.Duration(timeoutSeconds) * time.Second
-
-	// parse GRPC and Liveness ports
-	CSIParam.CephFSGRPCMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_CEPHFS_GRPC_METRICS_PORT", DefaultCephFSGRPCMerticsPort)
-	if err != nil {
-		return errors.Wrap(err, "error getting CSI CephFS GRPC metrics port.")
-	}
-	CSIParam.CephFSLivenessMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_CEPHFS_LIVENESS_METRICS_PORT", DefaultCephFSLivenessMerticsPort)
-	if err != nil {
-		return errors.Wrap(err, "error getting CSI CephFS liveness metrics port.")
-	}
-
-	CSIParam.RBDGRPCMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_RBD_GRPC_METRICS_PORT", DefaultRBDGRPCMerticsPort)
-	if err != nil {
-		return errors.Wrap(err, "error getting CSI RBD GRPC metrics port.")
-	}
-	CSIParam.CSIAddonsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSIADDONS_PORT", DefaultCSIAddonsPort)
-	if err != nil {
-		return errors.Wrap(err, "failed to get CSI Addons port")
-	}
-	CSIParam.RBDLivenessMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_RBD_LIVENESS_METRICS_PORT", DefaultRBDLivenessMerticsPort)
-	if err != nil {
-		return errors.Wrap(err, "error getting CSI RBD liveness metrics port.")
-	}
-
-	// default value `system-node-critical` is the highest available priority
-	CSIParam.PluginPriorityClassName = k8sutil.GetValue(r.opConfig.Parameters, "CSI_PLUGIN_PRIORITY_CLASSNAME", "")
-
-	// default value `system-cluster-critical` is applied for some
-	// critical pods in cluster but less priority than plugin pods
-	CSIParam.ProvisionerPriorityClassName = k8sutil.GetValue(r.opConfig.Parameters, "CSI_PROVISIONER_PRIORITY_CLASSNAME", "")
-
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_OMAP_GENERATOR", "false"), "true") {
-		CSIParam.EnableOMAPGenerator = true
-	}
-
-	// SA token projection is stable only from kubernetes version 1.20.
-	if ver.Major == KubeMinMajor && ver.Minor >= KubeMinVerForOIDCTokenProjection {
-		CSIParam.EnableOIDCTokenProjection = true
-	}
-
-	// if k8s >= v1.17 enable RBD and CephFS snapshotter by default
-	if ver.Major == KubeMinMajor && ver.Minor >= kubeMinVerForSnapshot {
-		CSIParam.EnableRBDSnapshotter = true
-		CSIParam.EnableCephFSSnapshotter = true
-	}
-
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_RBD_SNAPSHOTTER", "true"), "false") {
-		CSIParam.EnableRBDSnapshotter = false
-	}
-
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_CEPHFS_SNAPSHOTTER", "true"), "false") {
-		CSIParam.EnableCephFSSnapshotter = false
-	}
-
-	CSIParam.EnableVolumeReplicationSideCar = false
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_VOLUME_REPLICATION", "false"), "true") {
-		CSIParam.EnableVolumeReplicationSideCar = true
-	}
-
-	CSIParam.EnableCSIAddonsSideCar = false
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_CSIADDONS", "false"), "true") {
-		CSIParam.EnableCSIAddonsSideCar = true
-	}
-
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_ENCRYPTION", "false"), "true") {
-		CSIParam.EnableCSIEncryption = true
-	}
-
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
-		CSIParam.CephFSPluginUpdateStrategy = onDelete
-	} else {
-		CSIParam.CephFSPluginUpdateStrategy = rollingUpdate
-	}
-
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_NFS_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
-		CSIParam.NFSPluginUpdateStrategy = onDelete
-	} else {
-		CSIParam.NFSPluginUpdateStrategy = rollingUpdate
-	}
-
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_RBD_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
-		CSIParam.RBDPluginUpdateStrategy = onDelete
-	} else {
-		CSIParam.RBDPluginUpdateStrategy = rollingUpdate
-	}
-
-	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_PLUGIN_ENABLE_SELINUX_HOST_MOUNT", "false"), "true") {
-		CSIParam.EnablePluginSelinuxHostMount = true
-	}
-
-	logger.Infof("Kubernetes version is %s.%s", ver.Major, ver.Minor)
-
-	CSIParam.ResizerImage = k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_RESIZER_IMAGE", DefaultResizerImage)
-
-	logLevel := k8sutil.GetValue(r.opConfig.Parameters, "CSI_LOG_LEVEL", "")
-	CSIParam.LogLevel = defaultLogLevel
-	if logLevel != "" {
-		l, err := strconv.ParseUint(logLevel, 10, 8)
-		if err != nil {
-			logger.Errorf("failed to parse CSI_LOG_LEVEL. Defaulting to %d. %v", defaultLogLevel, err)
-		} else {
-			CSIParam.LogLevel = uint8(l)
-		}
-	}
-
-	CSIParam.ProvisionerReplicas = defaultProvisionerReplicas
-	nodes, err := r.context.Clientset.CoreV1().Nodes().List(r.opManagerContext, metav1.ListOptions{})
-	if err == nil {
-		if len(nodes.Items) == 1 {
-			CSIParam.ProvisionerReplicas = 1
-		} else {
-			replicas := k8sutil.GetValue(r.opConfig.Parameters, "CSI_PROVISIONER_REPLICAS", "2")
-			r, err := strconv.ParseInt(replicas, 10, 32)
-			if err != nil {
-				logger.Errorf("failed to parse CSI_PROVISIONER_REPLICAS. Defaulting to %d. %v", defaultProvisionerReplicas, err)
-			} else {
-				CSIParam.ProvisionerReplicas = int32(r)
-			}
-		}
-	} else {
-		logger.Errorf("failed to get nodes. Defaulting the number of replicas of provisioner pods to %d. %v", CSIParam.ProvisionerReplicas, err)
-	}
-
 	CSIParam.CSIPluginImage = k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_CEPH_IMAGE", DefaultCSIPluginImage)
 	CSIParam.NFSPluginImage = k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_NFS_IMAGE", DefaultNFSPluginImage)
 	CSIParam.RegistrarImage = k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_REGISTRAR_IMAGE", DefaultRegistrarImage)
diff --git a/pkg/operator/ceph/csi/spec.go b/pkg/operator/ceph/csi/spec.go
index 526c709ec..e85e4f957 100644
--- a/pkg/operator/ceph/csi/spec.go
+++ b/pkg/operator/ceph/csi/spec.go
@@ -20,6 +20,8 @@ import (
 	"context"
 	_ "embed"
 	"fmt"
+	"strconv"
+	"strings"
 	"time"
 
 	"github.com/rook/rook/pkg/operator/k8sutil"
@@ -258,10 +260,6 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 	RBDDriverName = tp.DriverNamePrefix + "rbd.csi.ceph.com"
 	NFSDriverName = tp.DriverNamePrefix + "nfs.csi.ceph.com"
 
-	if CustomCSICephConfigExists {
-		CSIParam.MountCustomCephConf = v.SupportsCustomCephConf()
-	}
-
 	csiDriverobj = beta1CsiDriver{}
 	if ver.Major > KubeMinMajor || ver.Major == KubeMinMajor && ver.Minor >= kubeMinVerForV1csiDriver {
 		csiDriverobj = v1CsiDriver{}
@@ -284,6 +282,153 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 		}
 	}
 
+	tp.EnableCSIGRPCMetrics = fmt.Sprintf("%t", EnableCSIGRPCMetrics)
+
+	// If not set or set to anything but "false", the kernel client will be enabled
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_FORCE_CEPHFS_KERNEL_CLIENT", "true"), "false") {
+		tp.ForceCephFSKernelClient = "false"
+	} else {
+		tp.ForceCephFSKernelClient = "true"
+	}
+
+	// parese RPC timeout
+	timeout := k8sutil.GetValue(r.opConfig.Parameters, grpcTimeout, "150")
+	timeoutSeconds, err := strconv.Atoi(timeout)
+	if err != nil {
+		logger.Errorf("failed to parse %q. Defaulting to %d. %v", grpcTimeout, defaultGRPCTimeout, err)
+		timeoutSeconds = defaultGRPCTimeout
+	}
+	if timeoutSeconds < 120 {
+		logger.Warningf("%s is %q but it should be >= 120, setting the default value %d", grpcTimeout, timeout, defaultGRPCTimeout)
+		timeoutSeconds = defaultGRPCTimeout
+	}
+	tp.GRPCTimeout = time.Duration(timeoutSeconds) * time.Second
+
+	// parse GRPC and Liveness ports
+	tp.CephFSGRPCMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_CEPHFS_GRPC_METRICS_PORT", DefaultCephFSGRPCMerticsPort)
+	if err != nil {
+		return errors.Wrap(err, "error getting CSI CephFS GRPC metrics port.")
+	}
+	tp.CephFSLivenessMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_CEPHFS_LIVENESS_METRICS_PORT", DefaultCephFSLivenessMerticsPort)
+	if err != nil {
+		return errors.Wrap(err, "error getting CSI CephFS liveness metrics port.")
+	}
+
+	tp.RBDGRPCMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_RBD_GRPC_METRICS_PORT", DefaultRBDGRPCMerticsPort)
+	if err != nil {
+		return errors.Wrap(err, "error getting CSI RBD GRPC metrics port.")
+	}
+	tp.CSIAddonsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSIADDONS_PORT", DefaultCSIAddonsPort)
+	if err != nil {
+		return errors.Wrap(err, "failed to get CSI Addons port")
+	}
+	tp.RBDLivenessMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_RBD_LIVENESS_METRICS_PORT", DefaultRBDLivenessMerticsPort)
+	if err != nil {
+		return errors.Wrap(err, "error getting CSI RBD liveness metrics port.")
+	}
+
+	// default value `system-node-critical` is the highest available priority
+	tp.PluginPriorityClassName = k8sutil.GetValue(r.opConfig.Parameters, "CSI_PLUGIN_PRIORITY_CLASSNAME", "")
+
+	// default value `system-cluster-critical` is applied for some
+	// critical pods in cluster but less priority than plugin pods
+	tp.ProvisionerPriorityClassName = k8sutil.GetValue(r.opConfig.Parameters, "CSI_PROVISIONER_PRIORITY_CLASSNAME", "")
+
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_OMAP_GENERATOR", "false"), "true") {
+		tp.EnableOMAPGenerator = true
+	}
+
+	// SA token projection is stable only from kubernetes version 1.20.
+	if ver.Major == KubeMinMajor && ver.Minor >= KubeMinVerForOIDCTokenProjection {
+		tp.EnableOIDCTokenProjection = true
+	}
+
+	// if k8s >= v1.17 enable RBD and CephFS snapshotter by default
+	if ver.Major == KubeMinMajor && ver.Minor >= kubeMinVerForSnapshot {
+		tp.EnableRBDSnapshotter = true
+		tp.EnableCephFSSnapshotter = true
+	}
+
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_RBD_SNAPSHOTTER", "true"), "false") {
+		tp.EnableRBDSnapshotter = false
+	}
+
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_CEPHFS_SNAPSHOTTER", "true"), "false") {
+		tp.EnableCephFSSnapshotter = false
+	}
+
+	tp.EnableVolumeReplicationSideCar = false
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_VOLUME_REPLICATION", "false"), "true") {
+		tp.EnableVolumeReplicationSideCar = true
+	}
+
+	tp.EnableCSIAddonsSideCar = false
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_CSIADDONS", "false"), "true") {
+		tp.EnableCSIAddonsSideCar = true
+	}
+
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_ENCRYPTION", "false"), "true") {
+		tp.EnableCSIEncryption = true
+	}
+
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
+		tp.CephFSPluginUpdateStrategy = onDelete
+	} else {
+		tp.CephFSPluginUpdateStrategy = rollingUpdate
+	}
+
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_NFS_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
+		tp.NFSPluginUpdateStrategy = onDelete
+	} else {
+		tp.NFSPluginUpdateStrategy = rollingUpdate
+	}
+
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_RBD_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
+		tp.RBDPluginUpdateStrategy = onDelete
+	} else {
+		tp.RBDPluginUpdateStrategy = rollingUpdate
+	}
+
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_PLUGIN_ENABLE_SELINUX_HOST_MOUNT", "false"), "true") {
+		tp.EnablePluginSelinuxHostMount = true
+	}
+
+	logger.Infof("Kubernetes version is %s.%s", ver.Major, ver.Minor)
+
+	tp.ResizerImage = k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_RESIZER_IMAGE", DefaultResizerImage)
+
+	logLevel := k8sutil.GetValue(r.opConfig.Parameters, "CSI_LOG_LEVEL", "")
+	tp.LogLevel = defaultLogLevel
+	if logLevel != "" {
+		l, err := strconv.ParseUint(logLevel, 10, 8)
+		if err != nil {
+			logger.Errorf("failed to parse CSI_LOG_LEVEL. Defaulting to %d. %v", defaultLogLevel, err)
+		} else {
+			tp.LogLevel = uint8(l)
+		}
+	}
+
+	if CustomCSICephConfigExists {
+		tp.MountCustomCephConf = v.SupportsCustomCephConf()
+	}
+	tp.ProvisionerReplicas = defaultProvisionerReplicas
+	nodes, err := r.context.Clientset.CoreV1().Nodes().List(r.opManagerContext, metav1.ListOptions{})
+	if err == nil {
+		if len(nodes.Items) == 1 {
+			tp.ProvisionerReplicas = 1
+		} else {
+			replicas := k8sutil.GetValue(r.opConfig.Parameters, "CSI_PROVISIONER_REPLICAS", "2")
+			r, err := strconv.ParseInt(replicas, 10, 32)
+			if err != nil {
+				logger.Errorf("failed to parse CSI_PROVISIONER_REPLICAS. Defaulting to %d. %v", defaultProvisionerReplicas, err)
+			} else {
+				tp.ProvisionerReplicas = int32(r)
+			}
+		}
+	} else {
+		logger.Errorf("failed to get nodes. Defaulting the number of replicas of provisioner pods to %d. %v", tp.ProvisionerReplicas, err)
+	}
+
 	if EnableRBD {
 		rbdPlugin, err = templateToDaemonSet("rbdplugin", RBDPluginTemplatePath, tp)
 		if err != nil {
diff --git a/pkg/operator/ceph/file/subvolumegroup/controller.go b/pkg/operator/ceph/file/subvolumegroup/controller.go
index fe3f1403f..2855ce3ef 100644
--- a/pkg/operator/ceph/file/subvolumegroup/controller.go
+++ b/pkg/operator/ceph/file/subvolumegroup/controller.go
@@ -265,8 +265,7 @@ func (r *ReconcileCephFilesystemSubVolumeGroup) updateClusterConfig(cephFilesyst
 	// If the mon endpoints change, the mon health check go routine will take care of updating the
 	// config map, so no special care is needed in this controller
 	csiClusterConfigEntry := csi.CsiClusterConfigEntry{
-		Namespace: r.clusterInfo.Namespace,
-		Monitors:  csi.MonEndpoints(r.clusterInfo.Monitors),
+		Monitors: csi.MonEndpoints(r.clusterInfo.Monitors),
 		CephFS: &csi.CsiCephFSSpec{
 			SubvolumeGroup: cephFilesystemSubVolumeGroup.Name,
 		},
diff --git a/pkg/operator/ceph/pool/radosnamespace/controller.go b/pkg/operator/ceph/pool/radosnamespace/controller.go
index 866a3b682..c4bf66360 100644
--- a/pkg/operator/ceph/pool/radosnamespace/controller.go
+++ b/pkg/operator/ceph/pool/radosnamespace/controller.go
@@ -257,7 +257,6 @@ func (r *ReconcileCephBlockPoolRadosNamespace) updateClusterConfig(cephBlockPool
 	// If the mon endpoints change, the mon health check go routine will take care of updating the
 	// config map, so no special care is needed in this controller
 	csiClusterConfigEntry := csi.CsiClusterConfigEntry{
-		Namespace:      r.clusterInfo.Namespace,
 		Monitors:       csi.MonEndpoints(r.clusterInfo.Monitors),
 		RadosNamespace: cephBlockPoolRadosNamespace.Name,
 	}


Test patch:
diff --git a/pkg/operator/ceph/csi/cluster_config_test.go b/pkg/operator/ceph/csi/cluster_config_test.go
index df974bae6..08c9e1cad 100644
--- a/pkg/operator/ceph/csi/cluster_config_test.go
+++ b/pkg/operator/ceph/csi/cluster_config_test.go
@@ -24,39 +24,35 @@ import (
 
 func TestUpdateCsiClusterConfig(t *testing.T) {
 	csiClusterConfigEntry := CsiClusterConfigEntry{
-		Namespace: "rook-ceph-1",
-		Monitors:  []string{"1.2.3.4:5000"},
+		Monitors: []string{"1.2.3.4:5000"},
 	}
 	csiClusterConfigEntry2 := CsiClusterConfigEntry{
-		Namespace: "rook-ceph-2",
-		Monitors:  []string{"20.1.1.1:5000", "20.1.1.2:5000", "20.1.1.3:5000"},
+		Monitors: []string{"20.1.1.1:5000", "20.1.1.2:5000", "20.1.1.3:5000"},
 	}
 	csiClusterConfigEntry3 := CsiClusterConfigEntry{
-		Namespace: "rook-ceph-3",
-		Monitors:  []string{"10.1.1.1:5000", "10.1.1.2:5000", "10.1.1.3:5000"},
+		Monitors: []string{"10.1.1.1:5000", "10.1.1.2:5000", "10.1.1.3:5000"},
 		CephFS: &CsiCephFSSpec{
 			SubvolumeGroup: "mygroup",
 		},
 	}
-
 	var s string
 	var err error
 
 	t.Run("add a simple mons list", func(t *testing.T) {
-		s, err = updateCsiClusterConfig("[]", "rook-ceph-1", &csiClusterConfigEntry)
+		s, err = updateCsiClusterConfig("[]", "alpha", &csiClusterConfigEntry)
 		assert.NoError(t, err)
 		assert.Equal(t, s,
-			`[{"clusterID":"rook-ceph-1","monitors":["1.2.3.4:5000"],"namespace":"rook-ceph-1"}]`)
+			`[{"clusterID":"alpha","monitors":["1.2.3.4:5000"]}]`)
 	})
 
 	t.Run("add a 2nd mon to the current cluster", func(t *testing.T) {
 		csiClusterConfigEntry.Monitors = append(csiClusterConfigEntry.Monitors, "10.11.12.13:5000")
-		s, err = updateCsiClusterConfig(s, "rook-ceph-1", &csiClusterConfigEntry)
+		s, err = updateCsiClusterConfig(s, "alpha", &csiClusterConfigEntry)
 		assert.NoError(t, err)
 		cc, err := parseCsiClusterConfig(s)
 		assert.NoError(t, err)
 		assert.Equal(t, 1, len(cc))
-		assert.Equal(t, "rook-ceph-1", cc[0].ClusterID)
+		assert.Equal(t, "alpha", cc[0].ClusterID)
 		assert.Contains(t, cc[0].Monitors, "1.2.3.4:5000")
 		assert.Contains(t, cc[0].Monitors, "10.11.12.13:5000")
 		assert.Equal(t, 2, len(cc[0].Monitors))
@@ -68,18 +64,14 @@ func TestUpdateCsiClusterConfig(t *testing.T) {
 		cc, err := parseCsiClusterConfig(s)
 		assert.NoError(t, err)
 		assert.Equal(t, 2, len(cc))
-		assert.Equal(t, "rook-ceph-1", cc[0].ClusterID)
+		assert.Equal(t, "alpha", cc[0].ClusterID)
 		assert.Contains(t, cc[0].Monitors, "1.2.3.4:5000")
 		assert.Contains(t, cc[0].Monitors, "10.11.12.13:5000")
-		// check 1st cluster contains any of the 3 mons from 2nd cluster
-		assert.NotContains(t, cc[0].Monitors, "20.1.1.1:5000")
 		assert.Equal(t, 2, len(cc[0].Monitors))
 		assert.Equal(t, "beta", cc[1].ClusterID)
 		assert.Contains(t, cc[1].Monitors, "20.1.1.1:5000")
 		assert.Contains(t, cc[1].Monitors, "20.1.1.2:5000")
 		assert.Contains(t, cc[1].Monitors, "20.1.1.3:5000")
-		// check 2nd cluster contains any of the mons from 1st cluster
-		assert.NotContains(t, cc[1].Monitors, "10.11.12.13:5000")
 		assert.Equal(t, 3, len(cc[1].Monitors))
 	})
 
@@ -92,7 +84,7 @@ func TestUpdateCsiClusterConfig(t *testing.T) {
 		cc, err := parseCsiClusterConfig(s)
 		assert.NoError(t, err)
 		assert.Equal(t, 2, len(cc))
-		assert.Equal(t, "rook-ceph-1", cc[0].ClusterID)
+		assert.Equal(t, "alpha", cc[0].ClusterID)
 		assert.Contains(t, cc[0].Monitors, "1.2.3.4:5000")
 		assert.Contains(t, cc[0].Monitors, "10.11.12.13:5000")
 		assert.Equal(t, 2, len(cc[0].Monitors))
@@ -108,7 +100,7 @@ func TestUpdateCsiClusterConfig(t *testing.T) {
 		cc, err := parseCsiClusterConfig(s)
 		assert.NoError(t, err)
 		assert.Equal(t, 3, len(cc))
-		assert.Equal(t, "rook-ceph-1", cc[0].ClusterID)
+		assert.Equal(t, "alpha", cc[0].ClusterID)
 		assert.Equal(t, 2, len(cc[0].Monitors))
 		assert.Equal(t, "beta", cc[1].ClusterID)
 		assert.Equal(t, "baba", cc[2].ClusterID)
@@ -165,155 +157,4 @@ func TestUpdateCsiClusterConfig(t *testing.T) {
 		_, err = updateCsiClusterConfig("qqq", "beta", &csiClusterConfigEntry2)
 		assert.Error(t, err)
 	})
-
-	t.Run("test mon IP's update across all clusterID's belong to same cluster", func(t *testing.T) {
-		clusterIDofCluster1 := "rook-ceph"
-		subvolGrpNameofCluster1 := "subvol-group"
-		radosNSofCluster1 := "rados-ns"
-
-		csiCluster1ConfigEntry := CsiClusterConfigEntry{
-			Namespace: clusterIDofCluster1,
-			Monitors:  []string{"1.2.3.4:5000"},
-		}
-		s, err := updateCsiClusterConfig("[]", clusterIDofCluster1, &csiCluster1ConfigEntry)
-		assert.NoError(t, err)
-		assert.Equal(t, s,
-			`[{"clusterID":"rook-ceph","monitors":["1.2.3.4:5000"],"namespace":"rook-ceph"}]`)
-		// add subvolumegroup to same cluster
-		subVolCsiCluster1Config := CsiClusterConfigEntry{
-			Namespace: clusterIDofCluster1,
-			Monitors:  csiCluster1ConfigEntry.Monitors,
-			CephFS: &CsiCephFSSpec{
-				SubvolumeGroup: subvolGrpNameofCluster1,
-			},
-		}
-		s, err = updateCsiClusterConfig(s, subvolGrpNameofCluster1, &subVolCsiCluster1Config)
-		assert.NoError(t, err)
-		cc, err := parseCsiClusterConfig(s)
-		assert.NoError(t, err)
-		assert.Equal(t, 2, len(cc), cc)
-		assert.Equal(t, 1, len(cc[1].Monitors))
-		assert.Equal(t, subvolGrpNameofCluster1, cc[1].CephFS.SubvolumeGroup, cc)
-
-		// add rados to same cluster
-		radosNsCsiCluster1Config := CsiClusterConfigEntry{
-			Namespace:      clusterIDofCluster1,
-			Monitors:       csiCluster1ConfigEntry.Monitors,
-			RadosNamespace: radosNSofCluster1,
-		}
-		s, err = updateCsiClusterConfig(s, radosNSofCluster1, &radosNsCsiCluster1Config)
-		assert.NoError(t, err)
-		cc, err = parseCsiClusterConfig(s)
-		assert.NoError(t, err)
-		assert.Equal(t, 3, len(cc), cc)
-		assert.Equal(t, 1, len(cc[2].Monitors))
-		assert.Equal(t, radosNSofCluster1, cc[2].RadosNamespace, cc)
-
-		// update mon IP's and check is it updating for all clusterID's
-		csiCluster1ConfigEntry.Monitors = append(csiCluster1ConfigEntry.Monitors, "1.2.3.10:5000")
-		s, err = updateCsiClusterConfig(s, clusterIDofCluster1, &csiCluster1ConfigEntry)
-		assert.NoError(t, err)
-		cc, err = parseCsiClusterConfig(s)
-		assert.NoError(t, err)
-		assert.Equal(t, 3, len(cc), cc)
-		// check mon entries are updated in all configmap
-		for _, i := range cc {
-			assert.Equal(t, 2, len(i.Monitors))
-		}
-
-		clusterIDofCluster2 := "rook-ceph-2"
-		subvolGrpNameofCluster2 := "subvol-group-2"
-		radosNSofCluster2 := "rados-ns-2"
-
-		cluster2Mons := []string{"192.168.0.2:5000"}
-		csiCluster2ConfigEntry := CsiClusterConfigEntry{
-			Namespace: clusterIDofCluster2,
-			Monitors:  cluster2Mons,
-		}
-		subVolCsiCluster2Config := CsiClusterConfigEntry{
-			Namespace: clusterIDofCluster2,
-			Monitors:  cluster2Mons,
-			CephFS: &CsiCephFSSpec{
-				SubvolumeGroup: subvolGrpNameofCluster2,
-			},
-		}
-		radosNsCsiCluster2Config := CsiClusterConfigEntry{
-			Namespace:      clusterIDofCluster2,
-			Monitors:       cluster2Mons,
-			RadosNamespace: radosNSofCluster2,
-		}
-		s, err = updateCsiClusterConfig(s, clusterIDofCluster2, &csiCluster2ConfigEntry)
-		assert.NoError(t, err)
-		s, err = updateCsiClusterConfig(s, subvolGrpNameofCluster2, &subVolCsiCluster2Config)
-		assert.NoError(t, err)
-		s, err = updateCsiClusterConfig(s, radosNSofCluster2, &radosNsCsiCluster2Config)
-		assert.NoError(t, err)
-		cc, err = parseCsiClusterConfig(s)
-		assert.NoError(t, err)
-		assert.Equal(t, 6, len(cc), cc)
-		// check mon entries of 1st cluster amd mon overlapping with 2nd cluster
-		for i := 0; i < 3; i++ {
-			assert.Equal(t, 2, len(cc[i].Monitors))
-			assert.False(t, contains(cc[i].Monitors, cluster2Mons))
-
-		}
-		// check mon entries of 2nd cluster
-		for i := 3; i < 6; i++ {
-			assert.Equal(t, 1, len(cc[i].Monitors))
-			assert.False(t, contains(cc[i].Monitors, csiCluster1ConfigEntry.Monitors))
-		}
-		// update mon on 2nd cluster and check is it updating for all clusterID's
-		// of 2nd cluster
-		csiCluster2ConfigEntry.Monitors = append(csiCluster2ConfigEntry.Monitors, "192.168.0.3:5000")
-		s, err = updateCsiClusterConfig(s, clusterIDofCluster2, &csiCluster2ConfigEntry)
-		assert.NoError(t, err)
-		cc, err = parseCsiClusterConfig(s)
-		assert.NoError(t, err)
-		assert.Equal(t, 6, len(cc), cc)
-		// check mon entries are updated
-		for _, i := range cc {
-			assert.Equal(t, 2, len(i.Monitors))
-		}
-		// check for overlapping
-		// check mon entries of 1st cluster amd mon overlapping with 2nd cluster
-		for i := 0; i < 3; i++ {
-			assert.False(t, contains(cc[i].Monitors, cluster2Mons))
-		}
-		// check mon entries of 2nd cluster
-		for i := 3; i < 6; i++ {
-			assert.False(t, contains(cc[i].Monitors, csiCluster1ConfigEntry.Monitors))
-		}
-		// Remove one mon from 2nd cluster and check is it updating for all
-		// clusterID's of 2nd cluster
-		i := 1
-		csiCluster2ConfigEntry.Monitors = append(csiCluster2ConfigEntry.Monitors[:i], csiCluster2ConfigEntry.Monitors[i+1:]...)
-		s, err = updateCsiClusterConfig(s, clusterIDofCluster2, &csiCluster2ConfigEntry)
-		assert.NoError(t, err)
-		cc, err = parseCsiClusterConfig(s)
-		assert.NoError(t, err)
-		assert.Equal(t, 6, len(cc), cc)
-		// check for overlapping
-		// check mon entries of 1st cluster amd mon overlapping with 2nd cluster
-		for i := 0; i < 3; i++ {
-			assert.False(t, contains(cc[i].Monitors, cluster2Mons))
-			assert.Equal(t, 2, len(cc[i].Monitors))
-		}
-		// check mon entries of 2nd cluster
-		for i := 3; i < 6; i++ {
-			assert.False(t, contains(cc[i].Monitors, csiCluster1ConfigEntry.Monitors))
-			assert.Equal(t, 1, len(cc[i].Monitors))
-		}
-	})
-}
-
-func contains(src, dest []string) bool {
-	for _, s := range src {
-		for _, d := range dest {
-			if s == d {
-				return true
-			}
-		}
-	}
-
-	return false
 }