Repository: rook/rook
Pull request #15411 (2025-02-17 13:19:50)

build(deps): bump the k8s-dependencies group with 7 updates
Bumps the k8s-dependencies group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [k8s.io/api](https://github.com/kubernetes/api) | `0.32.1` | `0.32.2` |
| [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.32.1` | `0.32.2` |
| [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.32.1` | `0.32.2` |
| [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.32.1` | `0.32.2` |
| [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.32.1` | `0.32.2` |
| [k8s.io/cloud-provider](https://github.com/kubernetes/cloud-provider) | `0.32.1` | `0.32.2` |
| [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.20.1` | `0.20.2` |

Updates `k8s.io/api` from 0.32.1 to 0.32.2
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/kubernetes/api/commit/78094a6f3ff1c3d9185e3d2a13a19ca8f61e511e"><code>78094a6</code></a> Update dependencies to v0.32.2 tag</li>
<li>See full diff in <a href="https://github.com/kubernetes/api/compare/v0.32.1...v0.32.2">compare view</a></li>
</ul>
</details>
<br />

Updates `k8s.io/apiextensions-apiserver` from 0.32.1 to 0.32.2
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/kubernetes/apiextensions-apiserver/commit/a3cd61d62877a6d2ba5b22fa0e2cffa6d440d63a"><code>a3cd61d</code></a> Update dependencies to v0.32.2 tag</li>
<li>See full diff in <a href="https://github.com/kubernetes/apiextensions-apiserver/compare/v0.32.1...v0.32.2">compare view</a></li>
</ul>
</details>
<br />

Updates `k8s.io/apimachinery` from 0.32.1 to 0.32.2
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a href="https://github.com/kubernetes/apimachinery/compare/v0.32.1...v0.32.2">compare view</a></li>
</ul>
</details>
<br />

Updates `k8s.io/cli-runtime` from 0.32.1 to 0.32.2
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/kubernetes/cli-runtime/commit/fcea953049b3f93fd3c3d8f754264494e53461c3"><code>fcea953</code></a> Update dependencies to v0.32.2 tag</li>
<li>See full diff in <a href="https://github.com/kubernetes/cli-runtime/compare/v0.32.1...v0.32.2">compare view</a></li>
</ul>
</details>
<br />

Updates `k8s.io/client-go` from 0.32.1 to 0.32.2
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/kubernetes/client-go/commit/86ff7a15de4ea0bf6f55107196994dd3f2adda80"><code>86ff7a1</code></a> Update dependencies to v0.32.2 tag</li>
<li>See full diff in <a href="https://github.com/kubernetes/client-go/compare/v0.32.1...v0.32.2">compare view</a></li>
</ul>
</details>
<br />

Updates `k8s.io/cloud-provider` from 0.32.1 to 0.32.2
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/kubernetes/cloud-provider/commit/4c7238c3392470cc47866444dd72f4cc66f6f7c6"><code>4c7238c</code></a> Update dependencies to v0.32.2 tag</li>
<li>See full diff in <a href="https://github.com/kubernetes/cloud-provider/compare/v0.32.1...v0.32.2">compare view</a></li>
</ul>
</details>
<br />

Updates `sigs.k8s.io/controller-runtime` from 0.20.1 to 0.20.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/kubernetes-sigs/controller-runtime/releases">sigs.k8s.io/controller-runtime's releases</a>.</em></p>
<blockquote>
<h2>v0.20.2</h2>
<h2>What's Changed</h2>
<ul>
<li>✨ Expose all Go runtime metrics by <a href="https://github.com/k8s-infra-cherrypick-robot"><code>@​k8s-infra-cherrypick-robot</code></a> in <a href="https://redirect.github.com/kubernetes-sigs/controller-runtime/pull/3100">kubernetes-sigs/controller-runtime#3100</a></li>
<li>🐛Fix behavior of rate limit option in priorityqueue.AddWithOpts by <a href="https://github.com/k8s-infra-cherrypick-robot"><code>@​k8s-infra-cherrypick-robot</code></a> in <a href="https://redirect.github.com/kubernetes-sigs/controller-runtime/pull/3106">kubernetes-sigs/controller-runtime#3106</a></li>
<li>🌱 Update dependencies, k8s 1.32.1 by <a href="https://github.com/k8s-infra-cherrypick-robot"><code>@​k8s-infra-cherrypick-robot</code></a> in <a href="https://redirect.github.com/kubernetes-sigs/controller-runtime/pull/3108">kubernetes-sigs/controller-runtime#3108</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/kubernetes-sigs/controller-runtime/compare/v0.20.1...v0.20.2">https://github.com/kubernetes-sigs/controller-runtime/compare/v0.20.1...v0.20.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/kubernetes-sigs/controller-runtime/commit/52b17917caa97ec546423867d9637f1787830f3e"><code>52b1791</code></a> [release-0.20] 🌱 Update dependencies, k8s 1.32.1 (<a href="https://redirect.github.com/kubernetes-sigs/controller-runtime/issues/3108">#3108</a>)</li>
<li><a href="https://github.com/kubernetes-sigs/controller-runtime/commit/ed7d2a48f943692787f41a81193d46876fccee7a"><code>ed7d2a4</code></a> Merge pull request <a href="https://redirect.github.com/kubernetes-sigs/controller-runtime/issues/3106">#3106</a> from k8s-infra-cherrypick-robot/cherry-pick-3103-to-...</li>
<li><a href="https://github.com/kubernetes-sigs/controller-runtime/commit/cad72fa419af1376359af268dcc94a0a23a99fe8"><code>cad72fa</code></a> Fix behavior of rate limit option in priorityqueue.AddWithOpts</li>
<li><a href="https://github.com/kubernetes-sigs/controller-runtime/commit/fc485839d5c10112642325e7e6df25084553c0e4"><code>fc48583</code></a> [release-0.20] ✨ Expose all Go runtime metrics (<a href="https://redirect.github.com/kubernetes-sigs/controller-runtime/issues/3100">#3100</a>)</li>
<li>See full diff in <a href="https://github.com/kubernetes-sigs/controller-runtime/compare/v0.20.1...v0.20.2">compare view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions


</details>


Patch:
diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml
index 970163609..db72d3c18 100644
--- a/.github/workflows/linters.yaml
+++ b/.github/workflows/linters.yaml
@@ -61,4 +61,4 @@ jobs:
         run: make pylint
 
       - name: Setup black for py
-        uses: psf/black@8a737e727ac5ab2f1d4cf5876720ed276dc8dc4b # stable
+        uses: psf/black@1b2427a2b785cc4aac97c19bb4b9a0de063f9547 # stable
diff --git a/.github/workflows/push-build.yaml b/.github/workflows/push-build.yaml
index af40e27ac..25c9dc10c 100644
--- a/.github/workflows/push-build.yaml
+++ b/.github/workflows/push-build.yaml
@@ -14,7 +14,6 @@ defaults:
 
 permissions:
   contents: read
-  packages: write
 
 jobs:
   push-image-to-container-registry:
@@ -42,20 +41,6 @@ jobs:
           username: ${{ secrets.DOCKER_USERNAME }}
           password: ${{ secrets.DOCKER_PASSWORD }}
 
-      - name: Login to Quay.io
-        uses: docker/login-action@v3
-        with:
-          registry: quay.io
-          username: ${{ secrets.QUAY_USERNAME }}
-          password: ${{ secrets.QUAY_ROBOT_TOKEN }}
-
-      - name: Login to GitHub Container Registry
-        uses: docker/login-action@v3
-        with:
-          registry: ghcr.io
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-
       - name: Configure AWS Credentials
         uses: aws-actions/configure-aws-credentials@ececac1a45f3b08a01d2dd070d28d111c5fe6722 # v4.1.0
         with:
@@ -69,10 +54,6 @@ jobs:
           echo "BRANCH_NAME=${GITHUB_REF##*/}" >> $GITHUB_ENV
           echo "GITHUB_REF"=${GITHUB_REF} >> $GITHUB_ENV
 
-      - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
-        with:
-          python-version: 3.13
-
       - name: Install dependencies
         run: |
           python3 -m pip install --upgrade pip setuptools wheel
diff --git a/Documentation/CRDs/Cluster/ceph-cluster-crd.md b/Documentation/CRDs/Cluster/ceph-cluster-crd.md
index eea150e38..51b4e4fc1 100755
--- a/Documentation/CRDs/Cluster/ceph-cluster-crd.md
+++ b/Documentation/CRDs/Cluster/ceph-cluster-crd.md
@@ -150,13 +150,6 @@ A specific will contain a specific release of Ceph as well as security fixes fro
 * `failureDomainLabel`: The label that is expected on each node where the mons
     are expected to be deployed. The labels must be found in the list of
     well-known [topology labels](#osd-topology).
-* `externalMonIDs`: ID list of external mons deployed outside of Rook cluster
-    and not managed by Rook. If set, Rook will not remove external mons from quorum
-    and populate external mons addresses to mon endpoints for CSI.
-    This parameter is supported only for local Rook cluster running in normal mode,
-    meaning that it will be ignored for external cluster (`spec.external.enabled: true`)
-    or for `stretchedCluster`.
-    For more details see [external mons](../../Storage-Configuration/Advanced/ceph-mon-health.md#external-monitors).
 * `zones`: The failure domain names where the Mons are expected to be deployed.
     There must be **at least three zones** specified in the list. Each zone can be
     backed by a different storage class by specifying the `volumeClaimTemplate`.
diff --git a/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md b/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md
index f04c71013..cd8839836 100644
--- a/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md
+++ b/Documentation/CRDs/Object-Storage/ceph-object-store-crd.md
@@ -390,10 +390,6 @@ spec:
       debug_rgw: "10" # int
       # debug-rgw: "20" # equivalent config keys can have dashes or underscores
       rgw_s3_auth_use_ldap: "true" # bool
-    rgwConfigFromSecret:
-      rgw_keystone_barbican_password: # name of rgw option with secret value
-        name: "barbican-secret" # name of K8s secret 
-        key: "password" # key of secret value in K8s secret.Data map[string]string
     rgwCommandFlags:
       rgw_dmclock_auth_res: "100.0" # float
       rgw_d4n_l1_datacache_persistent_path: /var/log/rook/rgwd4ncache # string
@@ -401,13 +397,12 @@ spec:
 ```
 
 * `rgwConfig` - These configurations are applied and modified at runtime, without RGW restart.
-* `rgwConfigFromSecret` - same as `rgwConfig` but config value is referenced from k8s secret.
 * `rgwCommandFlags` - These configurations are applied as CLI arguments and result in RGW daemons
     restarting when updates are applied. Restarts are desired behavior for some RGW configs.
 
 !!! note
-    Once an `rgwConfig` or `rgwConfigFromSecret` is set, it will not be removed from Ceph's central config store when removed
-    from the `rgwConfig` or `rgwConfigFromSecret` spec. Be sure to specifically set values back to their defaults once done.
+    Once an `rgwConfig` is set, it will not be removed from Ceph's central config store when removed
+    from the `rgwConfig` spec. Be sure to specifically set values back to their defaults once done.
     With this in mind, `rgwCommandFlags` may be a better choice for temporary config values like
     debug levels.
 
@@ -460,34 +455,6 @@ data:
     "bindpass.secret": aGVsbG8ud29ybGQK # hello.world
 ```
 
-### Example - usage with `rgwConfigFromSecret`
-
-The sample configuration below demonstrates how to securely handle secret configuration parameters when setting up RGW for [Barbican integration](https://docs.ceph.com/en/latest/radosgw/config-ref/#barbican-settings).
-
-```yaml
-  # ...
-  gateway:
-    # ...
-    rgwConfig:
-      rgw_barbican_url: "http://barbican.example.com:9311"
-      rgw_keystone_barbican_domain: "domain"
-      rgw_keystone_barbican_project: "project" 
-      rgw_keystone_barbican_user: "user"
-    rgwConfigFromSecret:
-      rgw_keystone_barbican_password:
-        name: "barbican-secret"
-        key: "password"
----
-apiVersion: v1
-kind: Secret
-metadata:
-  name: barbican-secret
-  namespace: rook-ceph
-type: Opaque
-data:
-  "password": aGVsbG8ud29ybGQK # hello.world
-```
-
 ## Deleting a CephObjectStore
 
 During deletion of a CephObjectStore resource, Rook protects against accidental or premature
diff --git a/Documentation/CRDs/specification.md b/Documentation/CRDs/specification.md
index 781234732..99e2000fd 100644
--- a/Documentation/CRDs/specification.md
+++ b/Documentation/CRDs/specification.md
@@ -7203,23 +7203,6 @@ applied. Use with caution.</p>
 </tr>
 <tr>
 <td>
-<code>rgwConfigFromSecret</code><br/>
-<em>
-<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#secretkeyselector-v1-core">
-map[string]k8s.io/api/core/v1.SecretKeySelector
-</a>
-</em>
-</td>
-<td>
-<em>(Optional)</em>
-<p>RgwConfigFromSecret works exactly like RgwConfig but takes config value from Secret Key reference.
-Values are modified at runtime without RGW restart.
-This feature is intended for advanced users. It allows breaking configurations to be easily
-applied. Use with caution.</p>
-</td>
-</tr>
-<tr>
-<td>
 <code>rgwCommandFlags</code><br/>
 <em>
 map[string]string
@@ -8794,22 +8777,6 @@ VolumeClaimTemplate
 <p>VolumeClaimTemplate is the PVC definition</p>
 </td>
 </tr>
-<tr>
-<td>
-<code>externalMonIDs</code><br/>
-<em>
-[]string
-</em>
-</td>
-<td>
-<em>(Optional)</em>
-<p>ExternalMonIDs - optional list of monitor IDs which are deployed externally and not managed by Rook.
-If set, Rook will not remove mons with given IDs from quorum.
-This parameter is used only for local Rook cluster running in normal mode
-and will be ignored if external or stretched mode is used.
-leading</p>
-</td>
-</tr>
 </tbody>
 </table>
 <h3 id="ceph.rook.io/v1.MonZoneSpec">MonZoneSpec
diff --git a/Documentation/Helm-Charts/operator-chart.md b/Documentation/Helm-Charts/operator-chart.md
index d9a5fa281..4307fc083 100644
--- a/Documentation/Helm-Charts/operator-chart.md
+++ b/Documentation/Helm-Charts/operator-chart.md
@@ -66,7 +66,7 @@ The following table lists the configurable parameters of the rook-operator chart
 | `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.repository` | CSIAddons sidecar image repository | `"quay.io/csiaddons/k8s-sidecar"` |
-| `csi.csiAddons.tag` | CSIAddons sidecar image tag | `"v0.12.0"` |
+| `csi.csiAddons.tag` | CSIAddons sidecar image tag | `"v0.11.0"` |
 | `csi.csiAddonsCephFSProvisionerPort` | CSI Addons server port for the Ceph FS provisioner | `9070` |
 | `csi.csiAddonsPort` | CSI Addons server port | `9070` |
 | `csi.csiAddonsRBDProvisionerPort` | CSI Addons server port for the RBD provisioner | `9070` |
diff --git a/Documentation/Storage-Configuration/Advanced/ceph-mon-health.md b/Documentation/Storage-Configuration/Advanced/ceph-mon-health.md
index 5e69b9ac2..f39c931b3 100644
--- a/Documentation/Storage-Configuration/Advanced/ceph-mon-health.md
+++ b/Documentation/Storage-Configuration/Advanced/ceph-mon-health.md
@@ -124,43 +124,3 @@ CephCluster CR:
 - `spec.network.hostNetwork`: When enabled or disabled, Rook fails over all monitors, configuring them to enable or disable host networking.
 - `spec.network.Provider` : When updated from being empty to "host", Rook fails over all monitors, configuring them to enable or disable host networking.
 - `spec.network.multiClusterService`: When enabled or disabled, Rook fails over all monitors, configuring them to start (or stop) using service IPs compatible with the multi-cluster service.
-
-## External Monitors
-
-!!! attention
-    This feature is experimental.
-
-It is possible to have both Rook-managed and external monitors in the same Rook cluster.
-One use case for this is 2 datacenter aka 2-AZ (Availability Zone) setup. For 2-AZ setup, Zone outage will lead to loss of the k8s control plane and half of the worker nodes hosting Rook mons.
-In this case remaining half of the Rook cluster will not be able to form quorum and will be in a stuck state even if the other half of worker nodes are still up.
-To avoid this situation, external mons can be used to form quorum and keep the cluster running.
-
-If there are external monitors, Rook must be aware of them, otherwise Rook will remove the unknown mons from the quorum. This is done by setting the `mon.externalMonIDs` field in the CephCluster CR. The `mon.count` ignores the number of `mon.externalMonIDs`. For example, if `mon.count = 2`, Rook will create two internal mons no matter how many external mons are in the cluster and no matter what their health state might be. External monitors are supported only for the local Rook cluster running in normal mode. The external mons will be ignored for external clusters and stretch clusters.
-
-Here is a step-by-step guide on how to add external monitors to a Rook cluster:
-
-1. Create a CephCluster CR with the `mon.externalMonIDs` field set to the external monitor IDs. For example:
-
-    ```yaml
-    spec:
-      mon:
-        # Spawn 2 Mons - one Mon in each AZ managed by Rook
-        count: 2
-        allowMultiplePerNode: false
-        # ID of external Mon
-        externalMonIDs:
-        - ext-mon-1 
-    ```
-
-    This will tell Rook to create two internal monitors in the cluster and to keep the external monitor with the ID `ext-mon-1` if it is found in the quorum.
-    It is also possible to add `externalMonIDs` to an existing Cluster.
-2. Wait until the Rook cluster and internal mons are up and running.
-3. Manually deploy an external monitor with the ID `ext-mon-1` outside of the Rook cluster and its availability zones. See [ceph guide](https://docs.ceph.com/en/latest/rados/operations/add-or-rm-mons/#adding-removing-monitors) on deploying monitors.
-4. Move the external Mon to [disallow-mode](https://docs.ceph.com/en/reef/rados/operations/change-mon-elections/#rados-operations-disallow-mode) to make sure that it won't be elected as a leader. The purpose of external mode is maintaining quorum to elect a new leader in case of a zone outage. The external Mon will likely have higher latency to the cluster so it should not be elected.
-5. Check that the external monitor is in the quorum by running `ceph status` or `ceph quorum_status` from the toolbox.
-6. Check that the external mon is added to the Rook mon endpoints:
-
-    ```console
-    $ kubectl -n rook-ceph get cm rook-ceph-mon-endpoints -o jsonpath='{.data.data}'
-    a=10.100.68.61:6789,b=10.103.201.172:6789,ext-mon-1=10.102.136.102:6789
-    ```
diff --git a/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md b/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md
index 75f43859c..17ca0d0ac 100644
--- a/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md
+++ b/Documentation/Storage-Configuration/Ceph-CSI/ceph-csi-drivers.md
@@ -166,9 +166,9 @@ that the controller inspects and forwards to one or more CSI-Addons sidecars for
 Deploy the controller by running the following commands:
 
 ```console
-kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.12.0/crds.yaml
-kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.12.0/rbac.yaml
-kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.12.0/setup-controller.yaml
+kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.11.0/crds.yaml
+kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.11.0/rbac.yaml
+kubectl create -f https://github.com/csi-addons/kubernetes-csi-addons/releases/download/v0.11.0/setup-controller.yaml
 ```
 
 This creates the required CRDs and configures permissions.
@@ -196,22 +196,22 @@ Execute the following to enable the CSI-Addons sidecars:
 CSI-Addons supports the following operations:
 
 * Reclaim Space
-    * [Creating a ReclaimSpaceJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#reclaimspacejob)
-    * [Creating a ReclaimSpaceCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#reclaimspacecronjob)
-    * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#annotating-perstentvolumeclaims)
-    * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#annotating-namespace)
-    * [Annotating StorageClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/reclaimspace.md#annotating-storageclass)
+    * [Creating a ReclaimSpaceJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#reclaimspacejob)
+    * [Creating a ReclaimSpaceCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#reclaimspacecronjob)
+    * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#annotating-perstentvolumeclaims)
+    * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#annotating-namespace)
+    * [Annotating StorageClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/reclaimspace.md#annotating-storageclass)
 * Network Fencing
-    * [Creating a NetworkFence](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/networkfence.md)
+    * [Creating a NetworkFence](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/networkfence.md)
 * Volume Replication
-    * [Creating VolumeReplicationClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/volumereplicationclass.md)
-    * [Creating VolumeReplication CR](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/volumereplication.md)
+    * [Creating VolumeReplicationClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/volumereplicationclass.md)
+    * [Creating VolumeReplication CR](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/volumereplication.md)
 * Key Rotation Job for PV encryption
-    * [Creating EncryptionKeyRotationJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#encryptionkeyrotationjob)
-    * [Creating EncryptionKeyRotationCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#encryptionkeyrotationcronjob)
-    * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#annotating-persistentvolumeclaims)
-    * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#annotating-namespace)
-    * [Annotating StorageClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.12.0/docs/encryptionkeyrotation.md#annotating-storageclass)
+    * [Creating EncryptionKeyRotationJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#encryptionkeyrotationjob)
+    * [Creating EncryptionKeyRotationCronJob](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#encryptionkeyrotationcronjob)
+    * [Annotating PersistentVolumeClaims](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#annotating-persistentvolumeclaims)
+    * [Annotating Namespace](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#annotating-namespace)
+    * [Annotating StorageClass](https://github.com/csi-addons/kubernetes-csi-addons/blob/v0.11.0/docs/encryptionkeyrotation.md#annotating-storageclass)
 
 ## Enable RBD and CephFS Encryption Support
 
diff --git a/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md b/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md
index 3e0fffd60..88b5b6840 100644
--- a/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md
+++ b/Documentation/Storage-Configuration/Ceph-CSI/custom-images.md
@@ -24,7 +24,7 @@ ROOK_CSI_PROVISIONER_IMAGE: "registry.k8s.io/sig-storage/csi-provisioner:v5.1.0"
 ROOK_CSI_ATTACHER_IMAGE: "registry.k8s.io/sig-storage/csi-attacher:v4.8.0"
 ROOK_CSI_RESIZER_IMAGE: "registry.k8s.io/sig-storage/csi-resizer:v1.13.1"
 ROOK_CSI_SNAPSHOTTER_IMAGE: "registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0"
-ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.12.0"
+ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.11.0"
 ```
 
 ### **Use private repository**
diff --git a/PendingReleaseNotes.md b/PendingReleaseNotes.md
index faf45c2b6..252f70b28 100644
--- a/PendingReleaseNotes.md
+++ b/PendingReleaseNotes.md
@@ -13,5 +13,3 @@ Object:
     See https://github.com/rook/rook/pull/15376 for more information.
 
 ## Features
-
-- Support external mons for local Rook cluster (see [#14733](https://github.com/rook/rook/issues/14733)).
diff --git a/build/release/Makefile b/build/release/Makefile
index efb068736..e8b592306 100644
--- a/build/release/Makefile
+++ b/build/release/Makefile
@@ -66,10 +66,8 @@ FLAVORS ?= output
 override BRANCH_NAME := pr/$(BRANCH_NAME)
 endif
 
-DOCKER_REGISTRY ?= docker.io/rook
-QUAY_REGISTRY ?= quay.io/rook
-GHCR_REGISTRY ?= ghcr.io/rook
-REGISTRIES ?= $(DOCKER_REGISTRY) $(QUAY_REGISTRY) $(GHCR_REGISTRY)
+DOCKER_REGISTRY ?= rook
+REGISTRIES ?= $(DOCKER_REGISTRY)
 IMAGE_ARCHS := $(subst linux_,,$(filter linux_%,$(PLATFORMS)))
 IMAGE_PLATFORMS := $(subst _,/,$(subst $(SPACE),$(COMMA),$(filter linux_%,$(PLATFORMS))))
 IMAGE_PLATFORMS_COMMA := $(shell echo "$(IMAGE_PLATFORMS)" | sed 's/ /,/g' | sed 's/.$$//')
@@ -193,14 +191,10 @@ $(foreach r,$(REGISTRIES), $(foreach i,$(IMAGES), $(foreach a,$(IMAGE_ARCHS),$(e
 
 publish.manifest.image.%: publish.all.images $(MANIFEST_TOOL)
 	$(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(DOCKER_REGISTRY)/$*-ARCH:$(VERSION) --target $(DOCKER_REGISTRY)/$*:$(VERSION)
-	$(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(QUAY_REGISTRY)/$*-ARCH:$(VERSION) --target $(QUAY_REGISTRY)/$*:$(VERSION)
-	$(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(GHCR_REGISTRY)/$*-ARCH:$(VERSION) --target $(GHCR_REGISTRY)/$*:$(VERSION)
 
 # add the "master" tag to the master image, but do not add the "release" tag for the release channel
 promote.manifest.image.%: promote.all.images $(MANIFEST_TOOL)
 	[ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(DOCKER_REGISTRY)/$*-ARCH:$(VERSION) --target $(DOCKER_REGISTRY)/$*:$(CHANNEL)
-	[ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(QUAY_REGISTRY)/$*-ARCH:$(VERSION) --target $(QUAY_REGISTRY)/$*:$(CHANNEL)
-	[ "$(CHANNEL)" = "release" ] || $(MANIFEST_TOOL) push from-args --platforms $(IMAGE_PLATFORMS_COMMA) --template $(GHCR_REGISTRY)/$*-ARCH:$(VERSION) --target $(GHCR_REGISTRY)/$*:$(CHANNEL)
 
 build.images: build.all.images
 publish.images: $(addprefix publish.manifest.image.,$(IMAGES))
diff --git a/cmd/rook/ceph/mgr.go b/cmd/rook/ceph/mgr.go
index 8b8834de1..372beb449 100644
--- a/cmd/rook/ceph/mgr.go
+++ b/cmd/rook/ceph/mgr.go
@@ -79,7 +79,7 @@ func runMgrSidecar(cmd *cobra.Command, args []string) error {
 	}
 
 	context := createContext()
-	clusterInfo.InternalMonitors = opcontroller.ParseMonEndpoints(cfg.monEndpoints)
+	clusterInfo.Monitors = opcontroller.ParseMonEndpoints(cfg.monEndpoints)
 	rook.LogStartupInfo(mgrSidecarCmd.Flags())
 
 	ownerRef := opcontroller.ClusterOwnerRef(clusterName, ownerRefID)
diff --git a/cmd/rook/ceph/osd.go b/cmd/rook/ceph/osd.go
index c231c4b95..d4f0caf5f 100644
--- a/cmd/rook/ceph/osd.go
+++ b/cmd/rook/ceph/osd.go
@@ -344,7 +344,7 @@ func commonOSDInit(cmd *cobra.Command) {
 	rook.SetLogLevel()
 	rook.LogStartupInfo(cmd.Flags())
 
-	clusterInfo.InternalMonitors = opcontroller.ParseMonEndpoints(cfg.monEndpoints)
+	clusterInfo.Monitors = opcontroller.ParseMonEndpoints(cfg.monEndpoints)
 }
 
 // use zone/region/hostname labels in the crushmap
diff --git a/deploy/charts/rook-ceph/templates/resources.yaml b/deploy/charts/rook-ceph/templates/resources.yaml
index d09b83f03..53a806f02 100644
--- a/deploy/charts/rook-ceph/templates/resources.yaml
+++ b/deploy/charts/rook-ceph/templates/resources.yaml
@@ -1789,16 +1789,6 @@ spec:
                       maximum: 9
                       minimum: 0
                       type: integer
-                    externalMonIDs:
-                      description: |-
-                        ExternalMonIDs - optional list of monitor IDs which are deployed externally and not managed by Rook.
-                        If set, Rook will not remove mons with given IDs from quorum.
-                        This parameter is used only for local Rook cluster running in normal mode
-                        and will be ignored if external or stretched mode is used.
-                        leading
-                      items:
-                        type: string
-                      type: array
                     failureDomainLabel:
                       type: string
                     stretchCluster:
@@ -11963,36 +11953,6 @@ spec:
                         applied. Use with caution.
                       nullable: true
                       type: object
-                    rgwConfigFromSecret:
-                      additionalProperties:
-                        description: SecretKeySelector selects a key of a Secret.
-                        properties:
-                          key:
-                            description: The key of the secret to select from.  Must be a valid secret key.
-                            type: string
-                          name:
-                            default: ""
-                            description: |-
-                              Name of the referent.
-                              This field is effectively required, but due to backwards compatibility is
-                              allowed to be empty. Instances of this type with an empty value here are
-                              almost certainly wrong.
-                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
-                            type: string
-                          optional:
-                            description: Specify whether the Secret or its key must be defined
-                            type: boolean
-                        required:
-                          - key
-                        type: object
-                        x-kubernetes-map-type: atomic
-                      description: |-
-                        RgwConfigFromSecret works exactly like RgwConfig but takes config value from Secret Key reference.
-                        Values are modified at runtime without RGW restart.
-                        This feature is intended for advanced users. It allows breaking configurations to be easily
-                        applied. Use with caution.
-                      nullable: true
-                      type: object
                     securePort:
                       description: The port the rgw service will be listening on (https)
                       format: int32
diff --git a/deploy/charts/rook-ceph/values.yaml b/deploy/charts/rook-ceph/values.yaml
index 19a3729b5..4ce764357 100644
--- a/deploy/charts/rook-ceph/values.yaml
+++ b/deploy/charts/rook-ceph/values.yaml
@@ -539,7 +539,7 @@ csi:
     # -- CSIAddons sidecar image repository
     repository: quay.io/csiaddons/k8s-sidecar
     # -- CSIAddons sidecar image tag
-    tag: v0.12.0
+    tag: v0.11.0
 
   nfs:
     # -- Enable the nfs csi driver
diff --git a/deploy/examples/crds.yaml b/deploy/examples/crds.yaml
index 3f206e8b2..25b576af4 100644
--- a/deploy/examples/crds.yaml
+++ b/deploy/examples/crds.yaml
@@ -1787,16 +1787,6 @@ spec:
                       maximum: 9
                       minimum: 0
                       type: integer
-                    externalMonIDs:
-                      description: |-
-                        ExternalMonIDs - optional list of monitor IDs which are deployed externally and not managed by Rook.
-                        If set, Rook will not remove mons with given IDs from quorum.
-                        This parameter is used only for local Rook cluster running in normal mode
-                        and will be ignored if external or stretched mode is used.
-                        leading
-                      items:
-                        type: string
-                      type: array
                     failureDomainLabel:
                       type: string
                     stretchCluster:
@@ -11954,36 +11944,6 @@ spec:
                         applied. Use with caution.
                       nullable: true
                       type: object
-                    rgwConfigFromSecret:
-                      additionalProperties:
-                        description: SecretKeySelector selects a key of a Secret.
-                        properties:
-                          key:
-                            description: The key of the secret to select from.  Must be a valid secret key.
-                            type: string
-                          name:
-                            default: ""
-                            description: |-
-                              Name of the referent.
-                              This field is effectively required, but due to backwards compatibility is
-                              allowed to be empty. Instances of this type with an empty value here are
-                              almost certainly wrong.
-                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
-                            type: string
-                          optional:
-                            description: Specify whether the Secret or its key must be defined
-                            type: boolean
-                        required:
-                          - key
-                        type: object
-                        x-kubernetes-map-type: atomic
-                      description: |-
-                        RgwConfigFromSecret works exactly like RgwConfig but takes config value from Secret Key reference.
-                        Values are modified at runtime without RGW restart.
-                        This feature is intended for advanced users. It allows breaking configurations to be easily
-                        applied. Use with caution.
-                      nullable: true
-                      type: object
                     securePort:
                       description: The port the rgw service will be listening on (https)
                       format: int32
diff --git a/deploy/examples/create-external-cluster-resources.py b/deploy/examples/create-external-cluster-resources.py
index a2f84eb50..38a567d8d 100644
--- a/deploy/examples/create-external-cluster-resources.py
+++ b/deploy/examples/create-external-cluster-resources.py
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
-        http://www.apache.org/licenses/LICENSE-2.0
+	http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/deploy/examples/images.txt b/deploy/examples/images.txt
index 8e3006e38..53cf473bf 100644
--- a/deploy/examples/images.txt
+++ b/deploy/examples/images.txt
@@ -3,7 +3,7 @@
  quay.io/ceph/ceph:v19.2.1
  quay.io/ceph/cosi:v0.1.2
  quay.io/cephcsi/cephcsi:v3.13.0
- quay.io/csiaddons/k8s-sidecar:v0.12.0
+ quay.io/csiaddons/k8s-sidecar:v0.11.0
  registry.k8s.io/sig-storage/csi-attacher:v4.8.0
  registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.13.0
  registry.k8s.io/sig-storage/csi-provisioner:v5.1.0
diff --git a/deploy/examples/operator-openshift.yaml b/deploy/examples/operator-openshift.yaml
index 27acb6a8a..26eead857 100644
--- a/deploy/examples/operator-openshift.yaml
+++ b/deploy/examples/operator-openshift.yaml
@@ -556,7 +556,7 @@ data:
   CSI_ENABLE_CSIADDONS: "false"
   # Enable watch for faster recovery from rbd rwo node loss
   ROOK_WATCH_FOR_NODE_FAILURE: "true"
-  # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.12.0"
+  # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.11.0"
   # The GCSI RPC 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/deploy/examples/operator.yaml b/deploy/examples/operator.yaml
index 960e94b15..b1fcd62b3 100644
--- a/deploy/examples/operator.yaml
+++ b/deploy/examples/operator.yaml
@@ -511,7 +511,7 @@ data:
   CSI_ENABLE_CSIADDONS: "false"
   # Enable watch for faster recovery from rbd rwo node loss
   ROOK_WATCH_FOR_NODE_FAILURE: "true"
-  # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.12.0"
+  # ROOK_CSIADDONS_IMAGE: "quay.io/csiaddons/k8s-sidecar:v0.11.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/go.mod b/go.mod
index 9f0e2076b..50d847c20 100644
--- a/go.mod
+++ b/go.mod
@@ -45,14 +45,14 @@ require (
 	golang.org/x/sync v0.11.0
 	gopkg.in/ini.v1 v1.67.0
 	gopkg.in/yaml.v2 v2.4.0
-	k8s.io/api v0.32.1
-	k8s.io/apiextensions-apiserver v0.32.1
-	k8s.io/apimachinery v0.32.1
-	k8s.io/cli-runtime v0.32.1
-	k8s.io/client-go v0.32.1
-	k8s.io/cloud-provider v0.32.1
+	k8s.io/api v0.32.2
+	k8s.io/apiextensions-apiserver v0.32.2
+	k8s.io/apimachinery v0.32.2
+	k8s.io/cli-runtime v0.32.2
+	k8s.io/client-go v0.32.2
+	k8s.io/cloud-provider v0.32.2
 	k8s.io/utils v0.0.0-20241210054802-24370beab758
-	sigs.k8s.io/controller-runtime v0.20.1
+	sigs.k8s.io/controller-runtime v0.20.2
 	sigs.k8s.io/mcs-api v0.1.0
 	sigs.k8s.io/yaml v1.4.0
 )
@@ -80,7 +80,7 @@ require (
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/emicklei/go-restful/v3 v3.12.1 // indirect
 	github.com/evanphx/json-patch v5.9.0+incompatible // indirect
-	github.com/evanphx/json-patch/v5 v5.9.0 // indirect
+	github.com/evanphx/json-patch/v5 v5.9.11 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
 	github.com/gemalto/flume v0.13.1 // indirect
diff --git a/go.sum b/go.sum
index f92a4e581..e0cc9991c 100644
--- a/go.sum
+++ b/go.sum
@@ -297,8 +297,8 @@ github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQL
 github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls=
 github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
-github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
-github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
+github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
+github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
 github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
@@ -764,8 +764,8 @@ github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8Ay
 github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
 github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
 github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
-github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
-github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
+github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
+github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -780,8 +780,8 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ
 github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
 github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
 github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
-github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
-github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
+github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
 github.com/openshift/api v0.0.0-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg=
 github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43 h1:3lcB5nqOOfsJzY4JD12AMKyg3+yQhAdJzNDenbmbMQg=
 github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
@@ -1645,15 +1645,15 @@ k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
 k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
 k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8=
 k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg=
-k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
-k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
+k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw=
+k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y=
 k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE=
 k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY=
 k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE=
 k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio=
 k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk=
-k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw=
-k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto=
+k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4=
+k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA=
 k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
 k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
 k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
@@ -1665,14 +1665,14 @@ k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp
 k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
 k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
 k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
-k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
-k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
+k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ=
+k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
 k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
 k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw=
 k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8=
 k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
-k8s.io/cli-runtime v0.32.1 h1:19nwZPlYGJPUDbhAxDIS2/oydCikvKMHsxroKNGA2mM=
-k8s.io/cli-runtime v0.32.1/go.mod h1:NJPbeadVFnV2E7B7vF+FvU09mpwYlZCu8PqjzfuOnkY=
+k8s.io/cli-runtime v0.32.2 h1:aKQR4foh9qeyckKRkNXUccP9moxzffyndZAvr+IXMks=
+k8s.io/cli-runtime v0.32.2/go.mod h1:a/JpeMztz3xDa7GCyyShcwe55p8pbcCVQxvqZnIwXN8=
 k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
 k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
 k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g=
@@ -1681,10 +1681,10 @@ k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA=
 k8s.io/client-go v0.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY=
 k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
 k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4=
-k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
-k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
-k8s.io/cloud-provider v0.32.1 h1:74rRhnfca3o4CsjjnIp/C3ARVuSmyNsxgWPtH0yc9Z0=
-k8s.io/cloud-provider v0.32.1/go.mod h1:GECSanFT+EeZ/ToX3xlasjETzMUI+VFu92zHUDUsGHw=
+k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA=
+k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94=
+k8s.io/cloud-provider v0.32.2 h1:8EC+fCYo0r0REczSjOZcVuQPCMxXxCKlgxDbYMrzC30=
+k8s.io/cloud-provider v0.32.2/go.mod h1:2s8TeAXhVezp5VISaTxM6vW3yDonOZXoN4Aryz1p1PQ=
 k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
 k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
 k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
@@ -1739,8 +1739,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
 sigs.k8s.io/controller-runtime v0.2.2/go.mod h1:9dyohw3ZtoXQuV1e766PHUn+cmrRCIcBh6XIMFNMZ+I=
 sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A=
-sigs.k8s.io/controller-runtime v0.20.1 h1:JbGMAG/X94NeM3xvjenVUaBjy6Ui4Ogd/J5ZtjZnHaE=
-sigs.k8s.io/controller-runtime v0.20.1/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU=
+sigs.k8s.io/controller-runtime v0.20.2 h1:/439OZVxoEc02psi1h4QO3bHzTgu49bb347Xp4gW1pc=
+sigs.k8s.io/controller-runtime v0.20.2/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY=
 sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI=
 sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=
 sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
diff --git a/pkg/apis/ceph.rook.io/v1/types.go b/pkg/apis/ceph.rook.io/v1/types.go
index 538526634..de8c70cce 100755
--- a/pkg/apis/ceph.rook.io/v1/types.go
+++ b/pkg/apis/ceph.rook.io/v1/types.go
@@ -626,13 +626,6 @@ type MonSpec struct {
 	// +kubebuilder:pruning:PreserveUnknownFields
 	// +optional
 	VolumeClaimTemplate *VolumeClaimTemplate `json:"volumeClaimTemplate,omitempty"`
-	// ExternalMonIDs - optional list of monitor IDs which are deployed externally and not managed by Rook.
-	// If set, Rook will not remove mons with given IDs from quorum.
-	// This parameter is used only for local Rook cluster running in normal mode
-	// and will be ignored if external or stretched mode is used.
-	// leading
-	// +optional
-	ExternalMonIDs []string `json:"externalMonIDs,omitempty"`
 }
 
 // VolumeClaimTemplate is a simplified version of K8s corev1's PVC. It has no type meta or status.
@@ -1755,14 +1748,6 @@ type GatewaySpec struct {
 	// +optional
 	RgwConfig map[string]string `json:"rgwConfig,omitempty"`
 
-	// RgwConfigFromSecret works exactly like RgwConfig but takes config value from Secret Key reference.
-	// Values are modified at runtime without RGW restart.
-	// This feature is intended for advanced users. It allows breaking configurations to be easily
-	// applied. Use with caution.
-	// +nullable
-	// +optional
-	RgwConfigFromSecret map[string]v1.SecretKeySelector `json:"rgwConfigFromSecret,omitempty"`
-
 	// RgwCommandFlags sets Ceph RGW config values for the gateway clients that serve this object
 	// store. Values are modified at RGW startup, resulting in RGW pod restarts.
 	// This feature is intended for advanced users. It allows breaking configurations to be easily
diff --git a/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go b/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go
index b3ef8a9a4..90d36b973 100644
--- a/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go
+++ b/pkg/apis/ceph.rook.io/v1/zz_generated.deepcopy.go
@@ -2743,13 +2743,6 @@ func (in *GatewaySpec) DeepCopyInto(out *GatewaySpec) {
 			(*out)[key] = val
 		}
 	}
-	if in.RgwConfigFromSecret != nil {
-		in, out := &in.RgwConfigFromSecret, &out.RgwConfigFromSecret
-		*out = make(map[string]corev1.SecretKeySelector, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
 	if in.RgwCommandFlags != nil {
 		in, out := &in.RgwCommandFlags, &out.RgwCommandFlags
 		*out = make(map[string]string, len(*in))
@@ -3353,11 +3346,6 @@ func (in *MonSpec) DeepCopyInto(out *MonSpec) {
 		*out = new(VolumeClaimTemplate)
 		(*in).DeepCopyInto(*out)
 	}
-	if in.ExternalMonIDs != nil {
-		in, out := &in.ExternalMonIDs, &out.ExternalMonIDs
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
 	return
 }
 
diff --git a/pkg/apis/go.mod b/pkg/apis/go.mod
index 93888c7e0..a56a5ca9c 100644
--- a/pkg/apis/go.mod
+++ b/pkg/apis/go.mod
@@ -22,8 +22,8 @@ require (
 	github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43
 	github.com/pkg/errors v0.9.1
 	github.com/stretchr/testify v1.10.0
-	k8s.io/api v0.32.1
-	k8s.io/apimachinery v0.32.1
+	k8s.io/api v0.32.2
+	k8s.io/apimachinery v0.32.2
 )
 
 require (
@@ -63,6 +63,8 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+	github.com/onsi/ginkgo/v2 v2.22.0 // indirect
+	github.com/onsi/gomega v1.36.1 // indirect
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
 	github.com/ryanuber/go-glob v1.0.0 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
@@ -79,7 +81,7 @@ require (
 	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/client-go v0.32.1 // indirect
+	k8s.io/client-go v0.32.2 // indirect
 	k8s.io/klog/v2 v2.130.1 // indirect
 	k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect
 	k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
diff --git a/pkg/apis/go.sum b/pkg/apis/go.sum
index a9c792c87..c774f55b6 100644
--- a/pkg/apis/go.sum
+++ b/pkg/apis/go.sum
@@ -607,8 +607,8 @@ github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8Ay
 github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
 github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
 github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
-github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
-github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
+github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
+github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -622,8 +622,8 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ
 github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
 github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
 github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
-github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
-github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
+github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
 github.com/openshift/api v0.0.0-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg=
 github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43 h1:3lcB5nqOOfsJzY4JD12AMKyg3+yQhAdJzNDenbmbMQg=
 github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
@@ -1405,8 +1405,8 @@ k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
 k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
 k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8=
 k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg=
-k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
-k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
+k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw=
+k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y=
 k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE=
 k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE=
 k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk=
@@ -1419,8 +1419,8 @@ k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRp
 k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
 k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
 k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
-k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
-k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
+k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ=
+k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
 k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw=
 k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
 k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
@@ -1429,8 +1429,8 @@ k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA=
 k8s.io/client-go v0.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY=
 k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
 k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4=
-k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
-k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
+k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA=
+k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94=
 k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
 k8s.io/code-generator v0.19.0/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk=
 k8s.io/code-generator v0.20.0/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
diff --git a/pkg/daemon/ceph/client/config.go b/pkg/daemon/ceph/client/config.go
index 278c37445..f2cc6119b 100644
--- a/pkg/daemon/ceph/client/config.go
+++ b/pkg/daemon/ceph/client/config.go
@@ -249,7 +249,7 @@ func PopulateMonHostMembers(clusterInfo *ClusterInfo) ([]string, []string) {
 	var monMembers []string
 	var monHosts []string
 
-	for _, monitor := range clusterInfo.AllMonitors() {
+	for _, monitor := range clusterInfo.Monitors {
 		if monitor.OutOfQuorum {
 			logger.Warningf("skipping adding mon %q to config file, detected out of quorum", monitor.Name)
 			continue
diff --git a/pkg/daemon/ceph/client/info.go b/pkg/daemon/ceph/client/info.go
index 79d273471..70e49bc48 100644
--- a/pkg/daemon/ceph/client/info.go
+++ b/pkg/daemon/ceph/client/info.go
@@ -39,13 +39,10 @@ type ClusterInfo struct {
 	FSID          string
 	MonitorSecret string
 	CephCred      CephCred
-	// InternalMonitors - montiros managed by Rook or external monitors when Rook manages external cluster.
-	InternalMonitors map[string]*MonInfo
-	// ExternalMons - external montiros listed in CephCluster.spec.mon.externalMonIDs when Rook managing local cluster.
-	ExternalMons map[string]*MonInfo
-	CephVersion  cephver.CephVersion
-	Namespace    string
-	OwnerInfo    *k8sutil.OwnerInfo
+	Monitors      map[string]*MonInfo
+	CephVersion   cephver.CephVersion
+	Namespace     string
+	OwnerInfo     *k8sutil.OwnerInfo
 	// Hide the name of the cluster since in 99% of uses we want to use the cluster namespace.
 	// If the CR name is needed, access it through the NamespacedName() method.
 	name              string
@@ -62,20 +59,6 @@ type ClusterInfo struct {
 	Context context.Context
 }
 
-func (c *ClusterInfo) AllMonitors() map[string]*MonInfo {
-	if len(c.ExternalMons) == 0 {
-		return c.InternalMonitors
-	}
-	res := make(map[string]*MonInfo, len(c.InternalMonitors)+len(c.ExternalMons))
-	for id, mon := range c.InternalMonitors {
-		res[id] = mon
-	}
-	for id, mon := range c.ExternalMons {
-		res[id] = mon
-	}
-	return res
-}
-
 // MonInfo is a collection of information about a Ceph mon.
 type MonInfo struct {
 	Name     string `json:"name"`
diff --git a/pkg/daemon/ceph/client/mirror.go b/pkg/daemon/ceph/client/mirror.go
index a0795c892..d9c2dc8a8 100644
--- a/pkg/daemon/ceph/client/mirror.go
+++ b/pkg/daemon/ceph/client/mirror.go
@@ -441,7 +441,7 @@ func CreateRBDMirrorBootstrapPeerWithoutPool(context *clusterd.Context, clusterI
 	logger.Infof("successfully created rbd-mirror bootstrap peer token for cluster %q", clusterInfo.NamespacedName().Name)
 
 	mons := sets.New[string]()
-	for _, mon := range clusterInfo.AllMonitors() {
+	for _, mon := range clusterInfo.Monitors {
 		mons.Insert(mon.Endpoint)
 	}
 
diff --git a/pkg/operator/ceph/cluster/cluster_external.go b/pkg/operator/ceph/cluster/cluster_external.go
index b9b14121b..37f825263 100644
--- a/pkg/operator/ceph/cluster/cluster_external.go
+++ b/pkg/operator/ceph/cluster/cluster_external.go
@@ -109,7 +109,7 @@ func (c *ClusterController) configureExternalCephCluster(cluster *cluster) error
 	}
 
 	// update the msgr2 flag
-	for _, m := range cluster.ClusterInfo.InternalMonitors {
+	for _, m := range cluster.ClusterInfo.Monitors {
 		// m.Endpoint=10.1.115.104:3300
 		monPort := util.GetPortFromEndpoint(m.Endpoint)
 		if monPort == client.Msgr2port {
@@ -123,7 +123,7 @@ func (c *ClusterController) configureExternalCephCluster(cluster *cluster) error
 	}
 
 	// Save CSI configmap
-	monEndpoints := csi.MonEndpoints(cluster.ClusterInfo.InternalMonitors, cluster.Spec.RequireMsgr2())
+	monEndpoints := csi.MonEndpoints(cluster.ClusterInfo.Monitors, cluster.Spec.RequireMsgr2())
 	csiConfigEntry := &csi.CSIClusterConfigEntry{
 		Namespace: cluster.ClusterInfo.Namespace,
 		ClusterInfo: cephcsi.ClusterInfo{
diff --git a/pkg/operator/ceph/cluster/mon/health.go b/pkg/operator/ceph/cluster/mon/health.go
index fe1042ae8..050d88f43 100644
--- a/pkg/operator/ceph/cluster/mon/health.go
+++ b/pkg/operator/ceph/cluster/mon/health.go
@@ -1,4 +1,5 @@
-/* Copyright 2018 The Rook Authors. All rights reserved.
+/*
+Copyright 2018 The Rook Authors. All rights reserved.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
@@ -19,7 +20,6 @@ import (
 	"context"
 	"fmt"
 	"os"
-	"slices"
 	"strings"
 	"time"
 
@@ -202,12 +202,6 @@ func (c *Cluster) checkHealth(ctx context.Context) error {
 	}
 	logger.Debugf("Mon quorum status: %+v", quorumStatus)
 
-	// handle external Mons
-	quorumStatus, err = c.reconcileExternalMons(ctx, quorumStatus)
-	if err != nil {
-		return errors.Wrap(err, "failed to check external mons health")
-	}
-
 	// Use a local mon count in case the user updates the crd in another goroutine.
 	// We need to complete a health check with a consistent value.
 	desiredMonCount := c.spec.Mon.Count
@@ -215,7 +209,7 @@ func (c *Cluster) checkHealth(ctx context.Context) error {
 
 	// Source of truth of which mons should exist is our *clusterInfo*
 	monsNotFound := map[string]interface{}{}
-	for _, mon := range c.ClusterInfo.InternalMonitors {
+	for _, mon := range c.ClusterInfo.Monitors {
 		monsNotFound[mon.Name] = struct{}{}
 	}
 
@@ -320,7 +314,7 @@ func (c *Cluster) checkHealth(ctx context.Context) error {
 	// handle all mons that haven't been in the Ceph mon map
 	for mon := range monsNotFound {
 		logger.Warningf("mon %s NOT found in ceph mon map, failover", mon)
-		c.failMon(len(c.ClusterInfo.InternalMonitors), desiredMonCount, mon)
+		c.failMon(len(c.ClusterInfo.Monitors), desiredMonCount, mon)
 		// only deal with one "not found in ceph mon map" mon per health check
 		return nil
 	}
@@ -357,24 +351,24 @@ func (c *Cluster) checkHealth(ctx context.Context) error {
 
 	// failover mon if `multiClusterService` is enabled but mon service is not exported
 	if allMonsInQuorum && c.spec.Network.MultiClusterService.Enabled {
-		for _, mon := range c.ClusterInfo.InternalMonitors {
+		for _, mon := range c.ClusterInfo.Monitors {
 			monResourceName := resourceName(mon.Name)
 			isAlreadyExported, err := k8sutil.IsServiceExported(c.ClusterInfo.Context, c.context, monResourceName, c.ClusterInfo.Namespace)
 			if err != nil {
 				return errors.Wrapf(err, "failed to check if the service %q is already exported", mon.Name)
 			}
 			if !isAlreadyExported {
-				c.failMon(len(c.ClusterInfo.InternalMonitors), desiredMonCount, mon.Name)
+				c.failMon(len(c.ClusterInfo.Monitors), desiredMonCount, mon.Name)
 				return nil
 			}
 		}
 	}
 
 	// failover any mons present in the mon fail over list
-	for _, mon := range c.ClusterInfo.InternalMonitors {
+	for _, mon := range c.ClusterInfo.Monitors {
 		if c.monsToFailover.Has(mon.Name) {
 			logger.Infof("fail over mon %q from the mon fail over list", mon.Name)
-			c.failMon(len(c.ClusterInfo.InternalMonitors), desiredMonCount, mon.Name)
+			c.failMon(len(c.ClusterInfo.Monitors), desiredMonCount, mon.Name)
 			c.monsToFailover.Delete(mon.Name)
 			return nil
 		}
@@ -383,102 +377,12 @@ func (c *Cluster) checkHealth(ctx context.Context) error {
 	return nil
 }
 
-// reconcileExternalMons handling external monitors defined in CephCluster.spec.mon.externalMonIDs when Rook managing local cluster.
-func (c *Cluster) reconcileExternalMons(ctx context.Context, quorumStatus cephclient.MonStatusResponse) (cephclient.MonStatusResponse, error) {
-	if len(c.spec.Mon.ExternalMonIDs) != 0 {
-		if c.spec.External.Enable {
-			logger.Warning("ignore external mon IDs in cluster spec: cluster is running in external mode")
-			return quorumStatus, nil
-		}
-		if c.spec.IsStretchCluster() {
-			logger.Warning("ignore external mon IDs in cluster spec: cluster is running in stretch mode")
-			return quorumStatus, nil
-		}
-	}
-
-	extMonIDs := c.spec.Mon.ExternalMonIDs
-	if c.ClusterInfo.ExternalMons == nil {
-		c.ClusterInfo.ExternalMons = make(map[string]*cephclient.MonInfo, len(extMonIDs))
-	}
-
-	extMonsChanged := false
-	for extID := range c.ClusterInfo.ExternalMons {
-		if slices.Contains(extMonIDs, extID) {
-			continue
-		}
-		// existing external mon was removed from Cluster CRD spec:
-		// remove it from CLusterInfo
-		logger.Debugf("existing external mon %q was removed from spec: removing it", extID)
-		delete(c.ClusterInfo.ExternalMons, extID)
-		extMonsChanged = true
-	}
-
-	// handle external monitors if configured in cluster CRD:
-	logger.Debugf("external mon IDs: %v", extMonIDs)
-	for _, extID := range extMonIDs {
-		monStatus, inQuorum := getMonByID(extID, quorumStatus)
-		if inQuorum {
-			logger.Debugf("external mon %q in quorum", extID)
-		} else {
-			logger.Debugf("external mon %q not in quorum %+v, %+v", extID, quorumStatus.Quorum, quorumStatus.MonMap.Mons)
-		}
-		_, inInfo := c.ClusterInfo.ExternalMons[extID]
-		if inQuorum && !inInfo {
-			// add newly discovered external mon to cluster info:
-			monInfo := monStatusToInfo(monStatus)
-			c.ClusterInfo.ExternalMons[extID] = monInfo
-			extMonsChanged = true
-			logger.Infof("new external mon %q found: %s, adding it", extID, monInfo.Endpoint)
-		} else if !inQuorum && inInfo {
-			// remove external mon from cluster info if it is out of quorum:
-			delete(c.ClusterInfo.ExternalMons, extID)
-			extMonsChanged = true
-			logger.Infof("new external mon %q not in quorum: removing it", extID)
-		}
-	}
-	if extMonsChanged {
-		// update config if external mon was removed or added:
-		if err := c.saveMonConfig(); err != nil {
-			return cephclient.MonStatusResponse{}, errors.Wrap(err, "failed to save mon config after adding/removing external mon")
-		}
-	}
-
-	// now, remove processed external mons from ceph quorum status response
-	// to not affect existing logic processing internal mons that are within the mon.count
-	quorumStatus = removeMonsFromQuorumStatusResponse(quorumStatus, extMonIDs)
-	return quorumStatus, nil
-}
-
-func removeMonsFromQuorumStatusResponse(quorumStatus cephclient.MonStatusResponse, idsToRemove []string) cephclient.MonStatusResponse {
-	var removeFromQuorum []int
-	var keepMons []cephclient.MonMapEntry
-
-	for _, mon := range quorumStatus.MonMap.Mons {
-		if !slices.Contains(idsToRemove, mon.Name) {
-			keepMons = append(keepMons, mon)
-			continue
-		}
-		removeFromQuorum = append(removeFromQuorum, mon.Rank)
-	}
-
-	var keepQuorum []int
-	for _, rank := range quorumStatus.Quorum {
-		if slices.Contains(removeFromQuorum, rank) {
-			continue
-		}
-		keepQuorum = append(keepQuorum, rank)
-	}
-	quorumStatus.MonMap.Mons = keepMons
-	quorumStatus.Quorum = keepQuorum
-	return quorumStatus
-}
-
 func (c *Cluster) trackMonInOrOutOfQuorum(monName string, inQuorum bool) (bool, error) {
 	updateNeeded := false
 	var monsOutOfQuorum []string
 	if monName == "" {
 		// All mons are in quorum, so make sure no mons are marked out of quorum
-		for monName, mon := range c.ClusterInfo.InternalMonitors {
+		for monName, mon := range c.ClusterInfo.Monitors {
 			if mon.OutOfQuorum {
 				logger.Infof("resetting mon %q to be back in quorum", monName)
 				mon.OutOfQuorum = false
@@ -486,7 +390,7 @@ func (c *Cluster) trackMonInOrOutOfQuorum(monName string, inQuorum bool) (bool,
 			}
 		}
 	} else {
-		mon, ok := c.ClusterInfo.InternalMonitors[monName]
+		mon, ok := c.ClusterInfo.Monitors[monName]
 		if !ok {
 			logger.Infof("mon %q not found to keep track of being out of quorum", monName)
 			return false, nil
@@ -771,7 +675,7 @@ func (c *Cluster) failoverMon(name string) error {
 			m.PublicIP = monService.Spec.ClusterIP
 		}
 	}
-	c.ClusterInfo.InternalMonitors[m.DaemonName] = cephclient.NewMonInfo(m.DaemonName, m.PublicIP, m.Port)
+	c.ClusterInfo.Monitors[m.DaemonName] = cephclient.NewMonInfo(m.DaemonName, m.PublicIP, m.Port)
 
 	// Start the deployment
 	newMonMightBeInQuorum = true
@@ -813,7 +717,7 @@ func (c *Cluster) removeMonWithOptionalQuorum(daemonName string, shouldRemoveFro
 			logger.Errorf("failed to remove mon %q from quorum. %v", daemonName, err)
 		}
 	}
-	delete(c.ClusterInfo.InternalMonitors, daemonName)
+	delete(c.ClusterInfo.Monitors, daemonName)
 	delete(c.mapping.Schedule, daemonName)
 
 	if err := c.saveMonConfig(); err != nil {
@@ -909,9 +813,9 @@ func (c *Cluster) addOrRemoveExternalMonitor(status cephclient.MonStatusResponse
 	// clearing the content of clusterinfo monitors
 	// and populate oldClusterInfoMonitors with monitors from clusterinfo
 	// later c.ClusterInfo.Monitors get populated again
-	for monName, mon := range c.ClusterInfo.InternalMonitors {
+	for monName, mon := range c.ClusterInfo.Monitors {
 		oldClusterInfoMonitors[mon.Name] = mon
-		delete(c.ClusterInfo.InternalMonitors, monName)
+		delete(c.ClusterInfo.Monitors, monName)
 	}
 	logger.Debugf("ClusterInfo is now Empty, refilling it from status.MonMap.Mons")
 
@@ -927,9 +831,17 @@ func (c *Cluster) addOrRemoveExternalMonitor(status cephclient.MonStatusResponse
 		if _, ok := oldClusterInfoMonitors[mon.Name]; !ok {
 			// If the mon is part of the quorum
 			if inQuorum {
-				info := monStatusToInfo(mon)
-				logger.Infof("new external mon %q found: %s, adding it", mon.Name, info.Endpoint)
-				c.ClusterInfo.InternalMonitors[mon.Name] = info
+				// let's add it to ClusterInfo
+				// FYI mon.PublicAddr is "10.97.171.131:6789/0"
+				// so we need to remove '/0'
+				endpointSlash := strings.Split(mon.PublicAddr, "/")
+				endpoint := endpointSlash[0]
+
+				// find IP and Port of that Mon
+				monIP := cephutil.GetIPFromEndpoint(endpoint)
+				monPort := cephutil.GetPortFromEndpoint(endpoint)
+				logger.Infof("new external mon %q found: %s, adding it", mon.Name, endpoint)
+				c.ClusterInfo.Monitors[mon.Name] = cephclient.NewMonInfo(mon.Name, monIP, monPort)
 			} else {
 				logger.Debugf("mon %q is not in quorum and not in ClusterInfo", mon.Name)
 			}
@@ -945,7 +857,7 @@ func (c *Cluster) addOrRemoveExternalMonitor(status cephclient.MonStatusResponse
 			} else {
 				// this mon was in clusterInfo and is still in the quorum
 				// add it again
-				c.ClusterInfo.InternalMonitors[mon.Name] = oldClusterInfoMonitors[mon.Name]
+				c.ClusterInfo.Monitors[mon.Name] = oldClusterInfoMonitors[mon.Name]
 				logger.Debugf("everything is fine mon %q in the clusterInfo and its quorum status is %v", mon.Name, inQuorum)
 			}
 		}
@@ -953,33 +865,20 @@ func (c *Cluster) addOrRemoveExternalMonitor(status cephclient.MonStatusResponse
 	// compare old clusterInfo with new ClusterInfo
 	// if length differ -> the are different
 	// then check if all elements are the same
-	if len(oldClusterInfoMonitors) != len(c.ClusterInfo.InternalMonitors) {
+	if len(oldClusterInfoMonitors) != len(c.ClusterInfo.Monitors) {
 		changed = true
 	} else {
-		for _, mon := range c.ClusterInfo.InternalMonitors {
+		for _, mon := range c.ClusterInfo.Monitors {
 			if old, ok := oldClusterInfoMonitors[mon.Name]; !ok || *old != *mon {
 				changed = true
 			}
 		}
 	}
 
-	logger.Debugf("ClusterInfo.Monitors is %+v", c.ClusterInfo.InternalMonitors)
+	logger.Debugf("ClusterInfo.Monitors is %+v", c.ClusterInfo.Monitors)
 	return changed, nil
 }
 
-func monStatusToInfo(mon cephclient.MonMapEntry) *cephclient.MonInfo {
-	// let's add it to ClusterInfo
-	// FYI mon.PublicAddr is "10.97.171.131:6789/0"
-	// so we need to remove '/0'
-	endpointSlash := strings.Split(mon.PublicAddr, "/")
-	endpoint := endpointSlash[0]
-
-	// find IP and Port of that Mon
-	monIP := cephutil.GetIPFromEndpoint(endpoint)
-	monPort := cephutil.GetPortFromEndpoint(endpoint)
-	return cephclient.NewMonInfo(mon.Name, monIP, monPort)
-}
-
 func (c *Cluster) evictMonIfMultipleOnSameNode() error {
 	if c.spec.Mon.AllowMultiplePerNode {
 		logger.Debug("skipping check for multiple mons on same node since multiple mons are allowed")
diff --git a/pkg/operator/ceph/cluster/mon/mon.go b/pkg/operator/ceph/cluster/mon/mon.go
index 4d059b39c..df8fc7ff3 100644
--- a/pkg/operator/ceph/cluster/mon/mon.go
+++ b/pkg/operator/ceph/cluster/mon/mon.go
@@ -58,8 +58,6 @@ const (
 	EndpointConfigMapName = "rook-ceph-mon-endpoints"
 	// EndpointDataKey is the name of the key inside the mon configmap to get the endpoints
 	EndpointDataKey = "data"
-	// EndpointExternalMonsKey key in EndpointConfigMapName configmap containing IDs of external mons
-	EndpointExternalMonsKey = "externalMons"
 	// AppName is the name of the secret storing cluster mon.admin key, fsid and name
 	AppName = "rook-ceph-mon"
 	//nolint:gosec // OperatorCreds is the name of the secret
@@ -305,7 +303,7 @@ func (c *Cluster) startMons(targetCount int) error {
 		}
 	}
 
-	logger.Debugf("mon endpoints used are: %s", flattenMonEndpoints(c.ClusterInfo.AllMonitors()))
+	logger.Debugf("mon endpoints used are: %s", flattenMonEndpoints(c.ClusterInfo.Monitors))
 
 	// reconcile mon PDB
 	if err := c.reconcileMonPDB(); err != nil {
@@ -486,7 +484,7 @@ func (c *Cluster) ensureMonsRunning(mons []*monConfig, i, targetCount int, requi
 	// Calculate how many mons we expected to exist after this method is completed.
 	// If we are adding a new mon, we expect one more than currently exist.
 	// If we haven't created all the desired mons already, we will be adding a new one with this iteration
-	expectedMonCount := len(c.ClusterInfo.InternalMonitors)
+	expectedMonCount := len(c.ClusterInfo.Monitors)
 	if expectedMonCount < targetCount {
 		expectedMonCount++
 	}
@@ -550,12 +548,13 @@ func (c *Cluster) initClusterInfo(cephVersion cephver.CephVersion, clusterName s
 }
 
 func (c *Cluster) initMonConfig(size int) (int, []*monConfig, error) {
+
 	// initialize the mon pod info for mons that have been previously created
 	mons := c.clusterInfoToMonConfig()
 
 	// initialize mon info if we don't have enough mons (at first startup)
-	existingCount := len(c.ClusterInfo.InternalMonitors)
-	for i := len(c.ClusterInfo.InternalMonitors); i < size; i++ {
+	existingCount := len(c.ClusterInfo.Monitors)
+	for i := len(c.ClusterInfo.Monitors); i < size; i++ {
 		c.maxMonID++
 		zone, err := c.findAvailableZone(mons)
 		if err != nil {
@@ -573,7 +572,7 @@ func (c *Cluster) clusterInfoToMonConfig() []*monConfig {
 
 func (c *Cluster) clusterInfoToMonConfigWithExclude(excludedMon string) []*monConfig {
 	mons := []*monConfig{}
-	for _, monitor := range c.ClusterInfo.InternalMonitors {
+	for _, monitor := range c.ClusterInfo.Monitors {
 		if monitor.Name == excludedMon {
 			// Skip a mon if it is being failed over
 			continue
@@ -852,7 +851,7 @@ func (c *Cluster) initMonIPs(mons []*monConfig) error {
 				}
 			}
 		}
-		c.ClusterInfo.InternalMonitors[m.DaemonName] = cephclient.NewMonInfo(m.DaemonName, m.PublicIP, m.Port)
+		c.ClusterInfo.Monitors[m.DaemonName] = cephclient.NewMonInfo(m.DaemonName, m.PublicIP, m.Port)
 	}
 
 	return nil
@@ -1161,7 +1160,7 @@ func (c *Cluster) saveMonConfig() error {
 		return errors.Wrap(err, "failed to write connection config for new mons")
 	}
 
-	monEndpoints := csi.MonEndpoints(c.ClusterInfo.AllMonitors(), c.spec.RequireMsgr2())
+	monEndpoints := csi.MonEndpoints(c.ClusterInfo.Monitors, c.spec.RequireMsgr2())
 	csiConfigEntry := &csi.CSIClusterConfigEntry{
 		Namespace: c.ClusterInfo.Namespace,
 		ClusterInfo: cephcsi.ClusterInfo{
@@ -1174,7 +1173,7 @@ func (c *Cluster) saveMonConfig() error {
 		return errors.Wrap(err, "failed to update csi cluster config")
 	}
 
-	if csi.EnableCSIOperator() && len(c.ClusterInfo.AllMonitors()) > 0 {
+	if csi.EnableCSIOperator() && len(c.ClusterInfo.Monitors) > 0 {
 		err := csi.CreateUpdateCephConnection(c.context.Client, c.ClusterInfo, c.spec)
 		if err != nil {
 			return errors.Wrap(err, "failed to create/update cephConnection")
@@ -1208,7 +1207,7 @@ func (c *Cluster) persistExpectedMonDaemons() error {
 	}
 
 	csiConfigValue, err := csi.FormatCsiClusterConfig(
-		c.Namespace, c.ClusterInfo.AllMonitors())
+		c.Namespace, c.ClusterInfo.Monitors)
 	if err != nil {
 		return errors.Wrap(err, "failed to format csi config")
 	}
@@ -1220,21 +1219,14 @@ func (c *Cluster) persistExpectedMonDaemons() error {
 
 	// preserve the mons detected out of quorum
 	var monsOutOfQuorum []string
-	for monName, mon := range c.ClusterInfo.InternalMonitors {
+	for monName, mon := range c.ClusterInfo.Monitors {
 		if mon.OutOfQuorum {
 			monsOutOfQuorum = append(monsOutOfQuorum, monName)
 		}
 	}
-	extMonIDs := make([]string, 0, len(c.ClusterInfo.ExternalMons))
-	if c.ClusterInfo.ExternalMons != nil {
-		for monID := range c.ClusterInfo.ExternalMons {
-			extMonIDs = append(extMonIDs, monID)
-		}
-	}
 
 	configMap.Data = map[string]string{
-		EndpointDataKey:         flattenMonEndpoints(c.ClusterInfo.AllMonitors()),
-		EndpointExternalMonsKey: strings.Join(extMonIDs, ","),
+		EndpointDataKey: flattenMonEndpoints(c.ClusterInfo.Monitors),
 		// persist the maxMonID that was previously stored in the configmap. We are likely saving info
 		// about scheduling of the mons, but we only want to update the maxMonID once a new mon has
 		// actually been started. If the operator is restarted or the reconcile is otherwise restarted,
diff --git a/pkg/operator/ceph/cluster/mon/util.go b/pkg/operator/ceph/cluster/mon/util.go
index 39b20e582..f688a3794 100644
--- a/pkg/operator/ceph/cluster/mon/util.go
+++ b/pkg/operator/ceph/cluster/mon/util.go
@@ -17,7 +17,6 @@ limitations under the License.
 package mon
 
 import (
-	"slices"
 	"strings"
 
 	"github.com/rook/rook/pkg/daemon/ceph/client"
@@ -35,17 +34,6 @@ func monInQuorum(monitor client.MonMapEntry, quorum []int) bool {
 	return false
 }
 
-func getMonByID(monID string, monMap client.MonStatusResponse) (info client.MonMapEntry, inQuorum bool) {
-	for _, mon := range monMap.MonMap.Mons {
-		if mon.Name != monID {
-			continue
-		}
-		monRank := mon.Rank
-		return mon, slices.Contains(monMap.Quorum, monRank)
-	}
-	return client.MonMapEntry{}, false
-}
-
 // convert the mon name to the numeric mon ID
 func fullNameToIndex(name string) (int, error) {
 	// remove the "rook-ceph-mon" prefix
diff --git a/pkg/operator/ceph/cluster/nodedaemon/exporter.go b/pkg/operator/ceph/cluster/nodedaemon/exporter.go
index 8fb73b621..cbd0495e5 100644
--- a/pkg/operator/ceph/cluster/nodedaemon/exporter.go
+++ b/pkg/operator/ceph/cluster/nodedaemon/exporter.go
@@ -198,11 +198,6 @@ func getCephExporterDaemonContainer(cephCluster cephv1.CephCluster, cephVersion
 		args = append(args, "--addrs", "::")
 	}
 
-	containerPort := corev1.ContainerPort{
-		ContainerPort: int32(DefaultMetricsPort),
-		Protocol:      corev1.ProtocolTCP,
-	}
-
 	container := corev1.Container{
 		Name:            "ceph-exporter",
 		Command:         []string{"ceph-exporter"},
@@ -210,7 +205,6 @@ func getCephExporterDaemonContainer(cephCluster cephv1.CephCluster, cephVersion
 		Image:           cephImage,
 		ImagePullPolicy: controller.GetContainerImagePullPolicy(cephCluster.Spec.CephVersion.ImagePullPolicy),
 		Env:             envVars,
-		Ports:           []corev1.ContainerPort{containerPort},
 		VolumeMounts:    volumeMounts,
 		Resources:       cephv1.GetCephExporterResources(cephCluster.Spec.Resources),
 		SecurityContext: controller.PodSecurityContext(),
diff --git a/pkg/operator/ceph/controller/cluster_info.go b/pkg/operator/ceph/controller/cluster_info.go
index 7a4d3851d..2da3191ca 100644
--- a/pkg/operator/ceph/controller/cluster_info.go
+++ b/pkg/operator/ceph/controller/cluster_info.go
@@ -23,7 +23,6 @@ import (
 	"os"
 	"path"
 	"path/filepath"
-	"slices"
 	"strconv"
 	"strings"
 	"time"
@@ -57,8 +56,6 @@ const (
 	EndpointConfigMapName = "rook-ceph-mon-endpoints"
 	// EndpointDataKey is the name of the key inside the mon configmap to get the endpoints
 	EndpointDataKey = "data"
-	// EndpointExternalMonsKey key in EndpointConfigMapName configmap containing IDs of external mons
-	EndpointExternalMonsKey = "externalMons"
 	// OutOfQuorumKey is the name of the key for tracking mons detected out of quorum
 	OutOfQuorumKey = "outOfQuorum"
 	// MaxMonIDKey is the name of the max mon id used
@@ -151,7 +148,7 @@ func CreateOrLoadClusterInfo(clusterdContext *clusterd.Context, context context.
 	}
 
 	// get the existing monitor config
-	clusterInfo.ExternalMons, clusterInfo.InternalMonitors, maxMonID, monMapping, err = loadMonConfig(clusterdContext.Clientset, namespace)
+	clusterInfo.Monitors, maxMonID, monMapping, err = loadMonConfig(clusterdContext.Clientset, namespace)
 	if err != nil {
 		return nil, maxMonID, monMapping, errors.Wrap(err, "failed to get mon config")
 	}
@@ -279,34 +276,33 @@ func UpdateMonsOutOfQuorum(clientset kubernetes.Interface, namespace string, mon
 }
 
 // loadMonConfig returns the monitor endpoints and maxMonID
-func loadMonConfig(clientset kubernetes.Interface, namespace string) (extMons map[string]*cephclient.MonInfo, internalMons map[string]*cephclient.MonInfo, maxMonID int, monMapping *Mapping, err error) {
+func loadMonConfig(clientset kubernetes.Interface, namespace string) (map[string]*cephclient.MonInfo, int, *Mapping, error) {
 	ctx := context.TODO()
-	extMons = map[string]*cephclient.MonInfo{}
-	internalMons = map[string]*cephclient.MonInfo{}
-	maxMonID = -1
-	monMapping = &Mapping{
+	monEndpointMap := map[string]*cephclient.MonInfo{}
+	maxMonID := -1
+	monMapping := &Mapping{
 		Schedule: map[string]*MonScheduleInfo{},
 	}
 
 	cm, err := clientset.CoreV1().ConfigMaps(namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
 	if err != nil {
 		if !kerrors.IsNotFound(err) {
-			return nil, nil, maxMonID, monMapping, err
+			return nil, maxMonID, monMapping, err
 		}
 		// If the config map was not found, initialize the empty set of monitors
-		return extMons, internalMons, maxMonID, monMapping, nil
+		return monEndpointMap, maxMonID, monMapping, nil
 	}
 
 	// Parse the monitor List
 	if info, ok := cm.Data[EndpointDataKey]; ok {
-		internalMons = ParseMonEndpoints(info)
+		monEndpointMap = ParseMonEndpoints(info)
 	}
 
 	// Parse the mons that were detected out of quorum
 	if outOfQuorum, ok := cm.Data[OutOfQuorumKey]; ok && len(outOfQuorum) > 0 {
 		monNames := strings.Split(outOfQuorum, ",")
 		for _, monName := range monNames {
-			if monInfo, ok := internalMons[monName]; ok {
+			if monInfo, ok := monEndpointMap[monName]; ok {
 				monInfo.OutOfQuorum = true
 			} else {
 				logger.Warningf("did not find mon %q to set it out of quorum in the cluster info", monName)
@@ -326,7 +322,7 @@ func loadMonConfig(clientset kubernetes.Interface, namespace string) (extMons ma
 	}
 
 	// Make sure the max id is consistent with the current monitors
-	for _, m := range internalMons {
+	for _, m := range monEndpointMap {
 		id, _ := fullNameToIndex(m.Name)
 		if maxMonID < id {
 			maxMonID = id
@@ -340,19 +336,9 @@ func loadMonConfig(clientset kubernetes.Interface, namespace string) (extMons ma
 	if err != nil {
 		logger.Errorf("invalid JSON in mon mapping. %v", err)
 	}
-	// filter external mons:
-	if extMonIDsStr, ok := cm.Data[EndpointExternalMonsKey]; ok && extMonIDsStr != "" {
-		extMonIDs := strings.Split(extMonIDsStr, ",")
-		for monID, mon := range internalMons {
-			if slices.Contains(extMonIDs, monID) {
-				extMons[monID] = mon
-				delete(internalMons, monID)
-			}
-		}
-	}
 
-	logger.Debugf("loaded: maxMonID=%d, extMons=%+v, mons=%+v, assignment=%+v", maxMonID, extMons, internalMons, monMapping)
-	return extMons, internalMons, maxMonID, monMapping, nil
+	logger.Debugf("loaded: maxMonID=%d, mons=%+v, assignment=%+v", maxMonID, monEndpointMap, monMapping)
+	return monEndpointMap, maxMonID, monMapping, nil
 }
 
 // convert the mon name to the numeric mon ID
@@ -427,7 +413,7 @@ func PopulateExternalClusterInfo(cephClusterSpec *cephv1.ClusterSpec, context *c
 			time.Sleep(externalConnectionRetry)
 			continue
 		}
-		logger.Infof("found the cluster info to connect to the external cluster. will use %q to check health and monitor status. mons=%+v", clusterInfo.CephCred.Username, clusterInfo.AllMonitors())
+		logger.Infof("found the cluster info to connect to the external cluster. will use %q to check health and monitor status. mons=%+v", clusterInfo.CephCred.Username, clusterInfo.Monitors)
 		clusterInfo.OwnerInfo = ownerInfo
 
 		return clusterInfo, nil
diff --git a/pkg/operator/ceph/csi/ceph_connection.go b/pkg/operator/ceph/csi/ceph_connection.go
index 61d89c57b..518b09d2f 100644
--- a/pkg/operator/ceph/csi/ceph_connection.go
+++ b/pkg/operator/ceph/csi/ceph_connection.go
@@ -91,7 +91,7 @@ func generateCephConnSpec(c client.Client, clusterInfo *cephclient.ClusterInfo,
 		csiClusterConnSpec.RbdMirrorDaemonCount = cephRBDMirrorList.Items[0].Spec.Count
 	}
 
-	for _, mon := range clusterInfo.AllMonitors() {
+	for _, mon := range clusterInfo.Monitors {
 		csiClusterConnSpec.Monitors = append(csiClusterConnSpec.Monitors, mon.Endpoint)
 	}
 
diff --git a/pkg/operator/ceph/csi/spec.go b/pkg/operator/ceph/csi/spec.go
index 3bdde58e5..5b968453f 100644
--- a/pkg/operator/ceph/csi/spec.go
+++ b/pkg/operator/ceph/csi/spec.go
@@ -139,7 +139,7 @@ var (
 	DefaultAttacherImage    = "registry.k8s.io/sig-storage/csi-attacher:v4.8.0"
 	DefaultSnapshotterImage = "registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0"
 	DefaultResizerImage     = "registry.k8s.io/sig-storage/csi-resizer:v1.13.1"
-	DefaultCSIAddonsImage   = "quay.io/csiaddons/k8s-sidecar:v0.12.0"
+	DefaultCSIAddonsImage   = "quay.io/csiaddons/k8s-sidecar:v0.11.0"
 
 	// image pull policy
 	DefaultCSIImagePullPolicy = string(corev1.PullIfNotPresent)
diff --git a/pkg/operator/ceph/file/subvolumegroup/controller.go b/pkg/operator/ceph/file/subvolumegroup/controller.go
index 2969f00b7..e5605785a 100644
--- a/pkg/operator/ceph/file/subvolumegroup/controller.go
+++ b/pkg/operator/ceph/file/subvolumegroup/controller.go
@@ -298,7 +298,7 @@ func (r *ReconcileCephFilesystemSubVolumeGroup) updateClusterConfig(cephFilesyst
 	csiClusterConfigEntry := csi.CSIClusterConfigEntry{
 		Namespace: r.clusterInfo.Namespace,
 		ClusterInfo: cephcsi.ClusterInfo{
-			Monitors: csi.MonEndpoints(r.clusterInfo.AllMonitors(), cephCluster.Spec.RequireMsgr2()),
+			Monitors: csi.MonEndpoints(r.clusterInfo.Monitors, cephCluster.Spec.RequireMsgr2()),
 			CephFS: cephcsi.CephFS{
 				SubvolumeGroup:     getSubvolumeGroupName(cephFilesystemSubVolumeGroup),
 				KernelMountOptions: r.clusterInfo.CSIDriverSpec.CephFS.KernelMountOptions,
diff --git a/pkg/operator/ceph/object/config.go b/pkg/operator/ceph/object/config.go
index dad9879c6..8c3608f2b 100644
--- a/pkg/operator/ceph/object/config.go
+++ b/pkg/operator/ceph/object/config.go
@@ -27,7 +27,6 @@ import (
 	cephconfig "github.com/rook/rook/pkg/operator/ceph/config"
 	"github.com/rook/rook/pkg/operator/ceph/config/keyring"
 	v1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 const (
@@ -216,38 +215,12 @@ func (c *clusterConfig) generateMonConfigOptions(rgwConfig *rgwConfig) (map[stri
 	for flag, val := range c.store.Spec.Gateway.RgwConfig {
 		if currVal, ok := configOptions[flag]; ok {
 			// RGW might break with some user-specified config overrides; log clearly to help triage
-			logger.Infof("overriding object store %q RGW config option %q with user-specified rgwConfig",
-				fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag)
-			logger.Tracef("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfig %q",
+			logger.Infof("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfig %q",
 				fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, currVal, val)
 		}
 		configOptions[flag] = val
 	}
 
-	for flag, val := range c.store.Spec.Gateway.RgwConfigFromSecret {
-		if val.Key == "" || val.Name == "" {
-			return nil, fmt.Errorf("invalid object store %q rgwConfigFromSecret value %q=%+v", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, val)
-		}
-		secret, err := c.context.Clientset.CoreV1().Secrets(c.clusterInfo.Namespace).Get(c.clusterInfo.Context, val.Name, metav1.GetOptions{})
-		if err != nil {
-			return nil, fmt.Errorf("unable to lookup secret for object store %q rgwConfigFromSecret %q=%+v", fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, val)
-		}
-		secretVal, ok := secret.Data[val.Key]
-		if !ok {
-			return nil, fmt.Errorf("unable to lookup secret for object store %q rgwConfigFromSecret %q: key %q not found in secret %q",
-				fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, val.Key, val.Name)
-		}
-
-		if currVal, ok := configOptions[flag]; ok {
-			// RGW might break with some user-specified config overrides; log clearly to help triage
-			logger.Infof("overriding object store %q RGW config option %q with user-specified rgwConfigFromSecret",
-				fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag)
-			logger.Tracef("overriding object store %q RGW config option %q (current value %q) with user-specified rgwConfigFromSecret %q",
-				fmt.Sprintf("%s/%s", c.store.Namespace, c.store.Name), flag, currVal, secretVal)
-		}
-		configOptions[flag] = string(secretVal)
-	}
-
 	return configOptions, nil
 }
 
diff --git a/pkg/operator/ceph/pool/radosnamespace/controller.go b/pkg/operator/ceph/pool/radosnamespace/controller.go
index 14974bdf6..bbac0c9cc 100644
--- a/pkg/operator/ceph/pool/radosnamespace/controller.go
+++ b/pkg/operator/ceph/pool/radosnamespace/controller.go
@@ -323,7 +323,7 @@ func (r *ReconcileCephBlockPoolRadosNamespace) updateClusterConfig(cephBlockPool
 	csiClusterConfigEntry := csi.CSIClusterConfigEntry{
 		Namespace: r.clusterInfo.Namespace,
 		ClusterInfo: cephcsi.ClusterInfo{
-			Monitors: csi.MonEndpoints(r.clusterInfo.AllMonitors(), cephCluster.Spec.RequireMsgr2()),
+			Monitors: csi.MonEndpoints(r.clusterInfo.Monitors, cephCluster.Spec.RequireMsgr2()),
 			RBD: cephcsi.RBD{
 				RadosNamespace: getRadosNamespaceName(cephBlockPoolRadosNamespace),
 			},


Test patch:
diff --git a/deploy/examples/create-external-cluster-resources-tests.py b/deploy/examples/create-external-cluster-resources-tests.py
index 8c1feecf9..b3a5196c7 100644
--- a/deploy/examples/create-external-cluster-resources-tests.py
+++ b/deploy/examples/create-external-cluster-resources-tests.py
@@ -3,7 +3,7 @@ Copyright 2022 The Rook Authors. All rights reserved.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
-        http://www.apache.org/licenses/LICENSE-2.0
+	http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/pkg/daemon/ceph/client/config_test.go b/pkg/daemon/ceph/client/config_test.go
index cf7810312..cfb2afa20 100644
--- a/pkg/daemon/ceph/client/config_test.go
+++ b/pkg/daemon/ceph/client/config_test.go
@@ -37,7 +37,7 @@ func TestCreateDefaultCephConfig(t *testing.T) {
 		FSID:          "id",
 		MonitorSecret: "monsecret",
 		Namespace:     "foo-cluster",
-		InternalMonitors: map[string]*MonInfo{
+		Monitors: map[string]*MonInfo{
 			"node0": {Name: "mon0", Endpoint: "10.0.0.1:6789"},
 			"node1": {Name: "mon1", Endpoint: "10.0.0.2:6789"},
 		},
@@ -89,7 +89,7 @@ func TestGenerateConfigFile(t *testing.T) {
 		FSID:          "myfsid",
 		MonitorSecret: "monsecret",
 		Namespace:     ns,
-		InternalMonitors: map[string]*MonInfo{
+		Monitors: map[string]*MonInfo{
 			"node0": {Name: "mon0", Endpoint: "10.0.0.1:6789"},
 		},
 		CephCred: CephCred{Username: "admin", Secret: "mysecret"},
@@ -112,9 +112,9 @@ func TestGenerateConfigFile(t *testing.T) {
 }
 
 func verifyConfig(t *testing.T, cephConfig *CephConfig, cluster *ClusterInfo, loggingLevel int) {
-	monMembers := make([]string, len(cluster.InternalMonitors))
+	monMembers := make([]string, len(cluster.Monitors))
 	i := 0
-	for _, expectedMon := range cluster.InternalMonitors {
+	for _, expectedMon := range cluster.Monitors {
 		contained := false
 		monMembers[i] = expectedMon.Name
 		for _, actualMon := range strings.Split(cephConfig.MonMembers, " ") {
diff --git a/pkg/daemon/ceph/client/test/info.go b/pkg/daemon/ceph/client/test/info.go
index c5081e243..4aaa57ac3 100644
--- a/pkg/daemon/ceph/client/test/info.go
+++ b/pkg/daemon/ceph/client/test/info.go
@@ -51,15 +51,14 @@ func CreateTestClusterInfo(monCount int) *client.ClusterInfo {
 			Username: client.AdminUsername,
 			Secret:   "adminkey",
 		},
-		InternalMonitors: map[string]*client.MonInfo{},
-		ExternalMons:     map[string]*client.MonInfo{},
-		OwnerInfo:        ownerInfo,
-		Context:          context.TODO(),
+		Monitors:  map[string]*client.MonInfo{},
+		OwnerInfo: ownerInfo,
+		Context:   context.TODO(),
 	}
 	mons := []string{"a", "b", "c", "d", "e"}
 	for i := 0; i < monCount; i++ {
 		id := mons[i]
-		c.InternalMonitors[id] = &client.MonInfo{
+		c.Monitors[id] = &client.MonInfo{
 			Name:     id,
 			Endpoint: fmt.Sprintf("1.2.3.%d:3300", (i + 1)),
 		}
diff --git a/pkg/operator/ceph/cluster/mon/health_test.go b/pkg/operator/ceph/cluster/mon/health_test.go
index 5a9452a75..90a778dbc 100644
--- a/pkg/operator/ceph/cluster/mon/health_test.go
+++ b/pkg/operator/ceph/cluster/mon/health_test.go
@@ -29,7 +29,6 @@ import (
 	cephclient "github.com/rook/rook/pkg/daemon/ceph/client"
 	clienttest "github.com/rook/rook/pkg/daemon/ceph/client/test"
 	"github.com/rook/rook/pkg/operator/ceph/config"
-	"github.com/rook/rook/pkg/operator/ceph/controller"
 	opcontroller "github.com/rook/rook/pkg/operator/ceph/controller"
 	testopk8s "github.com/rook/rook/pkg/operator/k8sutil/test"
 	"github.com/rook/rook/pkg/operator/test"
@@ -75,7 +74,7 @@ func TestCheckHealth(t *testing.T) {
 	assert.NotNil(t, err)
 
 	c.spec.Mon.Count = 3
-	logger.Infof("initial mons: %v", c.ClusterInfo.InternalMonitors)
+	logger.Infof("initial mons: %v", c.ClusterInfo.Monitors)
 	c.waitForStart = false
 
 	c.mapping.Schedule["f"] = &opcontroller.MonScheduleInfo{
@@ -93,7 +92,7 @@ func TestCheckHealth(t *testing.T) {
 	c.ClusterInfo.Context = ctx
 	err = c.checkHealth(ctx)
 	assert.Nil(t, err)
-	logger.Infof("mons after checkHealth: %v", c.ClusterInfo.InternalMonitors)
+	logger.Infof("mons after checkHealth: %v", c.ClusterInfo.Monitors)
 	assert.ElementsMatch(t, []string{"rook-ceph-mon-a", "rook-ceph-mon-f"}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
 	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
 
@@ -106,8 +105,8 @@ func TestCheckHealth(t *testing.T) {
 		"g",
 	}
 	for _, monName := range newMons {
-		_, ok := c.ClusterInfo.InternalMonitors[monName]
-		assert.True(t, ok, fmt.Sprintf("mon %s not found in monitor list. %v", monName, c.ClusterInfo.InternalMonitors))
+		_, ok := c.ClusterInfo.Monitors[monName]
+		assert.True(t, ok, fmt.Sprintf("mon %s not found in monitor list. %v", monName, c.ClusterInfo.Monitors))
 	}
 
 	deployments, err := clientset.AppsV1().Deployments(c.Namespace).List(ctx, metav1.ListOptions{})
@@ -154,7 +153,7 @@ func TestCheckHealth(t *testing.T) {
 func TestRemoveExtraMon(t *testing.T) {
 	endpoint := "1.2.3.4:6789"
 	c := &Cluster{mapping: &opcontroller.Mapping{}}
-	c.ClusterInfo = &cephclient.ClusterInfo{InternalMonitors: map[string]*cephclient.MonInfo{
+	c.ClusterInfo = &cephclient.ClusterInfo{Monitors: map[string]*cephclient.MonInfo{
 		"a": {Name: "a", Endpoint: endpoint},
 		"b": {Name: "b", Endpoint: endpoint},
 		"c": {Name: "c", Endpoint: endpoint},
@@ -183,7 +182,7 @@ func TestRemoveExtraMon(t *testing.T) {
 		{Name: "y"},
 		{Name: "z"},
 	}}
-	c.ClusterInfo.InternalMonitors["e"] = &cephclient.MonInfo{Name: "e", Endpoint: endpoint}
+	c.ClusterInfo.Monitors["e"] = &cephclient.MonInfo{Name: "e", Endpoint: endpoint}
 	c.mapping.Schedule["a"].Zone = "x"
 	c.mapping.Schedule["b"].Zone = "y"
 	c.mapping.Schedule["c"].Zone = "y"
@@ -219,7 +218,7 @@ func TestTrackMonsOutOfQuorum(t *testing.T) {
 		context:   &clusterd.Context{Clientset: clientset, ConfigDir: tempDir},
 		ownerInfo: ownerInfo,
 		Namespace: "ns"}
-	c.ClusterInfo = &cephclient.ClusterInfo{InternalMonitors: map[string]*cephclient.MonInfo{
+	c.ClusterInfo = &cephclient.ClusterInfo{Monitors: map[string]*cephclient.MonInfo{
 		"a": {Name: "a", Endpoint: endpoint},
 		"b": {Name: "b", Endpoint: endpoint},
 		"c": {Name: "c", Endpoint: endpoint},
@@ -324,7 +323,7 @@ func TestScaleMonDeployment(t *testing.T) {
 
 	name := "a"
 	c.spec.Mon.Count = 3
-	logger.Infof("initial mons: %v", c.ClusterInfo.InternalMonitors[name])
+	logger.Infof("initial mons: %v", c.ClusterInfo.Monitors[name])
 	monConfig := &monConfig{ResourceName: resourceName(name), DaemonName: name, DataPathMap: &config.DataPathMap{}}
 	d, err := c.makeDeployment(monConfig, false)
 	require.NoError(t, err)
@@ -438,7 +437,7 @@ func TestAddRemoveMons(t *testing.T) {
 	// checking the health will increase the mons as desired all in one go
 	err := c.checkHealth(ctx)
 	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors), fmt.Sprintf("mons: %v", c.ClusterInfo.InternalMonitors))
+	assert.Equal(t, 5, len(c.ClusterInfo.Monitors), fmt.Sprintf("mons: %v", c.ClusterInfo.Monitors))
 	assert.ElementsMatch(t, []string{
 		// b is created first, no updates
 		"rook-ceph-mon-b",                    // b updated when c created
@@ -449,39 +448,39 @@ func TestAddRemoveMons(t *testing.T) {
 	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
 
 	// reducing the mon count to 3 will reduce the mon count once each time we call checkHealth
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors)
+	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.Monitors)
 	c.spec.Mon.Count = 3
 	err = c.checkHealth(ctx)
 	assert.Nil(t, err)
-	assert.Equal(t, 4, len(c.ClusterInfo.InternalMonitors))
+	assert.Equal(t, 4, len(c.ClusterInfo.Monitors))
 	// No updates in unit tests w/ workaround
 	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
 	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
 
 	// after the second call we will be down to the expected count of 3
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors)
+	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.Monitors)
 	err = c.checkHealth(ctx)
 	assert.Nil(t, err)
-	assert.Equal(t, 3, len(c.ClusterInfo.InternalMonitors))
+	assert.Equal(t, 3, len(c.ClusterInfo.Monitors))
 	// No updates in unit tests w/ workaround
 	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
 	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
 
 	// now attempt to reduce the mons down to quorum size 1
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors)
+	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.Monitors)
 	c.spec.Mon.Count = 1
 	err = c.checkHealth(ctx)
 	assert.Nil(t, err)
-	assert.Equal(t, 2, len(c.ClusterInfo.InternalMonitors))
+	assert.Equal(t, 2, len(c.ClusterInfo.Monitors))
 	// No updates in unit tests w/ workaround
 	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
 	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
 
 	// cannot reduce from quorum size of 2 to 1
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors)
+	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.Monitors)
 	err = c.checkHealth(ctx)
 	assert.Nil(t, err)
-	assert.Equal(t, 2, len(c.ClusterInfo.InternalMonitors))
+	assert.Equal(t, 2, len(c.ClusterInfo.Monitors))
 	// No updates in unit tests w/ workaround
 	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
 	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
@@ -512,7 +511,7 @@ func TestAddOrRemoveExternalMonitor(t *testing.T) {
 	changed, err = c.addOrRemoveExternalMonitor(fakeResp)
 	assert.NoError(t, err)
 	assert.False(t, changed)
-	assert.Equal(t, 1, len(c.ClusterInfo.InternalMonitors))
+	assert.Equal(t, 1, len(c.ClusterInfo.Monitors))
 
 	//
 	// TEST 2
@@ -525,7 +524,7 @@ func TestAddOrRemoveExternalMonitor(t *testing.T) {
 	assert.NoError(t, err)
 	assert.True(t, changed)
 	// ClusterInfo should shrink to 1
-	assert.Equal(t, 1, len(c.ClusterInfo.InternalMonitors))
+	assert.Equal(t, 1, len(c.ClusterInfo.Monitors))
 
 	//
 	// TEST 3
@@ -546,7 +545,7 @@ func TestAddOrRemoveExternalMonitor(t *testing.T) {
 	assert.NoError(t, err)
 	assert.True(t, changed)
 	// ClusterInfo should now have 2 monitors
-	assert.Equal(t, 2, len(c.ClusterInfo.InternalMonitors))
+	assert.Equal(t, 2, len(c.ClusterInfo.Monitors))
 }
 
 func TestNewHealthChecker(t *testing.T) {
@@ -611,522 +610,3 @@ func TestUpdateMonInterval(t *testing.T) {
 		assert.Equal(t, time.Minute, h.interval)
 	})
 }
-
-func Test_removeMonsFromQuorumStatusResponse(t *testing.T) {
-	type args struct {
-		quorumStatus cephclient.MonStatusResponse
-		idsToRemove  []string
-	}
-	tests := []struct {
-		name string
-		args args
-		want cephclient.MonStatusResponse
-	}{
-		{
-			name: "remove one mon",
-			args: args{
-				quorumStatus: cephclient.MonStatusResponse{
-					Quorum: []int{0, 1, 2},
-					MonMap: struct {
-						Mons []cephclient.MonMapEntry `json:"mons"`
-					}{
-						Mons: []cephclient.MonMapEntry{
-							{
-								Name: "a",
-								Rank: 0,
-							},
-							{
-								Name: "b",
-								Rank: 1,
-							},
-							{
-								Name: "c",
-								Rank: 2,
-							},
-						},
-					},
-				},
-				idsToRemove: []string{"b"},
-			},
-			want: cephclient.MonStatusResponse{
-				Quorum: []int{0, 2},
-				MonMap: struct {
-					Mons []cephclient.MonMapEntry `json:"mons"`
-				}{
-					Mons: []cephclient.MonMapEntry{
-						{
-							Name: "a",
-							Rank: 0,
-						},
-						{
-							Name: "c",
-							Rank: 2,
-						},
-					},
-				},
-			},
-		},
-		{
-			name: "not remove if not present",
-			args: args{
-				quorumStatus: cephclient.MonStatusResponse{
-					Quorum: []int{0, 1, 2},
-					MonMap: struct {
-						Mons []cephclient.MonMapEntry `json:"mons"`
-					}{
-						Mons: []cephclient.MonMapEntry{
-							{
-								Name: "a",
-								Rank: 0,
-							},
-							{
-								Name: "b",
-								Rank: 1,
-							},
-							{
-								Name: "c",
-								Rank: 2,
-							},
-						},
-					},
-				},
-				idsToRemove: []string{"e"},
-			},
-			want: cephclient.MonStatusResponse{
-				Quorum: []int{0, 1, 2},
-				MonMap: struct {
-					Mons []cephclient.MonMapEntry `json:"mons"`
-				}{
-					Mons: []cephclient.MonMapEntry{
-						{
-							Name: "a",
-							Rank: 0,
-						},
-						{
-							Name: "b",
-							Rank: 1,
-						},
-						{
-							Name: "c",
-							Rank: 2,
-						},
-					},
-				},
-			},
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := removeMonsFromQuorumStatusResponse(tt.args.quorumStatus, tt.args.idsToRemove); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("removeMonsFromQuorumStatusResponse() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestExternalMons_notInSpec_InQuorum(t *testing.T) {
-	// 1. setup test
-	ctx := context.TODO()
-	var deploymentsUpdated *[]*apps.Deployment
-	updateDeploymentAndWait, deploymentsUpdated = testopk8s.UpdateDeploymentAndWaitStub()
-
-	monQuorumResponse := clienttest.MonInQuorumResponse()
-	executor := &exectest.MockExecutor{
-		MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
-			logger.Infof("executing command: %s %+v", command, args)
-			if args[0] == "auth" && args[1] == "get-or-create-key" {
-				return "{\"key\":\"mysecurekey\"}", nil
-			}
-			return monQuorumResponse, nil
-		},
-	}
-	clientset := test.New(t, 1)
-	configDir := t.TempDir()
-	context := &clusterd.Context{
-		Clientset: clientset,
-		ConfigDir: configDir,
-		Executor:  executor,
-	}
-	ownerInfo := cephclient.NewMinimumOwnerInfoWithOwnerRef()
-	c := New(ctx, context, "ns", cephv1.ClusterSpec{}, ownerInfo)
-	setCommonMonProperties(c, 0, cephv1.MonSpec{Count: 5, AllowMultiplePerNode: true}, "myversion")
-	c.maxMonID = 0 // "a" is max mon id
-	c.waitForStart = false
-
-	// checking the health will increase the mons as desired all in one go
-	err := c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors), fmt.Sprintf("mons: %v", c.ClusterInfo.InternalMonitors))
-	assert.ElementsMatch(t, []string{
-		// b is created first, no updates
-		"rook-ceph-mon-b",                    // b updated when c created
-		"rook-ceph-mon-b", "rook-ceph-mon-c", // b and c updated when d created
-		"rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", // etc.
-		"rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", "rook-ceph-mon-e"},
-		testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	inital5Mons := make(map[string]*cephclient.MonInfo)
-	for k, v := range c.ClusterInfo.InternalMonitors {
-		inital5Mons[k] = v
-	}
-
-	// 2. add external mon to quorum but not in spec:
-
-	mons := make(map[string]*cephclient.MonInfo)
-	for k, v := range inital5Mons {
-		mons[k] = v
-	}
-	// add unknown mon to quorum:
-	mons["ext-mon-id"] = &cephclient.MonInfo{Name: "ext-mon-id", Endpoint: "0.0.0.0:6789"}
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(mons)
-
-	// internal mons and deployments has not changed
-	// and unknown mon was removed from quorum
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors))
-	assert.Empty(t, c.ClusterInfo.ExternalMons)
-
-	// No updates in unit tests w/ workaround
-	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that unknown mon is not in endpoint configmap
-	cm, err := c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Empty(t, cm.Data[EndpointExternalMonsKey])
-	monsFromCM := controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 5)
-	for id, mon := range monsFromCM {
-		assert.Equal(t, inital5Mons[id].Name, mon.Name)
-		assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint)
-		assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum)
-	}
-
-	// 3. downscale mons to 4:
-	c.spec.Mon.Count = 4
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors)
-
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	// todo fix
-	assert.Equal(t, 4, len(c.ClusterInfo.InternalMonitors))
-	assert.Empty(t, c.ClusterInfo.ExternalMons)
-	// No updates in unit tests w/ workaround
-	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that unknown mon is not in endpoint configmap
-	cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Empty(t, cm.Data[EndpointExternalMonsKey])
-	monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 4)
-	for id, mon := range monsFromCM {
-		assert.Equal(t, inital5Mons[id].Name, mon.Name)
-		assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint)
-		assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum)
-	}
-
-	// 4. upscale back to 5:
-	c.spec.Mon.Count = 5
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors)
-
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors))
-	assert.Empty(t, c.ClusterInfo.ExternalMons)
-	// No updates in unit tests w/ workaround
-	assert.Len(t, testopk8s.DeploymentNamesUpdated(deploymentsUpdated), 4)
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that unknown mon is not in endpoint configmap
-	cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Empty(t, cm.Data[EndpointExternalMonsKey])
-	monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 5)
-	for id, mon := range monsFromCM {
-		assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Name, mon.Name)
-		assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Endpoint, mon.Endpoint)
-		assert.Equal(t, c.ClusterInfo.InternalMonitors[id].OutOfQuorum, mon.OutOfQuorum)
-	}
-
-}
-
-func TestExternalMons_inSpec_notInQuorum(t *testing.T) {
-	// 1. setup test
-	ctx := context.TODO()
-	var deploymentsUpdated *[]*apps.Deployment
-	updateDeploymentAndWait, deploymentsUpdated = testopk8s.UpdateDeploymentAndWaitStub()
-
-	monQuorumResponse := clienttest.MonInQuorumResponse()
-	executor := &exectest.MockExecutor{
-		MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
-			logger.Infof("executing command: %s %+v", command, args)
-			if args[0] == "auth" && args[1] == "get-or-create-key" {
-				return "{\"key\":\"mysecurekey\"}", nil
-			}
-			return monQuorumResponse, nil
-		},
-	}
-	clientset := test.New(t, 1)
-	configDir := t.TempDir()
-	context := &clusterd.Context{
-		Clientset: clientset,
-		ConfigDir: configDir,
-		Executor:  executor,
-	}
-	ownerInfo := cephclient.NewMinimumOwnerInfoWithOwnerRef()
-	c := New(ctx, context, "ns", cephv1.ClusterSpec{}, ownerInfo)
-	setCommonMonProperties(c, 0, cephv1.MonSpec{Count: 5, AllowMultiplePerNode: true}, "myversion")
-	c.maxMonID = 0 // "a" is max mon id
-	c.waitForStart = false
-
-	// checking the health will increase the mons as desired all in one go
-	err := c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors), fmt.Sprintf("mons: %v", c.ClusterInfo.InternalMonitors))
-	assert.ElementsMatch(t, []string{
-		// b is created first, no updates
-		"rook-ceph-mon-b",                    // b updated when c created
-		"rook-ceph-mon-b", "rook-ceph-mon-c", // b and c updated when d created
-		"rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", // etc.
-		"rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", "rook-ceph-mon-e"},
-		testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	inital5Mons := make(map[string]*cephclient.MonInfo)
-	for k, v := range c.ClusterInfo.InternalMonitors {
-		inital5Mons[k] = v
-	}
-
-	// 2. add external mon id to spec but not to quorum
-	c.spec.Mon.ExternalMonIDs = []string{"ext-mon-id"}
-
-	// don't add ext mon to quorum:
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(inital5Mons)
-
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors))
-	assert.Empty(t, c.ClusterInfo.ExternalMons)
-
-	// No updates in unit tests w/ workaround
-	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that unknown mon is not in endpoint configmap
-	cm, err := c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Empty(t, cm.Data[EndpointExternalMonsKey])
-	monsFromCM := controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 5)
-	for id, mon := range monsFromCM {
-		assert.Equal(t, inital5Mons[id].Name, mon.Name)
-		assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint)
-		assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum)
-	}
-
-	// 3. downscale mons to 4:
-	c.spec.Mon.Count = 4
-
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 4, len(c.ClusterInfo.InternalMonitors))
-	assert.Empty(t, c.ClusterInfo.ExternalMons)
-	// No updates in unit tests w/ workaround
-	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that unknown mon is not in endpoint configmap
-	cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Empty(t, cm.Data[EndpointExternalMonsKey])
-	monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 4)
-	for id, mon := range monsFromCM {
-		assert.Equal(t, inital5Mons[id].Name, mon.Name)
-		assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint)
-		assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum)
-	}
-
-	// 4. upscale back to 5:
-	c.spec.Mon.Count = 5
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(c.ClusterInfo.InternalMonitors)
-
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors))
-	assert.Empty(t, c.ClusterInfo.ExternalMons)
-	// No updates in unit tests w/ workaround
-	assert.Len(t, testopk8s.DeploymentNamesUpdated(deploymentsUpdated), 4)
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that unknown mon is not in endpoint configmap
-	cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Empty(t, cm.Data[EndpointExternalMonsKey])
-	monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 5)
-	for id, mon := range monsFromCM {
-		assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Name, mon.Name)
-		assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Endpoint, mon.Endpoint)
-		assert.Equal(t, c.ClusterInfo.InternalMonitors[id].OutOfQuorum, mon.OutOfQuorum)
-	}
-
-}
-
-func TestExternalMons_inSpec_inQuorum(t *testing.T) {
-	// 1. setup test
-	ctx := context.TODO()
-	var deploymentsUpdated *[]*apps.Deployment
-	updateDeploymentAndWait, deploymentsUpdated = testopk8s.UpdateDeploymentAndWaitStub()
-
-	monQuorumResponse := clienttest.MonInQuorumResponse()
-	executor := &exectest.MockExecutor{
-		MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
-			logger.Infof("executing command: %s %+v", command, args)
-			if args[0] == "auth" && args[1] == "get-or-create-key" {
-				return "{\"key\":\"mysecurekey\"}", nil
-			}
-			return monQuorumResponse, nil
-		},
-	}
-	clientset := test.New(t, 1)
-	configDir := t.TempDir()
-	context := &clusterd.Context{
-		Clientset: clientset,
-		ConfigDir: configDir,
-		Executor:  executor,
-	}
-	ownerInfo := cephclient.NewMinimumOwnerInfoWithOwnerRef()
-	c := New(ctx, context, "ns", cephv1.ClusterSpec{}, ownerInfo)
-	setCommonMonProperties(c, 0, cephv1.MonSpec{Count: 5, AllowMultiplePerNode: true}, "myversion")
-	c.maxMonID = 0 // "a" is max mon id
-	c.waitForStart = false
-
-	// checking the health will increase the mons as desired all in one go
-	err := c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors), fmt.Sprintf("mons: %v", c.ClusterInfo.InternalMonitors))
-	assert.ElementsMatch(t, []string{
-		// b is created first, no updates
-		"rook-ceph-mon-b",                    // b updated when c created
-		"rook-ceph-mon-b", "rook-ceph-mon-c", // b and c updated when d created
-		"rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", // etc.
-		"rook-ceph-mon-b", "rook-ceph-mon-c", "rook-ceph-mon-d", "rook-ceph-mon-e"},
-		testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	inital5Mons := make(map[string]*cephclient.MonInfo)
-	for k, v := range c.ClusterInfo.InternalMonitors {
-		inital5Mons[k] = v
-	}
-
-	// 2. add external mon id to spec
-	c.spec.Mon.ExternalMonIDs = []string{"ext-mon-id"}
-
-	// add ext mon to quorum:
-	mons := make(map[string]*cephclient.MonInfo)
-	for k, v := range inital5Mons {
-		mons[k] = v
-	}
-	mons["ext-mon-id"] = &cephclient.MonInfo{Name: "ext-mon-id", Endpoint: "0.0.0.0:6789"}
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(mons)
-
-	// internal mons and deployments has not changed
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors))
-	// external mon is in quorum
-	assert.Len(t, c.ClusterInfo.ExternalMons, 1)
-	assert.Equal(t, "ext-mon-id", c.ClusterInfo.ExternalMons["ext-mon-id"].Name)
-
-	// No updates in unit tests w/ workaround
-	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that ext mon is in endpoint configmap
-	cm, err := c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Equal(t, "ext-mon-id", cm.Data[EndpointExternalMonsKey])
-	monsFromCM := controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 6)
-	for id, mon := range monsFromCM {
-		if id == "ext-mon-id" {
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].Name, mon.Name)
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].Endpoint, mon.Endpoint)
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].OutOfQuorum, mon.OutOfQuorum)
-		} else {
-			assert.Equal(t, inital5Mons[id].Name, mon.Name)
-			assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint)
-			assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum)
-		}
-	}
-
-	// 3. downscale mons to 4:
-	c.spec.Mon.Count = 4
-
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 4, len(c.ClusterInfo.InternalMonitors))
-	assert.Len(t, c.ClusterInfo.ExternalMons, 1)
-	// No updates in unit tests w/ workaround
-	assert.ElementsMatch(t, []string{}, testopk8s.DeploymentNamesUpdated(deploymentsUpdated))
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that unknown mon is not in endpoint configmap
-	cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Equal(t, "ext-mon-id", cm.Data[EndpointExternalMonsKey])
-	monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 5)
-	for id, mon := range monsFromCM {
-		if id == "ext-mon-id" {
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].Name, mon.Name)
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].Endpoint, mon.Endpoint)
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].OutOfQuorum, mon.OutOfQuorum)
-		} else {
-			assert.Equal(t, inital5Mons[id].Name, mon.Name)
-			assert.Equal(t, inital5Mons[id].Endpoint, mon.Endpoint)
-			assert.Equal(t, inital5Mons[id].OutOfQuorum, mon.OutOfQuorum)
-		}
-	}
-
-	// 4. upscale back to 5:
-	c.spec.Mon.Count = 5
-	mons = make(map[string]*cephclient.MonInfo)
-	for k, v := range c.ClusterInfo.InternalMonitors {
-		mons[k] = v
-	}
-	mons["ext-mon-id"] = &cephclient.MonInfo{Name: "ext-mon-id", Endpoint: "0.0.0.0:6789"}
-	monQuorumResponse = clienttest.MonInQuorumResponseFromMons(mons)
-
-	err = c.checkHealth(ctx)
-	assert.Nil(t, err)
-	assert.Equal(t, 5, len(c.ClusterInfo.InternalMonitors))
-	assert.Len(t, c.ClusterInfo.ExternalMons, 1)
-	// No updates in unit tests w/ workaround
-	assert.Len(t, testopk8s.DeploymentNamesUpdated(deploymentsUpdated), 4)
-	testopk8s.ClearDeploymentsUpdated(deploymentsUpdated)
-
-	// check that unknown mon is not in endpoint configmap
-	cm, err = c.context.Clientset.CoreV1().ConfigMaps(c.Namespace).Get(ctx, EndpointConfigMapName, metav1.GetOptions{})
-	assert.Nil(t, err)
-	assert.Equal(t, "ext-mon-id", cm.Data[EndpointExternalMonsKey])
-	monsFromCM = controller.ParseMonEndpoints(cm.Data[EndpointDataKey])
-	assert.Len(t, monsFromCM, 6)
-	for id, mon := range monsFromCM {
-		if id == "ext-mon-id" {
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].Name, mon.Name)
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].Endpoint, mon.Endpoint)
-			assert.Equal(t, c.ClusterInfo.ExternalMons[id].OutOfQuorum, mon.OutOfQuorum)
-		} else {
-			assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Name, mon.Name)
-			assert.Equal(t, c.ClusterInfo.InternalMonitors[id].Endpoint, mon.Endpoint)
-			assert.Equal(t, c.ClusterInfo.InternalMonitors[id].OutOfQuorum, mon.OutOfQuorum)
-		}
-	}
-}
diff --git a/pkg/operator/ceph/cluster/mon/mon_test.go b/pkg/operator/ceph/cluster/mon/mon_test.go
index a481ec4d7..b4c5e0f5b 100644
--- a/pkg/operator/ceph/cluster/mon/mon_test.go
+++ b/pkg/operator/ceph/cluster/mon/mon_test.go
@@ -288,8 +288,8 @@ func TestPersistMons(t *testing.T) {
 	assert.Equal(t, map[string]string{"key": "value"}, cm.Annotations)
 
 	// Persist mon b, and remove mon a for simply testing the configmap is updated
-	c.ClusterInfo.InternalMonitors["b"] = &cephclient.MonInfo{Name: "b", Endpoint: "4.5.6.7:3300"}
-	delete(c.ClusterInfo.InternalMonitors, "a")
+	c.ClusterInfo.Monitors["b"] = &cephclient.MonInfo{Name: "b", Endpoint: "4.5.6.7:3300"}
+	delete(c.ClusterInfo.Monitors, "a")
 	err = c.persistExpectedMonDaemons()
 	assert.NoError(t, err)
 
@@ -317,7 +317,7 @@ func TestSaveMonEndpoints(t *testing.T) {
 	assert.Equal(t, "-1", cm.Data[opcontroller.MaxMonIDKey])
 
 	// update the config map
-	c.ClusterInfo.InternalMonitors["a"].Endpoint = "2.3.4.5:6789"
+	c.ClusterInfo.Monitors["a"].Endpoint = "2.3.4.5:6789"
 	c.maxMonID = 2
 	c.mapping.Schedule["a"] = &opcontroller.MonScheduleInfo{
 		Name:     "node0",
diff --git a/pkg/operator/ceph/config/store_test.go b/pkg/operator/ceph/config/store_test.go
index e9a2962b7..902a72e4c 100644
--- a/pkg/operator/ceph/config/store_test.go
+++ b/pkg/operator/ceph/config/store_test.go
@@ -45,25 +45,25 @@ func TestStore(t *testing.T) {
 		sec, e := clientset.CoreV1().Secrets(ns).Get(ctxt, StoreName, metav1.GetOptions{})
 		assert.NoError(t, e)
 		mh := strings.Split(sec.StringData["mon_host"], ",") // list of mon ip:port pairs in cluster
-		expectedEndpoints := len(ci.InternalMonitors)
+		expectedEndpoints := len(ci.Monitors)
 		if mon1EndpointsEnabled {
 			expectedEndpoints *= 2
 		}
-		assert.Equal(t, expectedEndpoints, len(mh), ci.InternalMonitors["a"].Endpoint) // we need to pass x2 since we split on "," above and that returns msgr1 and msgr2 addresses
-		mim := strings.Split(sec.StringData["mon_initial_members"], ",")               // list of mon ids in cluster
-		assert.Equal(t, len(ci.InternalMonitors), len(mim))
+		assert.Equal(t, expectedEndpoints, len(mh), ci.Monitors["a"].Endpoint) // we need to pass x2 since we split on "," above and that returns msgr1 and msgr2 addresses
+		mim := strings.Split(sec.StringData["mon_initial_members"], ",")       // list of mon ids in cluster
+		assert.Equal(t, len(ci.Monitors), len(mim))
 		// make sure every mon has its id/ip:port in mon_initial_members/mon_host
 		for _, id := range mim {
 			// cannot use "assert.Contains(t, mh, ci.Monitors[id].Endpoint)"
 			// it looks like the value is not found but if present, it might be confused by the brackets
 			contains := false
 			for _, c := range mh {
-				if strings.Contains(c, ci.InternalMonitors[id].Endpoint) {
+				if strings.Contains(c, ci.Monitors[id].Endpoint) {
 					contains = true
 				}
 			}
 			assert.True(t, contains)
-			assert.Contains(t, mim, ci.InternalMonitors[id].Name)
+			assert.Contains(t, mim, ci.Monitors[id].Name)
 		}
 	}
 
@@ -80,14 +80,14 @@ func TestStore(t *testing.T) {
 
 	// Now run the same test for v1 endpoints
 	mon1EndpointsEnabled = true
-	for _, mon := range i1.InternalMonitors {
+	for _, mon := range i1.Monitors {
 		mon.Endpoint = "1.2.3.4:6789"
 	}
 	err = s.CreateOrUpdate(i1)
 	assert.NoError(t, err)
 	assertConfigStore(i1)
 
-	for _, mon := range i3.InternalMonitors {
+	for _, mon := range i3.Monitors {
 		mon.Endpoint = "1.2.3.4:6789"
 	}
 	err = s.CreateOrUpdate(i3)
diff --git a/pkg/operator/ceph/object/config_test.go b/pkg/operator/ceph/object/config_test.go
index 21ae599c6..f146ce617 100644
--- a/pkg/operator/ceph/object/config_test.go
+++ b/pkg/operator/ceph/object/config_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package object
 
 import (
-	"context"
 	"testing"
 
 	cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
@@ -26,8 +25,6 @@ import (
 	cephver "github.com/rook/rook/pkg/operator/ceph/version"
 	"github.com/rook/rook/pkg/operator/test"
 	"github.com/stretchr/testify/assert"
-	v1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 func newConfig(t *testing.T) *clusterConfig {
@@ -185,49 +182,3 @@ func Test_clusterConfig_generateMonConfigOptions(t *testing.T) {
 		})
 	}
 }
-
-func TestRgwConfigFromSecret(t *testing.T) {
-	objContext := &Context{
-		Context: &clusterd.Context{
-			Clientset: test.New(t, 3),
-		},
-		clusterInfo: cephclient.AdminTestClusterInfo("rook-ceph"),
-	}
-
-	objectStore := simpleStore()
-	objectStore.Spec.Gateway.RgwConfigFromSecret = map[string]v1.SecretKeySelector{
-		"rgw_secret_conf_name": {
-			LocalObjectReference: v1.LocalObjectReference{
-				Name: "my-secret",
-			},
-			Key: "secKey",
-		},
-	}
-
-	c := &clusterConfig{
-		store:       objectStore,
-		context:     objContext.Context,
-		clusterInfo: objContext.clusterInfo,
-	}
-
-	rgwConfig := &rgwConfig{}
-
-	_, err := c.generateMonConfigOptions(rgwConfig)
-	assert.Error(t, err, "error if secret not exists")
-
-	s := &v1.Secret{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      "my-secret",
-			Namespace: "rook-ceph",
-		},
-		Data: map[string][]byte{
-			"secKey": []byte("secVal"),
-		},
-	}
-	_, err = objContext.Context.Clientset.CoreV1().Secrets(objContext.clusterInfo.Namespace).Create(context.TODO(), s, metav1.CreateOptions{})
-	assert.NoError(t, err, "create secret")
-
-	got, err := c.generateMonConfigOptions(rgwConfig)
-	assert.NoError(t, err)
-	assert.EqualValues(t, "secVal", got["rgw_secret_conf_name"])
-}
diff --git a/tests/scripts/csiaddons.sh b/tests/scripts/csiaddons.sh
index c577b6dff..2b048b807 100755
--- a/tests/scripts/csiaddons.sh
+++ b/tests/scripts/csiaddons.sh
@@ -16,7 +16,7 @@
 
 set -xEo pipefail
 
-CSIADDONS_VERSION="v0.12.0"
+CSIADDONS_VERSION="v0.11.0"
 CSIADDONS_CRD_NAME="csiaddonsnodes.csiaddons.openshift.io"
 CSIADDONS_CONTAINER_NAME="csi-addons"
 
diff --git a/tests/scripts/pythonwebserver/server.py b/tests/scripts/pythonwebserver/server.py
index 6f0960310..eb2c841b0 100644
--- a/tests/scripts/pythonwebserver/server.py
+++ b/tests/scripts/pythonwebserver/server.py
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
-        http://www.apache.org/licenses/LICENSE-2.0
+	http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,