Repository: rook/rook
Pull request #15451 (2025-02-24 13:42:56)

build(deps): bump the github-dependencies group across 1 directory with 6 updates
Bumps the github-dependencies group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/ceph/go-ceph](https://github.com/ceph/go-ceph) | `0.31.0` | `0.32.0` |
| [github.com/google/go-cmp](https://github.com/google/go-cmp) | `0.6.0` | `0.7.0` |
| [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) | `1.15.0` | `1.16.0` |
| [github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring](https://github.com/prometheus-operator/prometheus-operator) | `0.80.0` | `0.80.1` |
| [github.com/prometheus-operator/prometheus-operator/pkg/client](https://github.com/prometheus-operator/prometheus-operator) | `0.80.0` | `0.80.1` |
| [github.com/spf13/cobra](https://github.com/spf13/cobra) | `1.8.1` | `1.9.1` |


Updates `github.com/ceph/go-ceph` from 0.31.0 to 0.32.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/ceph/go-ceph/releases">github.com/ceph/go-ceph's releases</a>.</em></p>
<blockquote>
<h2>Release v0.32.0</h2>
<p>The maintainers and contributors to go-ceph are pleased to announce the v0.32.0 release. This is another great step towards making it possible to use the power of the Ceph APIs in the Go language.</p>
<p>As this is a v0.x release we do not guarantee backwards compatibility with previous versions of the code. However, we aim not to disrupt existing consumers of the library and thus make an effort not to immediately implement breaking changes without very good justification. Please see the &quot;Deprecations &amp; Removals&quot; section (if present) to get a sense of what you can expect to change in the future and prepare your code ahead of time. You may also want to view &quot;Deprecations &amp; Removals&quot; of previous releases as they are not repeated here. All newly introduced APIs in the following section are labeled as &quot;preview&quot; APIs first, and are only available if the <code>ceph_preview</code> build tag is set. There is explicitly no backwards compatibility guaranteed for these until they are labeled as &quot;stable&quot; in a later release.</p>
<p>Special thanks to our new contributors:</p>
<ul>
<li><a href="https://github.com/idryomov"><code>@​idryomov</code></a> made their first contribution in <a href="https://redirect.github.com/ceph/go-ceph/pull/1067">ceph/go-ceph#1067</a></li>
</ul>
<h2>New Features</h2>
<h3>rbd</h3>
<ul>
<li>add EncryptionLoad2 implementing rbd_encryption_load2  by <a href="https://github.com/phlogistonjohn"><code>@​phlogistonjohn</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1061">ceph/go-ceph#1061</a>
<ul>
<li>Adds <code>EncryptionLoad2</code></li>
</ul>
</li>
</ul>
<h2>API Stability Updates</h2>
<p>The following APIs are now stable:</p>
<h3>rbd</h3>
<ul>
<li><code>GroupSnapGetInfo</code></li>
</ul>
<h2>Other changes</h2>
<h3>rgw</h3>
<ul>
<li>rgw/admin: support new-bucket-name for LinkBucket by <a href="https://github.com/sj14"><code>@​sj14</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1046">ceph/go-ceph#1046</a></li>
<li>rgw: use maintained github.com/aws/aws-sdk-go-v2 module instead of v1 by <a href="https://github.com/nixpanic"><code>@​nixpanic</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1057">ceph/go-ceph#1057</a></li>
<li>rgw/admin: parse more fields by bucket struct by <a href="https://github.com/clwluvw"><code>@​clwluvw</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1068">ceph/go-ceph#1068</a></li>
</ul>
<h3>rbd</h3>
<ul>
<li>rbd: fix cleanup of GroupSnapRollback and Sparsify progress callbacks by <a href="https://github.com/idryomov"><code>@​idryomov</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1067">ceph/go-ceph#1067</a></li>
</ul>
<h3>Internal</h3>
<ul>
<li>go-ceph: bump golang.org/x/sys from 0.27.0 to 0.28.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1056">ceph/go-ceph#1056</a></li>
<li>workflows: remove pre-quincy job by <a href="https://github.com/phlogistonjohn"><code>@​phlogistonjohn</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1060">ceph/go-ceph#1060</a></li>
<li>Makefile: Remove leftovers related to EOL releases by <a href="https://github.com/anoopcs9"><code>@​anoopcs9</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1062">ceph/go-ceph#1062</a></li>
<li>go-ceph: bump golang.org/x/sys from 0.28.0 to 0.29.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1069">ceph/go-ceph#1069</a></li>
<li>go-ceph: bump github.com/aws/smithy-go from 1.22.1 to 1.22.2 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1070">ceph/go-ceph#1070</a></li>
<li>go-ceph: bump github.com/aws/aws-sdk-go-v2 from 1.32.7 to 1.36.0 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1072">ceph/go-ceph#1072</a></li>
<li>go-ceph: bump github.com/aws/aws-sdk-go-v2/credentials from 1.17.48 to 1.17.57 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1071">ceph/go-ceph#1071</a></li>
<li>go-ceph: bump github.com/aws/aws-sdk-go-v2/config from 1.28.7 to 1.29.4 by <a href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1073">ceph/go-ceph#1073</a></li>
<li>internal: Use a wrapper to detect server version by <a href="https://github.com/anoopcs9"><code>@​anoopcs9</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1074">ceph/go-ceph#1074</a></li>
<li>containers: another workaround for ceph container changes by <a href="https://github.com/phlogistonjohn"><code>@​phlogistonjohn</code></a> in <a href="https://redirect.github.com/ceph/go-ceph/pull/1075">ceph/go-ceph#1075</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/ceph/go-ceph/compare/v0.31.0...v0.32.0">https://github.com/ceph/go-ceph/compare/v0.31.0...v0.32.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/ceph/go-ceph/commit/9716f6158a0c54f1ba13220d1f2e98f9ec2ba40a"><code>9716f61</code></a> release: update README</li>
<li><a href="https://github.com/ceph/go-ceph/commit/a14ea25b3ae48fdabd347547841c828f5acbf97e"><code>a14ea25</code></a> release: make api-fix-versions</li>
<li><a href="https://github.com/ceph/go-ceph/commit/3b0028f24308ec8f05b62d95db792e269fde5c42"><code>3b0028f</code></a> release: promote stable APIs</li>
<li><a href="https://github.com/ceph/go-ceph/commit/84919dd4ed0b955bfcb32ca13fb32a9a380d91ca"><code>84919dd</code></a> entrypoint: increase test timeout needed for rbd</li>
<li><a href="https://github.com/ceph/go-ceph/commit/0d6b5806656a7bd10bbedec454afa8e7b654414c"><code>0d6b580</code></a> rbd: add EncryptionOptionsLUKS for opening LUKS images</li>
<li><a href="https://github.com/ceph/go-ceph/commit/ccb22a5f5ee8d12b269aaa97df650fd1412d9e74"><code>ccb22a5</code></a> rbd: add EncryptionLoad2 implementing rbd_encryption_load2</li>
<li><a href="https://github.com/ceph/go-ceph/commit/6bc3fb2faa299218a758f8aa632eb3797722ee4f"><code>6bc3fb2</code></a> rbd: clean up rbd encryption load test case</li>
<li><a href="https://github.com/ceph/go-ceph/commit/1e053bb9d2a872a4b869a13b29a7dbe1a11ea0af"><code>1e053bb</code></a> rbd: fix a pair of erroneous comments</li>
<li><a href="https://github.com/ceph/go-ceph/commit/2c5da9f0f6dc0de7f910ef34c16605687ebb1903"><code>2c5da9f</code></a> containers: another workaround for ceph container changes</li>
<li><a href="https://github.com/ceph/go-ceph/commit/2e15e7224434b872e13db682d7a97b887930621e"><code>2e15e72</code></a> rbd: Use internal wrapper for detecting server version</li>
<li>Additional commits viewable in <a href="https://github.com/ceph/go-ceph/compare/v0.31.0...v0.32.0">compare view</a></li>
</ul>
</details>
<br />

Updates `github.com/google/go-cmp` from 0.6.0 to 0.7.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/google/go-cmp/releases">github.com/google/go-cmp's releases</a>.</em></p>
<blockquote>
<h2>v0.7.0</h2>
<p>New API:</p>
<ul>
<li>(<a href="https://redirect.github.com/google/go-cmp/issues/367">#367</a>) Support compare functions with SortSlices and SortMaps</li>
</ul>
<p>Panic messaging:</p>
<ul>
<li>(<a href="https://redirect.github.com/google/go-cmp/issues/370">#370</a>) Detect proto.Message types when failing to export a field</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/google/go-cmp/commit/9b12f366a942ebc7254abc7f32ca05068b455fb7"><code>9b12f36</code></a> Detect proto.Message types when failing to export a field (<a href="https://redirect.github.com/google/go-cmp/issues/370">#370</a>)</li>
<li><a href="https://github.com/google/go-cmp/commit/4dd3d63d6987c0f84fce8e1d1c5bb59f0badc220"><code>4dd3d63</code></a> fix: type 'aribica' =&gt; 'arabica' (<a href="https://redirect.github.com/google/go-cmp/issues/368">#368</a>)</li>
<li><a href="https://github.com/google/go-cmp/commit/391980c4b2e1cc2c30d2bfae6039815350490495"><code>391980c</code></a> Support compare functions with SortSlices and SortMaps (<a href="https://redirect.github.com/google/go-cmp/issues/367">#367</a>)</li>
<li>See full diff in <a href="https://github.com/google/go-cmp/compare/v0.6.0...v0.7.0">compare view</a></li>
</ul>
</details>
<br />

Updates `github.com/hashicorp/vault/api` from 1.15.0 to 1.16.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/hashicorp/vault/releases">github.com/hashicorp/vault/api's releases</a>.</em></p>
<blockquote>
<h2>v1.16.0</h2>
<h2>1.16.0</h2>
<h3>March 26, 2024</h3>
<p>SECURITY:</p>
<ul>
<li>auth/cert: compare public keys of trusted non-CA certificates with incoming
client certificates to prevent trusting certs with the same serial number
but not the same public/private key. [<a href="https://redirect.github.com/hashicorp/vault/pull/25649">GH-25649</a>]</li>
<li>auth/cert: validate OCSP response was signed by the expected issuer and serial number matched request [<a href="https://redirect.github.com/hashicorp/vault/pull/26091">GH-26091</a>]</li>
<li>secrets/transit: fix a regression that was honoring nonces provided in non-convergent modes during encryption. [<a href="https://redirect.github.com/hashicorp/vault/pull/22852">GH-22852</a>]</li>
</ul>
<p>CHANGES:</p>
<ul>
<li>Upgrade grpc to v1.58.3 [<a href="https://redirect.github.com/hashicorp/vault/pull/23703">GH-23703</a>]</li>
<li>Upgrade x/net to v0.17.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/23703">GH-23703</a>]</li>
<li>api: add the <code>enterprise</code> parameter to the <code>/sys/health</code> endpoint [<a href="https://redirect.github.com/hashicorp/vault/pull/24270">GH-24270</a>]</li>
<li>auth/alicloud: Update plugin to v0.16.1 [<a href="https://redirect.github.com/hashicorp/vault/pull/25014">GH-25014</a>]</li>
<li>auth/alicloud: Update plugin to v0.17.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25217">GH-25217</a>]</li>
<li>auth/approle: Normalized error response messages when invalid credentials are provided [<a href="https://redirect.github.com/hashicorp/vault/pull/23786">GH-23786</a>]</li>
<li>auth/azure: Update plugin to v0.16.1 [<a href="https://redirect.github.com/hashicorp/vault/pull/22795">GH-22795</a>]</li>
<li>auth/azure: Update plugin to v0.17.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25258">GH-25258</a>]</li>
<li>auth/cf: Update plugin to v0.16.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25196">GH-25196</a>]</li>
<li>auth/gcp: Update plugin to v0.16.2 [<a href="https://redirect.github.com/hashicorp/vault/pull/25233">GH-25233</a>]</li>
<li>auth/jwt: Update plugin to v0.19.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/24972">GH-24972</a>]</li>
<li>auth/jwt: Update plugin to v0.20.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25326">GH-25326</a>]</li>
<li>auth/jwt: Update plugin to v0.20.1 [<a href="https://redirect.github.com/hashicorp/vault/pull/25937">GH-25937</a>]</li>
<li>auth/kerberos: Update plugin to v0.10.1 [<a href="https://redirect.github.com/hashicorp/vault/pull/22797">GH-22797</a>]</li>
<li>auth/kerberos: Update plugin to v0.11.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25232">GH-25232</a>]</li>
<li>auth/kubernetes: Update plugin to v0.18.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25207">GH-25207</a>]</li>
<li>auth/oci: Update plugin to v0.14.1 [<a href="https://redirect.github.com/hashicorp/vault/pull/22774">GH-22774</a>]</li>
<li>auth/oci: Update plugin to v0.15.1 [<a href="https://redirect.github.com/hashicorp/vault/pull/25245">GH-25245</a>]</li>
<li>cli: Using <code>vault plugin reload</code> with <code>-plugin</code> in the root namespace will now reload the plugin across all namespaces instead of just the root namespace. [<a href="https://redirect.github.com/hashicorp/vault/pull/24878">GH-24878</a>]</li>
<li>cli: <code>vault plugin info</code> and <code>vault plugin deregister</code> now require 2 positional arguments instead of accepting either 1 or 2. [<a href="https://redirect.github.com/hashicorp/vault/pull/24250">GH-24250</a>]</li>
<li>core (enterprise): Seal High Availability (HA) must be enabled by <code>enable_multiseal</code> in configuration.</li>
<li>core: Bump Go version to 1.21.8.</li>
<li>database/couchbase: Update plugin to v0.10.1 [<a href="https://redirect.github.com/hashicorp/vault/pull/25275">GH-25275</a>]</li>
<li>database/elasticsearch: Update plugin to v0.14.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25263">GH-25263</a>]</li>
<li>database/mongodbatlas: Update plugin to v0.11.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25264">GH-25264</a>]</li>
<li>database/redis-elasticache: Update plugin to v0.3.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25296">GH-25296</a>]</li>
<li>database/redis: Update plugin to v0.2.3 [<a href="https://redirect.github.com/hashicorp/vault/pull/25289">GH-25289</a>]</li>
<li>database/snowflake: Update plugin to v0.10.0 [<a href="https://redirect.github.com/hashicorp/vault/pull/25143">GH-25143</a>]</li>
<li>database/snowflake: Update plugin to v0.9.1 [<a href="https://redirect.github.com/hashicorp/vault/pull/25020">GH-25020</a>]</li>
<li>events: Remove event noficiations websocket endpoint in non-Enterprise [<a href="https://redirect.github.com/hashicorp/vault/pull/25640">GH-25640</a>]</li>
<li>events: Source URL is now <code>vault://{vault node}</code> [<a href="https://redirect.github.com/hashicorp/vault/pull/24201">GH-24201</a>]</li>
<li>identity (enterprise): POST requests to the <code>/identity/entity/merge</code> endpoint
are now always forwarded from standbys to the active node. [<a href="https://redirect.github.com/hashicorp/vault/pull/24325">GH-24325</a>]</li>
<li>plugins/database: Reading connection config at <code>database/config/:name</code> will now return a computed <code>running_plugin_version</code> field if a non-builtin version is running. [<a href="https://redirect.github.com/hashicorp/vault/pull/25105">GH-25105</a>]</li>
<li>plugins: Add a warning to the response from sys/plugins/reload/backend if no plugins were reloaded. [<a href="https://redirect.github.com/hashicorp/vault/pull/24512">GH-24512</a>]</li>
<li>plugins: By default, environment variables provided during plugin registration will now take precedence over system environment variables.</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/hashicorp/vault/blob/main/CHANGELOG-v1.10-v1.15.md">github.com/hashicorp/vault/api's changelog</a>.</em></p>
<blockquote>
<h2>1.15.16 Enterprise</h2>
<h3>October 09, 2024</h3>
<p>SECURITY:</p>
<ul>
<li>secrets/identity: A privileged Vault operator with write permissions to the root namespace's identity endpoint could escalate their privileges to Vault's root policy (CVE-2024-9180) <a href="https://discuss.hashicorp.com/t/hcsec-2024-21-vault-operators-in-root-namespace-may-elevate-their-privileges/70565">HCSEC-2024-21</a></li>
</ul>
<p>IMPROVEMENTS:</p>
<ul>
<li>core: log at level ERROR rather than INFO when all seals are unhealthy. [<a href="https://redirect.github.com/hashicorp/vault/pull/28564">GH-28564</a>]</li>
</ul>
<p>BUG FIXES:</p>
<ul>
<li>auth/cert: When using ocsp_ca_certificates, an error was produced though extra certs validation succeeded. [<a href="https://redirect.github.com/hashicorp/vault/pull/28597">GH-28597</a>]</li>
<li>auth/token: Fix token TTL calculation so that it uses <code>max_lease_ttl</code> tune value for tokens created via <code>auth/token/create</code>. [<a href="https://redirect.github.com/hashicorp/vault/pull/28498">GH-28498</a>]</li>
</ul>
<h2>1.15.15 Enterprise</h2>
<h3>September 25, 2024</h3>
<p>SECURITY:</p>
<ul>
<li>secrets/ssh: require <code>valid_principals</code> to contain a value or <code>default_user</code> be set by default to guard against potentially insecure configurations. <code>allow_empty_principals</code> can be used for backwards compatibility [HCSEC-2024-20](<a href="https://discuss.hashicorp.com/t/hcsec-2024-20-vault-ssh-secrets-engine-configuration-did-not-restrict-valid-principals-by-default/7025">https://discuss.hashicorp.com/t/hcsec-2024-20-vault-ssh-secrets-engine-configuration-did-not-restrict-valid-principals-by-default/7025</a></li>
</ul>
<p>CHANGES:</p>
<ul>
<li>core: Bump Go version to 1.22.7.</li>
<li>secrets/ssh: Add a flag, <code>allow_empty_principals</code> to allow keys or certs to apply to any user/principal. [<a href="https://redirect.github.com/hashicorp/vault/pull/28466">GH-28466</a>]</li>
</ul>
<p>BUG FIXES:</p>
<ul>
<li>secret/aws: Fixed potential panic after step-down and the queue has not repopulated. [<a href="https://redirect.github.com/hashicorp/vault/pull/28330">GH-28330</a>]</li>
<li>auth/cert: During certificate validation, OCSP requests are debug logged even if Vault's log level is above DEBUG. [<a href="https://redirect.github.com/hashicorp/vault/pull/28450">GH-28450</a>]</li>
<li>auth/cert: ocsp_ca_certificates field was not honored when validating OCSP responses signed by a CA that did not issue the certificate. [<a href="https://redirect.github.com/hashicorp/vault/pull/28309">GH-28309</a>]</li>
<li>auth: Updated error handling for missing login credentials in AppRole and UserPass auth methods to return a 400 error instead of a 500 error. [<a href="https://redirect.github.com/hashicorp/vault/pull/28441">GH-28441</a>]</li>
<li>core: Fixed an issue where maximum request duration timeout was not being added to all requests containing strings sys/monitor and sys/events. With this change, timeout is now added to all requests except monitor and events endpoint. [<a href="https://redirect.github.com/hashicorp/vault/pull/28230">GH-28230</a>]</li>
</ul>
<h2>1.15.14 Enterprise</h2>
<h3>August 29, 2024</h3>
<p>CHANGES:</p>
<ul>
<li>activity (enterprise): filter all fields in client count responses by the request namespace [<a href="https://redirect.github.com/hashicorp/vault/pull/27790">GH-27790</a>]</li>
<li>core: Bump Go version to 1.22.6</li>
</ul>
<p>IMPROVEMENTS:</p>
<ul>
<li>activity log: Changes how new client counts in the current month are estimated, in order to return more
visibly sensible totals. [<a href="https://redirect.github.com/hashicorp/vault/pull/27547">GH-27547</a>]</li>
<li>activity: <code>/sys/internal/counters/activity</code> will now include a warning if the specified usage period contains estimated client counts. [<a href="https://redirect.github.com/hashicorp/vault/pull/28068">GH-28068</a>]</li>
<li>cli: <code>vault operator usage</code> will now include a warning if the specified usage period contains estimated client counts. [<a href="https://redirect.github.com/hashicorp/vault/pull/28068">GH-28068</a>]</li>
<li>core/activity: Ensure client count queries that include the current month return consistent results by sorting the clients before performing estimation [<a href="https://redirect.github.com/hashicorp/vault/pull/28062">GH-28062</a>]</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/hashicorp/vault/commit/c20eae3e84c55bf5180ac890b83ee81c9d7ded8b"><code>c20eae3</code></a> [VAULT-25372] This is an automated pull request to build all artifacts for a ...</li>
<li><a href="https://github.com/hashicorp/vault/commit/6f4631e83cdfcb5acd153755c59810b3b945fcf0"><code>6f4631e</code></a> backport of commit 792eb3b8c314fc82b46883fcf61227687026829d (<a href="https://redirect.github.com/hashicorp/vault/issues/26132">#26132</a>)</li>
<li><a href="https://github.com/hashicorp/vault/commit/314b34d0bce98ed7f051ea070f49e91616f051e4"><code>314b34d</code></a> Backport of doc: Add kault library reference into release/1.16.x (<a href="https://redirect.github.com/hashicorp/vault/issues/26130">#26130</a>)</li>
<li><a href="https://github.com/hashicorp/vault/commit/6ff205fb86348fe0ae9ee3542abc691f5b440cf8"><code>6ff205f</code></a> Backport of Clarify wrapping token language into release/1.16.x (<a href="https://redirect.github.com/hashicorp/vault/issues/26126">#26126</a>)</li>
<li><a href="https://github.com/hashicorp/vault/commit/58752185df6e2a52e59805038f1f8dd3a5a3c4d9"><code>5875218</code></a> backport of commit de7c905477d53391bed6a404d43f8ce3789d0a8e (<a href="https://redirect.github.com/hashicorp/vault/issues/26128">#26128</a>)</li>
<li><a href="https://github.com/hashicorp/vault/commit/d623bceab6b8d1a7f7c27bd55fbd872f42e0158c"><code>d623bce</code></a> backport of commit f661f4354ceb36bc9208f5474a19355d3a1016fe (<a href="https://redirect.github.com/hashicorp/vault/issues/26124">#26124</a>)</li>
<li><a href="https://github.com/hashicorp/vault/commit/4bfb02751dcdbd8f3d91671b3965b5e9458d78cc"><code>4bfb027</code></a> backport of commit fa469f8bdc469570b8edaa72517433305ce2e26d (<a href="https://redirect.github.com/hashicorp/vault/issues/26122">#26122</a>)</li>
<li><a href="https://github.com/hashicorp/vault/commit/bc9c84492684425d919f0f6459b0b4d1d65261d0"><code>bc9c844</code></a> backport of commit 3df09357b25b5180b2147f35dd669d83f37ac547 (<a href="https://redirect.github.com/hashicorp/vault/issues/26121">#26121</a>)</li>
<li><a href="https://github.com/hashicorp/vault/commit/6a694d0d55729ee5b589bdaf15e62dd263e485ed"><code>6a694d0</code></a> Backport of Docs/vault 23837/sync doc update into release/1.16.x (<a href="https://redirect.github.com/hashicorp/vault/issues/26058">#26058</a>)</li>
<li><a href="https://github.com/hashicorp/vault/commit/84bc41c8d7d3c6b7728ee893d1180290b4381562"><code>84bc41c</code></a> backport of commit 7b939bdbfd628b3870473f840a9ef5aee228927f (<a href="https://redirect.github.com/hashicorp/vault/issues/26117">#26117</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/hashicorp/vault/compare/v1.15.0...v1.16.0">compare view</a></li>
</ul>
</details>
<br />

Updates `github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring` from 0.80.0 to 0.80.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/prometheus-operator/prometheus-operator/releases">github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring's releases</a>.</em></p>
<blockquote>
<h2>0.80.1 / 2025-02-19</h2>
<ul>
<li>[BUGFIX] Fix msteamsv2_configs to work with either <code>webhook_url</code> or <code>webhook_url_file</code>. <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7352">#7352</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/prometheus-operator/prometheus-operator/blob/main/CHANGELOG.md">github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring's changelog</a>.</em></p>
<blockquote>
<h1>0.80.1 / 2025-02-19</h1>
<ul>
<li>[BUGFIX] Fix msteamsv2_configs to work with either <code>webhook_url</code> or <code>webhook_url_file</code>. <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7352">#7352</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/4126d60d8a8ae99be866cdd0d15546a4d3e9fe8b"><code>4126d60</code></a> Merge pull request <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7358">#7358</a> from slashpai/cut-0.80.1</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/e8a716268fa48e66dd4be70cb9c9648d4736a659"><code>e8a7162</code></a> chore: cut v0.80.1</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/85b1639a902a1cc2e7b13cf9371a1df356595f38"><code>85b1639</code></a> Merge pull request <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7352">#7352</a> from heliapb/fix/msteamsv2_config_r0_80</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/53b60e10e0095192bae8b5614c17f0eabd2bade8"><code>53b60e1</code></a> fix - MSTeamsV2 config</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/c740cff43a6918e304080402d68b258613311072"><code>c740cff</code></a> Merge pull request <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7354">#7354</a> from simonpasquier/backport-c0e32a49d</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/4130922c0200b427e104691adc95d9802b628663"><code>4130922</code></a> test: skip DNS service discovery tests</li>
<li>See full diff in <a href="https://github.com/prometheus-operator/prometheus-operator/compare/v0.80.0...v0.80.1">compare view</a></li>
</ul>
</details>
<br />

Updates `github.com/prometheus-operator/prometheus-operator/pkg/client` from 0.80.0 to 0.80.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/prometheus-operator/prometheus-operator/releases">github.com/prometheus-operator/prometheus-operator/pkg/client's releases</a>.</em></p>
<blockquote>
<h2>0.80.1 / 2025-02-19</h2>
<ul>
<li>[BUGFIX] Fix msteamsv2_configs to work with either <code>webhook_url</code> or <code>webhook_url_file</code>. <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7352">#7352</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/prometheus-operator/prometheus-operator/blob/main/CHANGELOG.md">github.com/prometheus-operator/prometheus-operator/pkg/client's changelog</a>.</em></p>
<blockquote>
<h1>0.80.1 / 2025-02-19</h1>
<ul>
<li>[BUGFIX] Fix msteamsv2_configs to work with either <code>webhook_url</code> or <code>webhook_url_file</code>. <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7352">#7352</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/4126d60d8a8ae99be866cdd0d15546a4d3e9fe8b"><code>4126d60</code></a> Merge pull request <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7358">#7358</a> from slashpai/cut-0.80.1</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/e8a716268fa48e66dd4be70cb9c9648d4736a659"><code>e8a7162</code></a> chore: cut v0.80.1</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/85b1639a902a1cc2e7b13cf9371a1df356595f38"><code>85b1639</code></a> Merge pull request <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7352">#7352</a> from heliapb/fix/msteamsv2_config_r0_80</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/53b60e10e0095192bae8b5614c17f0eabd2bade8"><code>53b60e1</code></a> fix - MSTeamsV2 config</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/c740cff43a6918e304080402d68b258613311072"><code>c740cff</code></a> Merge pull request <a href="https://redirect.github.com/prometheus-operator/prometheus-operator/issues/7354">#7354</a> from simonpasquier/backport-c0e32a49d</li>
<li><a href="https://github.com/prometheus-operator/prometheus-operator/commit/4130922c0200b427e104691adc95d9802b628663"><code>4130922</code></a> test: skip DNS service discovery tests</li>
<li>See full diff in <a href="https://github.com/prometheus-operator/prometheus-operator/compare/v0.80.0...v0.80.1">compare view</a></li>
</ul>
</details>
<br />

Updates `github.com/spf13/cobra` from 1.8.1 to 1.9.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/spf13/cobra/releases">github.com/spf13/cobra's releases</a>.</em></p>
<blockquote>
<h2>v1.9.1</h2>
<h3>🐛 Fixes</h3>
<ul>
<li>Fix CompletionFunc implementation by <a href="https://github.com/ccoVeille"><code>@​ccoVeille</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2234">spf13/cobra#2234</a></li>
<li>Revert &quot;Make detection for test-binary more universal (<a href="https://redirect.github.com/spf13/cobra/issues/2173">#2173</a>)&quot; by <a href="https://github.com/marckhouzam"><code>@​marckhouzam</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2235">spf13/cobra#2235</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/spf13/cobra/compare/v1.9.0...v1.9.1">https://github.com/spf13/cobra/compare/v1.9.0...v1.9.1</a></p>
<h2>v1.9.0</h2>
<h2>✨ Features</h2>
<ul>
<li>Allow linker to perform deadcode elimination for program using Cobra by <a href="https://github.com/aarzilli"><code>@​aarzilli</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/1956">spf13/cobra#1956</a></li>
<li>Add default completion command even if there are no other sub-commands by <a href="https://github.com/marckhouzam"><code>@​marckhouzam</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/1559">spf13/cobra#1559</a></li>
<li>Add CompletionWithDesc helper by <a href="https://github.com/ccoVeille"><code>@​ccoVeille</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2231">spf13/cobra#2231</a></li>
</ul>
<h2>🐛 Fixes</h2>
<ul>
<li>Fix deprecation comment for Command.SetOutput by <a href="https://github.com/thaJeztah"><code>@​thaJeztah</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2172">spf13/cobra#2172</a></li>
<li>Replace deprecated ioutil usage by <a href="https://github.com/nirs"><code>@​nirs</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2181">spf13/cobra#2181</a></li>
<li>Fix --version help and output for plugins by <a href="https://github.com/nirs"><code>@​nirs</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2180">spf13/cobra#2180</a></li>
<li>Allow to reset the templates to the default by <a href="https://github.com/marckhouzam"><code>@​marckhouzam</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2229">spf13/cobra#2229</a></li>
</ul>
<h2>🤖 Completions</h2>
<ul>
<li>Make Powershell completion work in constrained mode by <a href="https://github.com/lstemplinger"><code>@​lstemplinger</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2196">spf13/cobra#2196</a></li>
<li>Improve detection for flags that accept multiple values by <a href="https://github.com/thaJeztah"><code>@​thaJeztah</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2210">spf13/cobra#2210</a></li>
<li>add CompletionFunc type to help with completions by <a href="https://github.com/ccoVeille"><code>@​ccoVeille</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2220">spf13/cobra#2220</a></li>
<li>Add similar whitespace escape logic to bash v2 completions than in other completions by <a href="https://github.com/kangasta"><code>@​kangasta</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/1743">spf13/cobra#1743</a></li>
<li>Print ActiveHelp for bash along other completions by <a href="https://github.com/marckhouzam"><code>@​marckhouzam</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2076">spf13/cobra#2076</a></li>
<li>fix(completions): Complete map flags multiple times by <a href="https://github.com/gabe565"><code>@​gabe565</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2174">spf13/cobra#2174</a></li>
<li>fix(bash): nounset unbound file filter variable on empty extension by <a href="https://github.com/scop"><code>@​scop</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2228">spf13/cobra#2228</a></li>
</ul>
<h2>🧪 Testing</h2>
<ul>
<li>Test also with go 1.23 by <a href="https://github.com/nirs"><code>@​nirs</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2182">spf13/cobra#2182</a></li>
<li>Make detection for test-binary more universal by <a href="https://github.com/thaJeztah"><code>@​thaJeztah</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2173">spf13/cobra#2173</a></li>
</ul>
<h2>✍🏼 Documentation</h2>
<ul>
<li>docs: update README.md by <a href="https://github.com/eltociear"><code>@​eltociear</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2197">spf13/cobra#2197</a></li>
<li>Improve site formatting by <a href="https://github.com/nirs"><code>@​nirs</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2183">spf13/cobra#2183</a></li>
<li>doc: add Conduit by <a href="https://github.com/raulb"><code>@​raulb</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2230">spf13/cobra#2230</a></li>
<li>doc: azion project added to the list of CLIs that use cobra by <a href="https://github.com/maxwelbm"><code>@​maxwelbm</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2198">spf13/cobra#2198</a></li>
<li>Fix broken links in active_help.md by <a href="https://github.com/vuil"><code>@​vuil</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2202">spf13/cobra#2202</a></li>
<li>chore: fix function name in comment by <a href="https://github.com/zhuhaicity"><code>@​zhuhaicity</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2216">spf13/cobra#2216</a></li>
</ul>
<h2>🔧 Dependency upgrades</h2>
<ul>
<li>build(deps): bump github.com/cpuguy83/go-md2man/v2 from 2.0.5 to 2.0.6 by <a href="https://github.com/thaJeztah"><code>@​thaJeztah</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2206">spf13/cobra#2206</a></li>
<li>Update to latest go-md2man by <a href="https://github.com/mikelolasagasti"><code>@​mikelolasagasti</code></a> in <a href="https://redirect.github.com/spf13/cobra/pull/2201">spf13/cobra#2201</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/spf13/cobra/commit/40b5bc1437a564fc795d388b23835e84f54cd1d1"><code>40b5bc1</code></a> Revert &quot;Make detection for test-binary more universal (<a href="https://redirect.github.com/spf13/cobra/issues/2173">#2173</a>)&quot; (<a href="https://redirect.github.com/spf13/cobra/issues/2235">#2235</a>)</li>
<li><a href="https://github.com/spf13/cobra/commit/a97f9fd47b290016526c8af2dac0531fea5cd773"><code>a97f9fd</code></a> fix CompletionFunc implementation (<a href="https://redirect.github.com/spf13/cobra/issues/2234">#2234</a>)</li>
<li><a href="https://github.com/spf13/cobra/commit/5f9c40898e795a9fb0fd5ca83b6e05c3720523d1"><code>5f9c408</code></a> chore: Upgrade dependencies for v1.9.0 (<a href="https://redirect.github.com/spf13/cobra/issues/2233">#2233</a>)</li>
<li><a href="https://github.com/spf13/cobra/commit/24ada7fe71e3a3a8741dd52e0a7fc3b97450535a"><code>24ada7f</code></a> Remove the default &quot;completion&quot; cmd if it is alone (<a href="https://redirect.github.com/spf13/cobra/issues/1559">#1559</a>)</li>
<li><a href="https://github.com/spf13/cobra/commit/680936a2200be363c61feda8cd29287f0726a48c"><code>680936a</code></a> New logo</li>
<li><a href="https://github.com/spf13/cobra/commit/8cb30f9ca53a004a6fe88c5cfcc79ac7b24fc638"><code>8cb30f9</code></a> feat: add CompletionWithDesc helper (<a href="https://redirect.github.com/spf13/cobra/issues/2231">#2231</a>)</li>
<li><a href="https://github.com/spf13/cobra/commit/17b6dca2ffaf6113cbd1cf433ec988fa7d63c6f3"><code>17b6dca</code></a> doc: add Conduit (<a href="https://redirect.github.com/spf13/cobra/issues/2230">#2230</a>)</li>
<li><a href="https://github.com/spf13/cobra/commit/ab5cadcc1bbe224b329726fc5f8b99d6f93e9805"><code>ab5cadc</code></a> Allow to reset the templates to the default (<a href="https://redirect.github.com/spf13/cobra/issues/2229">#2229</a>)</li>
<li><a href="https://github.com/spf13/cobra/commit/4ba5566f5704a9c0d205e1ef3efc4896156d33fa"><code>4ba5566</code></a> fix(bash): nounset unbound file filter variable on empty extension (<a href="https://redirect.github.com/spf13/cobra/issues/2228">#2228</a>)</li>
<li><a href="https://github.com/spf13/cobra/commit/41b26ec8bb59dfba580f722201bf371c4f5703dd"><code>41b26ec</code></a> Print ActiveHelp for bash along other completions (<a href="https://redirect.github.com/spf13/cobra/issues/2076">#2076</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/spf13/cobra/compare/v1.8.1...v1.9.1">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/build.yml b/.github/workflows/build.yml
index b83cca118..41c11b36a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -30,7 +30,7 @@ jobs:
           go-version: "1.23"
 
       - name: Set up Helm
-        uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4.3.0
+        uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
         with:
           version: v3.6.2
 
diff --git a/.github/workflows/daily-nightly-jobs.yml b/.github/workflows/daily-nightly-jobs.yml
index f42a7a1d6..47ae30eba 100644
--- a/.github/workflows/daily-nightly-jobs.yml
+++ b/.github/workflows/daily-nightly-jobs.yml
@@ -145,7 +145,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-smoke-suite-reef-artifact
@@ -185,7 +185,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-smoke-suite-squid-artifact
@@ -225,7 +225,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-smoke-suite-master-artifact
@@ -265,7 +265,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-object-suite-master-artifact
@@ -305,7 +305,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-upgrade-suite-squid-artifact
@@ -346,7 +346,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-upgrade-suite-reef-artifact
diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml
index 4f5aff093..7283819fb 100644
--- a/.github/workflows/helm-lint.yaml
+++ b/.github/workflows/helm-lint.yaml
@@ -31,7 +31,7 @@ jobs:
           fetch-depth: 0
 
       - name: Set up Helm
-        uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4.3.0
+        uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
         with:
           version: v3.6.2
 
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index 91f0accb6..65bccd344 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -33,7 +33,7 @@ jobs:
           persist-credentials: false
 
       - name: "Run analysis"
-        uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
+        uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
         with:
           results_file: results.sarif
           results_format: sarif
@@ -55,7 +55,7 @@ jobs:
       # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
       # format to the repository Actions tab.
       - name: "Upload artifact"
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         with:
           name: SARIF file
           path: results.sarif
@@ -64,6 +64,6 @@ jobs:
       # Upload the results to GitHub's code scanning dashboard (optional).
       # Commenting out will disable upload of results to your repo's Code Scanning dashboard
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10
+        uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
         with:
           sarif_file: results.sarif
diff --git a/Documentation/Helm-Charts/operator-chart.md b/Documentation/Helm-Charts/operator-chart.md
index 4307fc083..6b97e20c9 100644
--- a/Documentation/Helm-Charts/operator-chart.md
+++ b/Documentation/Helm-Charts/operator-chart.md
@@ -67,9 +67,7 @@ The following table lists the configurable parameters of the rook-operator chart
 | `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.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` |
 | `csi.csiCephFSPluginResource` | CEPH CSI CephFS plugin resource requirement list | see values.yaml |
 | `csi.csiCephFSPluginVolume` | The volume of the CephCSI CephFS plugin DaemonSet | `nil` |
 | `csi.csiCephFSPluginVolumeMount` | The volume mounts of the CephCSI CephFS plugin DaemonSet | `nil` |
diff --git a/Documentation/Upgrade/node-maintenance.md b/Documentation/Upgrade/node-maintenance.md
deleted file mode 100644
index 5aa2d0646..000000000
--- a/Documentation/Upgrade/node-maintenance.md
+++ /dev/null
@@ -1,162 +0,0 @@
----
-title: Node Maintenance
----
-
-This guide outlines a comprehensive procedure for safely shutting down, maintaining, and restarting a nodes in the Rook Ceph cluster.
-
-Although updating nodes by failure domain (such as zones or racks) is preferred to minimize downtime, this guide describes the full shutdown process if downtime is acceptable.
-
-## Overview
-
-The basic maintenance procedure involves the following steps:
-
-1. Stop I/O: Scale down all applications to stop any I/O activity to Ceph.
-2. Set Ceph Flags: Optionally set the noout (and related) flags to prevent Ceph from marking OSDs as out.
-3. Shutdown Ceph Components: Scale down all Ceph deployments (with mons being the last) while ensuring the operator is scaled down first.
-4. Perform Maintenance: Conduct the necessary maintenance on your nodes.
-5. Restart Ceph Components: Scale up Ceph deployments (starting with mons) and then bring up the operator.
-6. Unset Ceph Flags: Remove any flags that were set before the shutdown.
-7. Restart Applications: Scale applications back up to resume operations.
-
-## Pre-Maintenance Steps
-
-Backup & Notifications: Always ensure you have a recent backup and inform stakeholders of the planned downtime.
-
-Update Strategy: Whenever possible, plan node updates by failure domain to avoid full cluster downtime.
-
-### Environment
-
-These instructions will work for as long the environment is parameterized correctly.
-Set the following environment variables, which will be used throughout this document.
-
-```console
-# Parameterize the environment
-export ROOK_OPERATOR_NAMESPACE=rook-ceph
-export ROOK_CLUSTER_NAMESPACE=rook-ceph
-```
-
-## Shutdown Procedure
-
-### **1. Scale Down Applications**
-
-Before any Ceph-specific actions, scale down all applications interacting with Ceph to ensure no new I/O is initiated.
-
-### **2. Set Ceph Flags**
-
-Setting the noout flag (and any additional flags) can help prevent Ceph from marking OSDs as out during the maintenance window.
-
-```console
-kubectl -n $ROOK_CLUSTER_NAMESPACE exec -it deploy/rook-ceph-tools -- bash
-ceph osd set noout
-# Optionally, set other flags as needed (e.g., norebalance, nodown)
-```
-
-!!! tip
-    The ordering of Ceph flags is not critical. You may set them in any order during shutdown and unset them in reverse order during startup.
-
-### **3. Scale Down the Operator**
-
-Scale down the rook-ceph-operator first to avoid it automatically restarting deployments you are scaling down.
-
-```console
-kubectl -n $ROOK_OPERATOR_NAMESPACE scale deployment rook-ceph-operator --replicas=0
-```
-
-### **4. Scale Down Ceph Deployments**
-
-Scale down the Ceph components in a controlled order. For example, you may choose the following order:
-
-```console
-RGW deployments > CSI CephFS plugin provisioners > CSI RBD plugin provisioners > OSD deployments > MON deployments > MGR deployments
-```
-
-A script to scale these down looks like:
-
-```console
-for _category in rook-ceph-rgw csi-cephfsplugin-provisioner csi-rbdplugin-provisioner rook-ceph-osd rook-ceph-mon rook-ceph-mgr rook-ceph-exporter rook-ceph-crashcollector; do
-    for _item in $(kubectl get deployment -n rook-ceph | awk '/^'"${_category}"'/{print $1}'); do
-        kubectl -n rook-ceph scale deployment ${_item} --replicas=0;
-        while [[ $(kubectl get deployment -n rook-ceph ${_item} -o jsonpath='{.status.readyReplicas}') != "" ]]; do
-            sleep 5;
-        done;
-    done;
-done
-```
-
-### **5. Node Maintenance**
-
-With all Ceph components safely scaled down, you can now perform your node maintenance tasks such as OS upgrades, hardware replacements, or other planned updates.
-
-## Startup Procedure
-
-### **1. Scale Up Ceph Components**
-
-Bring up the Ceph deployments in the following order to help ensure a healthy state before the operator takes over:
-
-Scale up MON deployments first:
-
-```console
-for _item in $(kubectl get deployment -n $ROOK_CLUSTER_NAMESPACE | awk '/^rook-ceph-mon/{print $1}'); do
-    kubectl -n $ROOK_CLUSTER_NAMESPACE scale deployment ${_item} --replicas=1;
-    while [[ $(kubectl get deployment -n $ROOK_CLUSTER_NAMESPACE ${_item} -o jsonpath='{.status.replicas}') != "1" ]]; do
-        sleep 5;
-    done;
-done
-```
-
-Then scale up OSD and MGR deployments:
-
-```console
-for _category in rook-ceph-mgr rook-ceph-osd; do
-    for _item in $(kubectl get deployment -n $ROOK_CLUSTER_NAMESPACE | awk '/^'"${_category}"'/{print $1}'); do
-        kubectl -n $ROOK_CLUSTER_NAMESPACE scale deployment ${_item} --replicas=1;
-        while [[ $(kubectl get deployment -n $ROOK_CLUSTER_NAMESPACE ${_item} -o jsonpath='{.status.replicas}') != "1" ]]; do
-            sleep 5;
-        done;
-    done;
-done
-```
-
-Finally, scale up other deployments:
-
-```console
-for _category in rook-ceph-exporter rook-ceph-crashcollector; do
-    for _item in $(kubectl get deployment -n $ROOK_CLUSTER_NAMESPACE | awk '/^'"${_category}"'/{print $1}'); do
-        kubectl -n $ROOK_CLUSTER_NAMESPACE scale deployment ${_item} --replicas=1;
-        while [[ $(kubectl get deployment -n $ROOK_CLUSTER_NAMESPACE ${_item} -o jsonpath='{.status.replicas}') != "1" ]]; do
-            sleep 5;
-        done;
-    done;
-done
-```
-
-### **2. Scale Up the Operator**
-
-Once the Ceph components are stable and healthy, scale the operator back up to allow it to reconcile any remaining changes.
-
-```console
-kubectl -n $ROOK_OPERATOR_NAMESPACE scale deployment rook-ceph-operator --replicas=1
-```
-
-!!! tip
-    Bringing the operator up after the core components ensures a smoother reconciliation process.
-
-### **3. Unset Ceph Flags**
-
-After the Ceph cluster is back online and healthy, unset any flags that were previously set.
-
-```console
-kubectl -n $ROOK_CLUSTER_NAMESPACE exec -it deploy/rook-ceph-tools -- bash
-ceph osd unset noout
-# Unset any additional flags as necessary
-```
-
-### **4. Scale Up Applications**
-
-Finally, scale your applications back to their original replica count to resume normal operations.
-
-### CSI Plugins Behavior
-
-Observation: Even when the csi-cephfsplugin-provisioner and csi-rbdplugin-provisioner deployments are scaled to 0 replicas, the corresponding CSI plugin pods (from DaemonSets) remain running.
-
-Explanation: Scaling down the csi-cephfsplugin-provisioner and csi-rbdplugin-provisioner deployments prevents new provisioning requests, but the CSI plugin pods persist because they are managed by DaemonSets. Since DaemonSets are stateless, they can be deleted if needed, and the Rook operator will automatically recreate them when restarted. However, deletion is not required to stop provisioning.
diff --git a/deploy/charts/rook-ceph-cluster/templates/ingress.yaml b/deploy/charts/rook-ceph-cluster/templates/ingress.yaml
index f915575f4..6d86c5f1d 100644
--- a/deploy/charts/rook-ceph-cluster/templates/ingress.yaml
+++ b/deploy/charts/rook-ceph-cluster/templates/ingress.yaml
@@ -10,7 +10,7 @@ metadata:
   {{- end }}
 spec:
   rules:
-    - host: {{ .Values.ingress.dashboard.host.name | quote }}
+    - host: {{ .Values.ingress.dashboard.host.name }}
       http:
         paths:
           - path: {{ .Values.ingress.dashboard.host.path | default "/" }}
diff --git a/deploy/charts/rook-ceph/templates/configmap.yaml b/deploy/charts/rook-ceph/templates/configmap.yaml
index 03e79640f..576764acc 100644
--- a/deploy/charts/rook-ceph/templates/configmap.yaml
+++ b/deploy/charts/rook-ceph/templates/configmap.yaml
@@ -208,12 +208,6 @@ data:
 {{- if .Values.csi.csiAddonsPort }}
   CSIADDONS_PORT: {{ .Values.csi.csiAddonsPort | quote }}
 {{- end }}
-{{- if .Values.csi.csiAddonsRBDProvisionerPort }}
-  CSIADDONS_RBD_PROVISIONER_PORT: {{ .Values.csi.csiAddonsRBDProvisionerPort | quote }}
-{{- end }}
-{{- if .Values.csi.csiAddonsCephFSProvisionerPort }}
-  CSIADDONS_CEPHFS_PROVISIONER_PORT: {{ .Values.csi.csiAddonsCephFSProvisionerPort | quote }}
-{{- end }}
 {{- if .Values.csi.forceCephFSKernelClient }}
   CSI_FORCE_CEPHFS_KERNEL_CLIENT: {{ .Values.csi.forceCephFSKernelClient | quote }}
 {{- end }}
diff --git a/deploy/charts/rook-ceph/values.yaml b/deploy/charts/rook-ceph/values.yaml
index 4ce764357..16efe55a2 100644
--- a/deploy/charts/rook-ceph/values.yaml
+++ b/deploy/charts/rook-ceph/values.yaml
@@ -443,12 +443,6 @@ csi:
   # -- CSI Addons server port
   # @default -- `9070`
   csiAddonsPort:
-  # -- CSI Addons server port for the RBD provisioner
-  # @default -- `9070`
-  csiAddonsRBDProvisionerPort:
-  # -- CSI Addons server port for the Ceph FS provisioner
-  # @default -- `9070`
-  csiAddonsCephFSProvisionerPort:
 
   # -- Enable Ceph Kernel clients on kernel < 4.17. If your kernel does not support quotas for CephFS
   # you may want to disable this setting. However, this will cause an issue during upgrades
diff --git a/deploy/examples/operator.yaml b/deploy/examples/operator.yaml
index b1fcd62b3..5af25f6da 100644
--- a/deploy/examples/operator.yaml
+++ b/deploy/examples/operator.yaml
@@ -470,12 +470,7 @@ data:
   # CSI_CEPHFS_LIVENESS_METRICS_PORT: "9081"
   # Configure CSI RBD liveness metrics port
   # CSI_RBD_LIVENESS_METRICS_PORT: "9080"
-
-  # We can override the ports for each individual component that uses the CSIADDONS sidecar
-  # This is useful if we're running in hostNetwork, where ports may conflict on the same host
   # CSIADDONS_PORT: "9070"
-  # CSIADDONS_RBD_PROVISIONER_PORT: "9070"
-  # CSIADDONS_CEPHFS_PROVISIONER_PORT: "9070"
 
   # Set CephFS Kernel mount options to use https://docs.ceph.com/en/latest/man/8/mount.ceph/#options
   # Set to "ms_mode=secure" when connections.encrypted is enabled in CephCluster CR
@@ -577,9 +572,6 @@ data:
 
   # RevisionHistoryLimit value for all deployments created by rook.
   # ROOK_REVISION_HISTORY_LIMIT: "3"
-
-  #  Custom label to identify node hostname. If not set `kubernetes.io/hostname` will be used
-  ROOK_CUSTOM_HOSTNAME_LABEL: ""
 ---
 # OLM: BEGIN OPERATOR DEPLOYMENT
 apiVersion: apps/v1
@@ -660,6 +652,10 @@ spec:
             - name: ROOK_UNREACHABLE_NODE_TOLERATION_SECONDS
               value: "5"
 
+            #  Custom label to identify node hostname. If not set `kubernetes.io/hostname` will be used
+            - name: ROOK_CUSTOM_HOSTNAME_LABEL
+              value: ""
+
             # The name of the node to pass with the downward API
             - name: NODE_NAME
               valueFrom:
diff --git a/go.mod b/go.mod
index 2df00e5a9..089594663 100644
--- a/go.mod
+++ b/go.mod
@@ -20,23 +20,23 @@ require (
 	github.com/banzaicloud/k8s-objectmatcher v1.8.0
 	github.com/ceph/ceph-csi-operator/api v0.0.0-20241211130321-1c8ad98a7d6e
 	github.com/ceph/ceph-csi/api v0.0.0-20241216133622-88b7e0d6684f
-	github.com/ceph/go-ceph v0.31.0
+	github.com/ceph/go-ceph v0.32.0
 	github.com/coreos/pkg v0.0.0-20240122114842-bbd7aa9bf6fb
 	github.com/csi-addons/kubernetes-csi-addons v0.11.0
 	github.com/gemalto/kmip-go v0.0.10
 	github.com/go-ini/ini v1.67.0
-	github.com/google/go-cmp v0.6.0
+	github.com/google/go-cmp v0.7.0
 	github.com/google/uuid v1.6.0
-	github.com/hashicorp/vault/api v1.15.0
+	github.com/hashicorp/vault/api v1.16.0
 	github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5
 	github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20221122204822-d1a8c34382f1
 	github.com/libopenstorage/secrets v0.0.0-20240416031220-a17cf7f72c6c
 	github.com/pkg/errors v0.9.1
-	github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.0
-	github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.0
+	github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1
+	github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.1
 	github.com/rook/rook/pkg/apis v0.0.0-20241216163035-3170ac6a0c58
 	github.com/sethvargo/go-password v0.3.1
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.9.1
 	github.com/spf13/pflag v1.0.6
 	github.com/stretchr/testify v1.10.0
 	github.com/sykesm/zap-logfmt v0.0.4
@@ -68,6 +68,9 @@ require (
 	github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect
 	github.com/ansel1/merry v1.8.0 // indirect
 	github.com/ansel1/merry/v2 v2.2.1 // indirect
+	github.com/aws/aws-sdk-go-v2 v1.36.0 // indirect
+	github.com/aws/aws-sdk-go-v2/credentials v1.17.57 // indirect
+	github.com/aws/smithy-go v1.22.2 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/blang/semver/v4 v4.0.0 // indirect
 	github.com/cenkalti/backoff/v4 v4.3.0 // indirect
@@ -82,7 +85,7 @@ require (
 	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
 	github.com/gemalto/flume v0.13.1 // indirect
 	github.com/go-errors/errors v1.5.1 // indirect
-	github.com/go-jose/go-jose/v4 v4.0.5 // indirect
+	github.com/go-jose/go-jose/v4 v4.0.4 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-logr/zapr v1.3.0 // indirect
 	github.com/go-openapi/jsonpointer v0.21.0 // indirect
diff --git a/go.sum b/go.sum
index c7b3fec4d..7bcd17803 100644
--- a/go.sum
+++ b/go.sum
@@ -148,6 +148,42 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l
 github.com/aws/aws-sdk-go v1.44.164/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk=
 github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
+github.com/aws/aws-sdk-go-v2 v1.36.0 h1:b1wM5CcE65Ujwn565qcwgtOTT1aT4ADOHHgglKjG7fk=
+github.com/aws/aws-sdk-go-v2 v1.36.0/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
+github.com/aws/aws-sdk-go-v2/config v1.29.4 h1:ObNqKsDYFGr2WxnoXKOhCvTlf3HhwtoGgc+KmZ4H5yg=
+github.com/aws/aws-sdk-go-v2/config v1.29.4/go.mod h1:j2/AF7j/qxVmsNIChw1tWfsVKOayJoGRDjg1Tgq7NPk=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.57 h1:kFQDsbdBAR3GZsB8xA+51ptEnq9TIj3tS4MuP5b+TcQ=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.57/go.mod h1:2kerxPUUbTagAr/kkaHiqvj/bcYHzi2qiJS/ZinllU0=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 h1:7lOW8NUwE9UZekS1DYoiPdVAqZ6A+LheHWb+mHbNOq8=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27/go.mod h1:w1BASFIPOPUae7AgaH4SbjNbfdkxuggLyGfNFTn8ITY=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 h1:lWm9ucLSRFiI4dQQafLrEOmEDGry3Swrz0BIRdiHJqQ=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31/go.mod h1:Huu6GG0YTfbPphQkDSo4dEGmQRTKb9k9G7RdtyQWxuI=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 h1:ACxDklUKKXb48+eg5ROZXi1vDgfMyfIA/WyvqHcHI0o=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31/go.mod h1:yadnfsDwqXeVaohbGc/RaD287PuyRw2wugkh5ZL2J6k=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 h1:GeNJsIFHB+WW5ap2Tec4K6dzcVTsRbsT1Lra46Hv9ME=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26/go.mod h1:zfgMpwHDXX2WGoG84xG2H+ZlPTkJUU4YUvx2svLQYWo=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 h1:D4oz8/CzT9bAEYtVhSBmFj2dNOtaHOtMKc2vHBwYizA=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2/go.mod h1:Za3IHqTQ+yNcRHxu1OFucBh0ACZT4j4VQFF0BqpZcLY=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 h1:tB4tNw83KcajNAzaIMhkhVI2Nt8fAZd5A5ro113FEMY=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7/go.mod h1:lvpyBGkZ3tZ9iSsUIcC2EWp+0ywa7aK3BLT+FwZi+mQ=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 h1:O+8vD2rGjfihBewr5bT+QUfYUHIxCVgG61LHoT59shM=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12/go.mod h1:usVdWJaosa66NMvmCrr08NcWDBRv4E6+YFG2pUdw1Lk=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 h1:Hi0KGbrnr57bEHWM0bJ1QcBzxLrL/k2DHvGYhb8+W1w=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7/go.mod h1:wKNgWgExdjjrm4qvfbTorkvocEstaoDl4WCvGfeCy9c=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 h1:SAfh4pNx5LuTafKKWR02Y+hL3A+3TX8cTKG1OIAJaBk=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q=
+github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 h1:c5WJ3iHz7rLIgArznb3JCSQT3uUMiz9DLZhIX+1G8ok=
+github.com/aws/aws-sdk-go-v2/service/sso v1.24.14/go.mod h1:+JJQTxB6N4niArC14YNtxcQtwEqzS3o9Z32n7q33Rfs=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 h1:f1L/JtUkVODD+k1+IiSJUUv8A++2qVr+Xvb3xWXETMU=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13/go.mod h1:tvqlFoja8/s0o+UruA1Nrezo/df0PzdunMDDurUfg6U=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.12 h1:fqg6c1KVrc3SYWma/egWue5rKI4G2+M4wMQN2JosNAA=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.12/go.mod h1:7Yn+p66q/jt38qMoVfNvjbm3D89mGBnkwDcijgtih8w=
+github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
+github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
 github.com/banzaicloud/k8s-objectmatcher v1.8.0 h1:Nugn25elKtPMTA2br+JgHNeSQ04sc05MDPmpJnd1N2A=
 github.com/banzaicloud/k8s-objectmatcher v1.8.0/go.mod h1:p2LSNAjlECf07fbhDyebTkPUIYnU05G+WfGgkTmgeMg=
 github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
@@ -171,8 +207,8 @@ github.com/ceph/ceph-csi-operator/api v0.0.0-20241211130321-1c8ad98a7d6e h1:Qoca
 github.com/ceph/ceph-csi-operator/api v0.0.0-20241211130321-1c8ad98a7d6e/go.mod h1:odEUoarG26wXBCC2l4O4nMWhAz6VTKr2FRkv9yELgi8=
 github.com/ceph/ceph-csi/api v0.0.0-20241216133622-88b7e0d6684f h1:ja5xvJlv3Sq5dlQVQMeM/dlCwcUXgZXg/kTPmMMQhJ8=
 github.com/ceph/ceph-csi/api v0.0.0-20241216133622-88b7e0d6684f/go.mod h1:NfzKbdhaXhWh1PJCExML9dAXHCqEDppf26ueLWYdxlk=
-github.com/ceph/go-ceph v0.31.0 h1:3yqMVsRN89VyMhJ+qiF91mQHw4RBjbWVVERGX7bYxkk=
-github.com/ceph/go-ceph v0.31.0/go.mod h1:VnMYp08oE2o2of29p/oGkxnM8VNF/+LJyVQ5pZSj3Wg=
+github.com/ceph/go-ceph v0.32.0 h1:iXRUGdPmH7h9Vf/WA1Dg3Wo1tgL7gcUbylfpbxrlGLs=
+github.com/ceph/go-ceph v0.32.0/go.mod h1:42eoJzyLS3VREzqrg2ot44NtuluQZi55hFRSoLF36GQ=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@@ -211,7 +247,7 @@ github.com/coreos/pkg v0.0.0-20240122114842-bbd7aa9bf6fb h1:GIzvVQ9UkUlOhSDlqmrQ
 github.com/coreos/pkg v0.0.0-20240122114842-bbd7aa9bf6fb/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
 github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
@@ -294,8 +330,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
 github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
 github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
 github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
-github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
-github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
+github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
+github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@@ -441,8 +477,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -558,8 +594,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
 github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hashicorp/vault/api v1.10.0/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8=
-github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA=
-github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8=
+github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4=
+github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA=
 github.com/hashicorp/vault/api/auth/approle v0.5.0/go.mod h1:CHOQIA1AZACfjTzHggmyfiOZ+xCSKNRFqe48FTCzH0k=
 github.com/hashicorp/vault/api/auth/approle v0.8.0 h1:FuVtWZ0xD6+wz1x0l5s0b4852RmVXQNEiKhVXt6lfQY=
 github.com/hashicorp/vault/api/auth/approle v0.8.0/go.mod h1:NV7O9r5JUtNdVnqVZeMHva81AIdpG0WoIQohNt1VCPM=
@@ -783,11 +819,11 @@ github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4
 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.44.1/go.mod h1:3WYi4xqXxGGXWDdQIITnLNmuDzO5n6wYva9spVhR4fg=
 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.46.0/go.mod h1:3WYi4xqXxGGXWDdQIITnLNmuDzO5n6wYva9spVhR4fg=
-github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.0 h1:ckSycH7xHtpcvXsmEY/qEziRhDQKqKqbsHi9kX/BO7A=
-github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.0/go.mod h1:6x4x0t9BP35g4XcjkHE9EB3RxhyfxpdpmZKd/Qyk8+M=
+github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1 h1:DP+PUNVOc+Bkft8a4QunLzaZ0RspWuD3tBbcPHr2PeE=
+github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1/go.mod h1:6x4x0t9BP35g4XcjkHE9EB3RxhyfxpdpmZKd/Qyk8+M=
 github.com/prometheus-operator/prometheus-operator/pkg/client v0.46.0/go.mod h1:k4BrWlVQQsvBiTcDnKEMgyh/euRxyxgrHdur/ZX/sdA=
-github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.0 h1:TvrTp81Ra7c3n+P4tArjx/st9x92q1BlxfjhqeP3aSA=
-github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.0/go.mod h1:G2GGhVurNB5qQh7DZVSAtdN4Szvp6IxWhc1+n2rclw4=
+github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.1 h1:7/TPlTy7tkMXC1KwS2WdUdU8J220DszlSQ1+KHjXwHc=
+github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.1/go.mod h1:0lW4yp2XE7AKohpGB2UGdomjP08rbr4f8JwAN6sUDWU=
 github.com/prometheus/client_golang v0.9.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
@@ -861,8 +897,8 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3
 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
 github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
diff --git a/pkg/apis/go.mod b/pkg/apis/go.mod
index d16bc64b4..9c59e4ba8 100644
--- a/pkg/apis/go.mod
+++ b/pkg/apis/go.mod
@@ -15,7 +15,7 @@ replace (
 )
 
 require (
-	github.com/hashicorp/vault/api v1.15.0
+	github.com/hashicorp/vault/api v1.16.0
 	github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5
 	github.com/kube-object-storage/lib-bucket-provisioner v0.0.0-20221122204822-d1a8c34382f1
 	github.com/libopenstorage/secrets v0.0.0-20240416031220-a17cf7f72c6c
@@ -33,7 +33,7 @@ require (
 	github.com/emicklei/go-restful/v3 v3.12.1 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
 	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
-	github.com/go-jose/go-jose/v4 v4.0.5 // indirect
+	github.com/go-jose/go-jose/v4 v4.0.4 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-openapi/jsonpointer v0.21.0 // indirect
 	github.com/go-openapi/jsonreference v0.21.0 // indirect
@@ -41,7 +41,7 @@ require (
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/google/gnostic-models v0.6.9 // indirect
-	github.com/google/go-cmp v0.6.0 // indirect
+	github.com/google/go-cmp v0.7.0 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/uuid v1.6.0 // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
diff --git a/pkg/apis/go.sum b/pkg/apis/go.sum
index 24b58e74d..8064afe4f 100644
--- a/pkg/apis/go.sum
+++ b/pkg/apis/go.sum
@@ -219,8 +219,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
-github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
-github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
+github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
+github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@@ -359,8 +359,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -468,8 +468,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
 github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hashicorp/vault/api v1.10.0/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8=
-github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA=
-github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8=
+github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4=
+github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA=
 github.com/hashicorp/vault/api/auth/approle v0.5.0/go.mod h1:CHOQIA1AZACfjTzHggmyfiOZ+xCSKNRFqe48FTCzH0k=
 github.com/hashicorp/vault/api/auth/approle v0.8.0 h1:FuVtWZ0xD6+wz1x0l5s0b4852RmVXQNEiKhVXt6lfQY=
 github.com/hashicorp/vault/api/auth/approle v0.8.0/go.mod h1:NV7O9r5JUtNdVnqVZeMHva81AIdpG0WoIQohNt1VCPM=
diff --git a/pkg/operator/ceph/cluster/controller.go b/pkg/operator/ceph/cluster/controller.go
index f499cccce..11eecc632 100644
--- a/pkg/operator/ceph/cluster/controller.go
+++ b/pkg/operator/ceph/cluster/controller.go
@@ -187,7 +187,10 @@ func add(opManagerContext context.Context, mgr manager.Manager, r reconcile.Reco
 
 	// Watch for changes on the hotplug config map
 	// TODO: to improve, can we run this against the operator namespace only?
-	disableVal := k8sutil.GetOperatorSetting(disableHotplugEnv, "false")
+	disableVal, err := k8sutil.GetOperatorSetting(opManagerContext, context.Clientset, opcontroller.OperatorSettingConfigMapName, disableHotplugEnv, "false")
+	if err != nil {
+		logger.Errorf("failed to get %s setting %s. %v", disableHotplugEnv, opcontroller.OperatorSettingConfigMapName, err)
+	}
 	if disableVal != "true" {
 		logger.Info("enabling hotplug orchestration")
 		s := source.Kind[client.Object](
diff --git a/pkg/operator/ceph/cluster/osd/osd.go b/pkg/operator/ceph/cluster/osd/osd.go
index 188659da9..04d91ca8e 100644
--- a/pkg/operator/ceph/cluster/osd/osd.go
+++ b/pkg/operator/ceph/cluster/osd/osd.go
@@ -88,7 +88,6 @@ type Cluster struct {
 	deviceSets     []deviceSet
 	migrateOSD     *OSDInfo
 	deprecatedOSDs map[string][]int
-	nodeConfigmaps map[string]struct{}
 }
 
 // New creates an instance of the OSD manager
@@ -207,9 +206,6 @@ func (c *Cluster) Start() error {
 	if err := c.validateOSDSettings(); err != nil {
 		return err
 	}
-	if err := c.initializeNodeConfigmaps(); err != nil {
-		return err
-	}
 	logger.Infof("start running osds in namespace %q", namespace)
 
 	if !c.spec.Storage.UseAllNodes && len(c.spec.Storage.Nodes) == 0 && len(c.spec.Storage.StorageClassDeviceSets) == 0 {
@@ -1057,24 +1053,3 @@ func getOSDLocationFromArgs(args []string) (string, bool) {
 
 	return "", false
 }
-
-func (c *Cluster) initializeNodeConfigmaps() error {
-	// Find existing configmaps matching the label
-	label := "node.config.rook.io/osd"
-	options := metav1.ListOptions{LabelSelector: label}
-	configmaps, err := c.context.Clientset.CoreV1().ConfigMaps(c.clusterInfo.Namespace).List(c.clusterInfo.Context, options)
-	if err != nil {
-		return errors.Wrapf(err, "failed to list configmaps in namespace %q with label %q", c.clusterInfo.Namespace, label)
-	}
-
-	c.nodeConfigmaps = map[string]struct{}{}
-	prefix := k8sutil.ConfigOverrideName + "-"
-	for _, configmap := range configmaps.Items {
-		if strings.HasPrefix(configmap.Name, prefix) {
-			nodeName := strings.TrimPrefix(configmap.Name, prefix)
-			logger.Infof("found node %q configmap, will mount it for alternate ceph conf overrides for osds on this node", nodeName)
-			c.nodeConfigmaps[nodeName] = struct{}{}
-		}
-	}
-	return nil
-}
diff --git a/pkg/operator/ceph/cluster/osd/provision_spec.go b/pkg/operator/ceph/cluster/osd/provision_spec.go
index 81166ca95..01b70b62e 100644
--- a/pkg/operator/ceph/cluster/osd/provision_spec.go
+++ b/pkg/operator/ceph/cluster/osd/provision_spec.go
@@ -104,7 +104,6 @@ func (c *Cluster) provisionPodTemplateSpec(osdProps osdProperties, restart v1.Re
 	// ceph-volume is currently set up to use /etc/ceph/ceph.conf; this means no user config
 	// overrides will apply to ceph-volume, but this is unnecessary anyway
 	volumes := append(controller.PodVolumes(provisionConfig.DataPathMap, c.spec.DataDirHostPath, c.spec.DataDirHostPath, true), copyBinariesVolume)
-	volumes = c.updateCephConfigVolume(volumes, osdProps.crushHostname)
 
 	// create a volume on /dev so the pod can access devices on the host
 	devVolume := v1.Volume{Name: "devices", VolumeSource: v1.VolumeSource{HostPath: &v1.HostPathVolumeSource{Path: "/dev"}}}
diff --git a/pkg/operator/ceph/cluster/osd/spec.go b/pkg/operator/ceph/cluster/osd/spec.go
index 37c56fb9b..ac4aeaeb9 100644
--- a/pkg/operator/ceph/cluster/osd/spec.go
+++ b/pkg/operator/ceph/cluster/osd/spec.go
@@ -328,24 +328,6 @@ func deploymentName(osdID int) string {
 	return fmt.Sprintf(osdAppNameFmt, osdID)
 }
 
-func (c *Cluster) updateCephConfigVolume(volumes []v1.Volume, nodeName string) []v1.Volume {
-	if _, ok := c.nodeConfigmaps[nodeName]; !ok {
-		logger.Debugf("no configmap to override for node %q", nodeName)
-		return volumes
-	}
-
-	updatedVolumes := []v1.Volume{}
-	for _, volume := range volumes {
-		if volume.Name == k8sutil.ConfigOverrideName {
-			logger.Debugf("found configmap volume to override for node %q", nodeName)
-			name := fmt.Sprintf("%s-%s", k8sutil.ConfigOverrideName, nodeName)
-			volume.VolumeSource.Projected.Sources[0].ConfigMap.LocalObjectReference.Name = name
-		}
-		updatedVolumes = append(updatedVolumes, volume)
-	}
-	return updatedVolumes
-}
-
 func (c *Cluster) makeDeployment(osdProps osdProperties, osd *OSDInfo, provisionConfig *provisionConfig) (*apps.Deployment, error) {
 	deploymentName := deploymentName(osd.ID)
 	replicaCount := int32(1)
@@ -357,8 +339,6 @@ func (c *Cluster) makeDeployment(osdProps osdProperties, osd *OSDInfo, provision
 		dataDirHostPath = ""
 	}
 	volumes := controller.PodVolumes(provisionConfig.DataPathMap, dataDirHostPath, c.spec.DataDirHostPath, false)
-	volumes = c.updateCephConfigVolume(volumes, osdProps.crushHostname)
-
 	failureDomainValue := osdProps.crushHostname
 	doConfigInit := true     // initialize ceph.conf in init container?
 	doBinaryCopyInit := true // copy rook binary in an init container?
diff --git a/pkg/operator/ceph/cluster/watcher.go b/pkg/operator/ceph/cluster/watcher.go
index c5ee33184..57363bfa2 100644
--- a/pkg/operator/ceph/cluster/watcher.go
+++ b/pkg/operator/ceph/cluster/watcher.go
@@ -159,21 +159,27 @@ func (c *clientCluster) onK8sNode(ctx context.Context, object runtime.Object, op
 }
 
 func (c *clientCluster) handleNodeFailure(ctx context.Context, cluster *cephv1.CephCluster, node *corev1.Node, opNamespace string) error {
-	watchForNodeLoss := k8sutil.GetOperatorSetting("ROOK_WATCH_FOR_NODE_FAILURE", "true")
+	watchForNodeLoss, err := k8sutil.GetOperatorSetting(ctx, c.context.Clientset, opcontroller.OperatorSettingConfigMapName, "ROOK_WATCH_FOR_NODE_FAILURE", "true")
+	if err != nil {
+		return pkgerror.Wrapf(err, "failed to get configmap value `ROOK_WATCH_FOR_NODE_FAILURE`.")
+	}
 
 	if strings.ToLower(watchForNodeLoss) != "true" {
 		logger.Debugf("not watching for node failures since `ROOK_WATCH_FOR_NODE_FAILURE` is set to %q", watchForNodeLoss)
 		return nil
 	}
 
-	disabledCSI := k8sutil.GetOperatorSetting("ROOK_CSI_DISABLE_DRIVER", "false")
+	disabledCSI, err := k8sutil.GetOperatorSetting(ctx, c.context.Clientset, opcontroller.OperatorSettingConfigMapName, "ROOK_CSI_DISABLE_DRIVER", "false")
+	if err != nil {
+		return pkgerror.Wrapf(err, "failed to get configmap value `ROOK_CSI_DISABLE_DRIVER`.")
+	}
 
 	if strings.ToLower(disabledCSI) != "false" {
 		logger.Debugf("not watching for node failures since `ROOK_CSI_DISABLE_DRIVER` is set to %q, skip creating networkFence", disabledCSI)
 		return nil
 	}
 
-	_, err := c.context.ApiExtensionsClient.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, "networkfences.csiaddons.openshift.io", metav1.GetOptions{})
+	_, err = c.context.ApiExtensionsClient.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, "networkfences.csiaddons.openshift.io", metav1.GetOptions{})
 	if err != nil {
 		if errors.IsNotFound(err) {
 			logger.Debug("networkfences.csiaddons.openshift.io CRD not found, skip creating networkFence")
diff --git a/pkg/operator/ceph/controller.go b/pkg/operator/ceph/controller.go
index 5aa86f336..879a51b2e 100644
--- a/pkg/operator/ceph/controller.go
+++ b/pkg/operator/ceph/controller.go
@@ -33,6 +33,7 @@ import (
 	"github.com/rook/rook/pkg/operator/k8sutil"
 	"github.com/rook/rook/pkg/util"
 	v1 "k8s.io/api/core/v1"
+	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -102,43 +103,52 @@ func (r *ReconcileConfig) Reconcile(context context.Context, request reconcile.R
 
 func (r *ReconcileConfig) reconcile(request reconcile.Request) (reconcile.Result, error) {
 	// Fetch the operator's configmap
+	opConfig := &v1.ConfigMap{}
 	logger.Debugf("reconciling %s", request.NamespacedName)
-	if request.Name == opcontroller.OperatorSettingConfigMapName {
-		if err := k8sutil.ApplyOperatorSettingsConfigmap(r.opManagerContext, r.context.Clientset); err != nil {
-			return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed to get operator setting configmap")
+	err := r.client.Get(r.opManagerContext, request.NamespacedName, opConfig)
+	if err != nil {
+		if kerrors.IsNotFound(err) {
+			logger.Debug("operator's configmap resource not found. will use default value or env var.")
+		} else {
+			// Error reading the object - requeue the request.
+			return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed to get operator's configmap")
 		}
+	} else {
+		// Populate the operator's config
+		r.config.Parameters = opConfig.Data
 	}
+
 	// Reconcile Ceph CLI timeout, since the clusterd context is passed to by pointer to all CRD
 	// controllers they will receive the update
-	opcontroller.SetCephCommandsTimeout()
+	opcontroller.SetCephCommandsTimeout(r.config.Parameters)
 
 	// Reconcile Operator's logging level
-	reconcileOperatorLogLevel()
+	reconcileOperatorLogLevel(opConfig.Data)
 
 	// Reconcile discovery daemon
-	err := r.reconcileDiscoveryDaemon()
+	err = r.reconcileDiscoveryDaemon(opConfig.Data)
 	if err != nil {
 		return opcontroller.ImmediateRetryResult, err
 	}
 
-	opcontroller.SetAllowLoopDevices()
-	opcontroller.SetEnforceHostNetwork()
-	opcontroller.SetRevisionHistoryLimit()
-	opcontroller.SetObcAllowAdditionalConfigFields()
+	opcontroller.SetAllowLoopDevices(r.config.Parameters)
+	opcontroller.SetEnforceHostNetwork(r.config.Parameters)
+	opcontroller.SetRevisionHistoryLimit(r.config.Parameters)
+	opcontroller.SetObcAllowAdditionalConfigFields(r.config.Parameters)
 
 	logger.Infof("%s done reconciling", controllerName)
 	return reconcile.Result{}, nil
 }
 
-func reconcileOperatorLogLevel() {
-	rookLogLevel := k8sutil.GetOperatorSetting("ROOK_LOG_LEVEL", util.DefaultLogLevel.String())
+func reconcileOperatorLogLevel(data map[string]string) {
+	rookLogLevel := k8sutil.GetValue(data, "ROOK_LOG_LEVEL", util.DefaultLogLevel.String())
 	util.SetGlobalLogLevel(rookLogLevel, logger)
 }
 
-func (r *ReconcileConfig) reconcileDiscoveryDaemon() error {
+func (r *ReconcileConfig) reconcileDiscoveryDaemon(data map[string]string) error {
 	rookDiscover := discover.New(r.context.Clientset)
-	if opcontroller.DiscoveryDaemonEnabled() {
-		if err := rookDiscover.Start(r.opManagerContext, r.config.OperatorNamespace, r.config.Image, r.config.ServiceAccount, true); err != nil {
+	if opcontroller.DiscoveryDaemonEnabled(r.config.Parameters) {
+		if err := rookDiscover.Start(r.opManagerContext, r.config.OperatorNamespace, r.config.Image, r.config.ServiceAccount, data, true); err != nil {
 			return errors.Wrap(err, "failed to start device discovery daemonset")
 		}
 	} else {
diff --git a/pkg/operator/ceph/controller/controller_utils.go b/pkg/operator/ceph/controller/controller_utils.go
index d55d00124..8cb661d74 100644
--- a/pkg/operator/ceph/controller/controller_utils.go
+++ b/pkg/operator/ceph/controller/controller_utils.go
@@ -40,6 +40,7 @@ type OperatorConfig struct {
 	Image             string
 	ServiceAccount    string
 	NamespaceToWatch  string
+	Parameters        map[string]string
 }
 
 // ClusterHealth is passed to the various monitoring go routines to stop them when the context is cancelled
@@ -98,13 +99,13 @@ var (
 	obcAllowAdditionalConfigFields = strings.Split(obcAllowAdditionalConfigFieldsDefaultValue, ",")
 )
 
-func DiscoveryDaemonEnabled() bool {
-	return k8sutil.GetOperatorSetting("ROOK_ENABLE_DISCOVERY_DAEMON", "false") == "true"
+func DiscoveryDaemonEnabled(data map[string]string) bool {
+	return k8sutil.GetValue(data, "ROOK_ENABLE_DISCOVERY_DAEMON", "false") == "true"
 }
 
 // SetCephCommandsTimeout sets the timeout value of Ceph commands which are executed from Rook
-func SetCephCommandsTimeout() {
-	strTimeoutSeconds := k8sutil.GetOperatorSetting("ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS", "15")
+func SetCephCommandsTimeout(data map[string]string) {
+	strTimeoutSeconds := k8sutil.GetValue(data, "ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS", "15")
 	timeoutSeconds, err := strconv.Atoi(strTimeoutSeconds)
 	if err != nil || timeoutSeconds < 1 {
 		logger.Warningf("ROOK_CEPH_COMMANDS_TIMEOUT is %q but it should be >= 1, set the default value 15", strTimeoutSeconds)
@@ -113,8 +114,8 @@ func SetCephCommandsTimeout() {
 	exec.CephCommandsTimeout = time.Duration(timeoutSeconds) * time.Second
 }
 
-func SetAllowLoopDevices() {
-	strLoopDevicesAllowed := k8sutil.GetOperatorSetting("ROOK_CEPH_ALLOW_LOOP_DEVICES", "false")
+func SetAllowLoopDevices(data map[string]string) {
+	strLoopDevicesAllowed := k8sutil.GetValue(data, "ROOK_CEPH_ALLOW_LOOP_DEVICES", "false")
 	var err error
 	loopDevicesAllowed, err = strconv.ParseBool(strLoopDevicesAllowed)
 	if err != nil {
@@ -127,8 +128,8 @@ func LoopDevicesAllowed() bool {
 	return loopDevicesAllowed
 }
 
-func SetEnforceHostNetwork() {
-	strval := k8sutil.GetOperatorSetting(enforceHostNetworkSettingName, enforceHostNetworkDefaultValue)
+func SetEnforceHostNetwork(data map[string]string) {
+	strval := k8sutil.GetValue(data, enforceHostNetworkSettingName, enforceHostNetworkDefaultValue)
 	val, err := strconv.ParseBool(strval)
 	if err != nil {
 		logger.Warningf("failed to parse value %q for %q. assuming false value", strval, enforceHostNetworkSettingName)
@@ -142,8 +143,8 @@ func EnforceHostNetwork() bool {
 	return cephv1.EnforceHostNetwork()
 }
 
-func SetRevisionHistoryLimit() {
-	strval := k8sutil.GetOperatorSetting(revisionHistoryLimitSettingName, "")
+func SetRevisionHistoryLimit(data map[string]string) {
+	strval := k8sutil.GetValue(data, revisionHistoryLimitSettingName, "")
 	var limit int32
 	if strval == "" {
 		logger.Debugf("not parsing empty string to int for %q. assuming default value.", revisionHistoryLimitSettingName)
@@ -165,8 +166,8 @@ func RevisionHistoryLimit() *int32 {
 	return revisionHistoryLimit
 }
 
-func SetObcAllowAdditionalConfigFields() {
-	strval := k8sutil.GetOperatorSetting(obcAllowAdditionalConfigFieldsSettingName, obcAllowAdditionalConfigFieldsDefaultValue)
+func SetObcAllowAdditionalConfigFields(data map[string]string) {
+	strval := k8sutil.GetValue(data, obcAllowAdditionalConfigFieldsSettingName, obcAllowAdditionalConfigFieldsDefaultValue)
 	obcAllowAdditionalConfigFields = strings.Split(strval, ",")
 }
 
diff --git a/pkg/operator/ceph/cr_manager.go b/pkg/operator/ceph/cr_manager.go
index 21d9e4860..b3398d681 100644
--- a/pkg/operator/ceph/cr_manager.go
+++ b/pkg/operator/ceph/cr_manager.go
@@ -143,7 +143,11 @@ func (o *Operator) startCRDManager(context context.Context, mgrErrorCh chan erro
 		}
 	}
 
-	metricsBindAddress := k8sutil.GetOperatorSetting("ROOK_OPERATOR_METRICS_BIND_ADDRESS", "0")
+	metricsBindAddress, err := k8sutil.GetOperatorSetting(context, o.context.Clientset, opcontroller.OperatorSettingConfigMapName, "ROOK_OPERATOR_METRICS_BIND_ADDRESS", "0")
+	if err != nil {
+		mgrErrorCh <- errors.Wrap(err, "failed to get configmap value `ROOK_OPERATOR_METRICS_BIND_ADDRESS`.")
+		return
+	}
 	skipNameValidation := true
 	// Set up a manager
 	mgrOpts := manager.Options{
diff --git a/pkg/operator/ceph/csi/controller.go b/pkg/operator/ceph/csi/controller.go
index 809b2da4d..b9c6c5034 100644
--- a/pkg/operator/ceph/csi/controller.go
+++ b/pkg/operator/ceph/csi/controller.go
@@ -42,6 +42,7 @@ import (
 	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/types"
 )
 
 const (
@@ -157,17 +158,32 @@ func (r *ReconcileCSI) reconcile(request reconcile.Request) (reconcile.Result, e
 		return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed creating csi config map")
 	}
 
-	if err := k8sutil.ApplyOperatorSettingsConfigmap(r.opManagerContext, r.context.Clientset); err != nil {
-		return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed to apply operator settings configmap")
+	// Fetch the operator's configmap. We force the NamespaceName to the operator since the request
+	// could be a CephCluster. If so the NamespaceName will be the one from the cluster and thus the
+	// CM won't be found
+	opNamespaceName := types.NamespacedName{Name: opcontroller.OperatorSettingConfigMapName, Namespace: r.opConfig.OperatorNamespace}
+	opConfig := &v1.ConfigMap{}
+	err = r.client.Get(r.opManagerContext, opNamespaceName, opConfig)
+	if err != nil {
+		if kerrors.IsNotFound(err) {
+			logger.Debug("operator's configmap resource not found. will use default value or env var.")
+			r.opConfig.Parameters = make(map[string]string)
+		} else {
+			// Error reading the object - requeue the request.
+			return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed to get operator's configmap")
+		}
+	} else {
+		// Populate the operator's config
+		r.opConfig.Parameters = opConfig.Data
 	}
 
-	enableCSIOperator, err = strconv.ParseBool(k8sutil.GetOperatorSetting("ROOK_USE_CSI_OPERATOR", "false"))
+	enableCSIOperator, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "ROOK_USE_CSI_OPERATOR", "false"))
 	if err != nil {
 		return reconcileResult, errors.Wrap(err, "unable to parse value for 'ROOK_USE_CSI_OPERATOR'")
 	}
 
 	// do not recocnile if csi driver is disabled
-	disableCSI, err := strconv.ParseBool(k8sutil.GetOperatorSetting("ROOK_CSI_DISABLE_DRIVER", "false"))
+	disableCSI, err := strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_DISABLE_DRIVER", "false"))
 	if err != nil {
 		return reconcile.Result{}, errors.Wrap(err, "unable to parse value for 'ROOK_CSI_DISABLE_DRIVER")
 	} else if disableCSI {
diff --git a/pkg/operator/ceph/csi/csi.go b/pkg/operator/ceph/csi/csi.go
index 6919eaf54..9769a519f 100644
--- a/pkg/operator/ceph/csi/csi.go
+++ b/pkg/operator/ceph/csi/csi.go
@@ -56,31 +56,31 @@ func (r *ReconcileCSI) validateAndConfigureDrivers(ownerInfo *k8sutil.OwnerInfo)
 func (r *ReconcileCSI) setParams() error {
 	var err error
 
-	if EnableRBD, err = strconv.ParseBool(k8sutil.GetOperatorSetting("ROOK_CSI_ENABLE_RBD", "true")); err != nil {
+	if EnableRBD, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_ENABLE_RBD", "true")); err != nil {
 		return errors.Wrap(err, "unable to parse value for 'ROOK_CSI_ENABLE_RBD'")
 	}
 
-	if EnableCephFS, err = strconv.ParseBool(k8sutil.GetOperatorSetting("ROOK_CSI_ENABLE_CEPHFS", "true")); err != nil {
+	if EnableCephFS, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_ENABLE_CEPHFS", "true")); err != nil {
 		return errors.Wrap(err, "unable to parse value for 'ROOK_CSI_ENABLE_CEPHFS'")
 	}
 
-	if EnableNFS, err = strconv.ParseBool(k8sutil.GetOperatorSetting("ROOK_CSI_ENABLE_NFS", "false")); err != nil {
+	if EnableNFS, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_ENABLE_NFS", "false")); err != nil {
 		return errors.Wrap(err, "unable to parse value for 'ROOK_CSI_ENABLE_NFS'")
 	}
 
-	if CSIParam.EnableCSIHostNetwork, err = strconv.ParseBool(k8sutil.GetOperatorSetting("CSI_ENABLE_HOST_NETWORK", "true")); err != nil {
+	if CSIParam.EnableCSIHostNetwork, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_HOST_NETWORK", "true")); err != nil {
 		return errors.Wrap(err, "failed to parse value for 'CSI_ENABLE_HOST_NETWORK'")
 	}
 
 	// If not set or set to anything but "false", the kernel client will be enabled
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_FORCE_CEPHFS_KERNEL_CLIENT", "true"), "false") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_FORCE_CEPHFS_KERNEL_CLIENT", "true"), "false") {
 		CSIParam.ForceCephFSKernelClient = "false"
 	} else {
 		CSIParam.ForceCephFSKernelClient = "true"
 	}
 
 	// parse RPC timeout
-	timeout := k8sutil.GetOperatorSetting(grpcTimeout, "150")
+	timeout := k8sutil.GetValue(r.opConfig.Parameters, grpcTimeout, "150")
 	timeoutSeconds, err := strconv.Atoi(timeout)
 	if err != nil {
 		logger.Errorf("failed to parse %q. Defaulting to %d. %v", grpcTimeout, defaultGRPCTimeout, err)
@@ -93,32 +93,20 @@ func (r *ReconcileCSI) setParams() error {
 	CSIParam.GRPCTimeout = time.Duration(timeoutSeconds) * time.Second
 
 	// parse Liveness port
-	CSIParam.CephFSLivenessMetricsPort, err = getPortFromConfig("CSI_CEPHFS_LIVENESS_METRICS_PORT", DefaultCephFSLivenessMerticsPort)
+	CSIParam.CephFSLivenessMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_CEPHFS_LIVENESS_METRICS_PORT", DefaultCephFSLivenessMerticsPort)
 	if err != nil {
 		return errors.Wrap(err, "error getting CSI CephFS liveness metrics port.")
 	}
-
-	CSIParam.CSIAddonsPort, err = getPortFromConfig("CSIADDONS_PORT", DefaultCSIAddonsPort)
+	CSIParam.CSIAddonsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSIADDONS_PORT", DefaultCSIAddonsPort)
 	if err != nil {
 		return errors.Wrap(err, "failed to get CSI Addons port")
 	}
-
-	CSIParam.CSIAddonsRBDProvisionerPort, err = getPortFromConfig("CSIADDONS_RBD_PROVISIONER_PORT", DefaultCSIAddonsRBDProvisionerPort)
-	if err != nil {
-		return errors.Wrap(err, "failed to get CSI Addons port for RBD provisioner")
-	}
-
-	CSIParam.CSIAddonsCephFSProvisionerPort, err = getPortFromConfig("CSIADDONS_CEPHFS_PROVISIONER_PORT", DefaultCSIAddonsCephFSProvisionerPort)
-	if err != nil {
-		return errors.Wrap(err, "failed to get CSI Addons port for Ceph FS provisioner")
-	}
-
-	CSIParam.RBDLivenessMetricsPort, err = getPortFromConfig("CSI_RBD_LIVENESS_METRICS_PORT", DefaultRBDLivenessMerticsPort)
+	CSIParam.RBDLivenessMetricsPort, err = getPortFromConfig(r.opConfig.Parameters, "CSI_RBD_LIVENESS_METRICS_PORT", DefaultRBDLivenessMerticsPort)
 	if err != nil {
 		return errors.Wrap(err, "error getting CSI RBD liveness metrics port.")
 	}
 
-	CSIParam.EnableLiveness, err = strconv.ParseBool(k8sutil.GetOperatorSetting("CSI_ENABLE_LIVENESS", "false"))
+	CSIParam.EnableLiveness, err = strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_LIVENESS", "false"))
 	if err != nil {
 		return errors.Wrap(err, "failed to parse value for 'CSI_ENABLE_LIVENESS'")
 	}
@@ -126,31 +114,31 @@ func (r *ReconcileCSI) setParams() error {
 	CSIParam.Privileged = controller.HostPathRequiresPrivileged()
 
 	// default value `system-node-critical` is the highest available priority
-	CSIParam.PluginPriorityClassName = k8sutil.GetOperatorSetting("CSI_PLUGIN_PRIORITY_CLASSNAME", "")
+	CSIParam.PluginPriorityClassName = k8sutil.GetValue(r.opConfig.Parameters, "CSI_PLUGIN_PRIORITY_CLASSNAME", "")
 
 	// default value `system-cluster-critical` is applied for some
 	// critical pods in cluster but less priority than plugin pods
-	CSIParam.ProvisionerPriorityClassName = k8sutil.GetOperatorSetting("CSI_PROVISIONER_PRIORITY_CLASSNAME", "")
+	CSIParam.ProvisionerPriorityClassName = k8sutil.GetValue(r.opConfig.Parameters, "CSI_PROVISIONER_PRIORITY_CLASSNAME", "")
 
 	CSIParam.EnableOMAPGenerator = false
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_OMAP_GENERATOR", "false"), "true") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_OMAP_GENERATOR", "false"), "true") {
 		CSIParam.EnableOMAPGenerator = true
 	}
 
 	CSIParam.EnableCSIDriverSeLinuxMount = true
 
 	CSIParam.EnableRBDSnapshotter = true
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_RBD_SNAPSHOTTER", "true"), "false") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_RBD_SNAPSHOTTER", "true"), "false") {
 		CSIParam.EnableRBDSnapshotter = false
 	}
 
 	CSIParam.EnableCephFSSnapshotter = true
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_CEPHFS_SNAPSHOTTER", "true"), "false") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_CEPHFS_SNAPSHOTTER", "true"), "false") {
 		CSIParam.EnableCephFSSnapshotter = false
 	}
 
 	CSIParam.EnableNFSSnapshotter = true
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_NFS_SNAPSHOTTER", "true"), "false") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_NFS_SNAPSHOTTER", "true"), "false") {
 		CSIParam.EnableNFSSnapshotter = false
 	}
 
@@ -159,36 +147,36 @@ func (r *ReconcileCSI) setParams() error {
 	if err == nil {
 		CSIParam.EnableCSIAddonsSideCar = true
 	}
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_CSIADDONS", ""), "false") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_CSIADDONS", ""), "false") {
 		CSIParam.EnableCSIAddonsSideCar = false
 	}
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_CSIADDONS", ""), "true") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_CSIADDONS", ""), "true") {
 		CSIParam.EnableCSIAddonsSideCar = true
 	}
 
 	CSIParam.EnableCSITopology = false
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_TOPOLOGY", "false"), "true") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_TOPOLOGY", "false"), "true") {
 		CSIParam.EnableCSITopology = true
 	}
 
 	CSIParam.EnableCSIEncryption = false
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_ENCRYPTION", "false"), "true") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_ENCRYPTION", "false"), "true") {
 		CSIParam.EnableCSIEncryption = true
 	}
 
 	CSIParam.CSIEnableMetadata = false
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_METADATA", "false"), "true") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_METADATA", "false"), "true") {
 		CSIParam.CSIEnableMetadata = true
 	}
 
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_CEPHFS_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
 		CSIParam.CephFSPluginUpdateStrategy = onDelete
 	} else {
 		CSIParam.CephFSPluginUpdateStrategy = rollingUpdate
-		CSIParam.CephFSPluginUpdateStrategyMaxUnavailable = k8sutil.GetOperatorSetting("CSI_CEPHFS_PLUGIN_UPDATE_STRATEGY_MAX_UNAVAILABLE", "1")
+		CSIParam.CephFSPluginUpdateStrategyMaxUnavailable = k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_PLUGIN_UPDATE_STRATEGY_MAX_UNAVAILABLE", "1")
 	}
 
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_NFS_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_NFS_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
 		CSIParam.NFSPluginUpdateStrategy = onDelete
 	} else {
 		CSIParam.NFSPluginUpdateStrategy = rollingUpdate
@@ -196,19 +184,19 @@ func (r *ReconcileCSI) setParams() error {
 
 	// Default values are based on Kubernetes official documentation.
 	// https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_RBD_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_RBD_PLUGIN_UPDATE_STRATEGY", rollingUpdate), onDelete) {
 		CSIParam.RBDPluginUpdateStrategy = onDelete
 	} else {
 		CSIParam.RBDPluginUpdateStrategy = rollingUpdate
-		CSIParam.RBDPluginUpdateStrategyMaxUnavailable = k8sutil.GetOperatorSetting("CSI_RBD_PLUGIN_UPDATE_STRATEGY_MAX_UNAVAILABLE", "1")
+		CSIParam.RBDPluginUpdateStrategyMaxUnavailable = k8sutil.GetValue(r.opConfig.Parameters, "CSI_RBD_PLUGIN_UPDATE_STRATEGY_MAX_UNAVAILABLE", "1")
 	}
 
 	CSIParam.EnablePluginSelinuxHostMount = false
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_PLUGIN_ENABLE_SELINUX_HOST_MOUNT", "false"), "true") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_PLUGIN_ENABLE_SELINUX_HOST_MOUNT", "false"), "true") {
 		CSIParam.EnablePluginSelinuxHostMount = true
 	}
 
-	logLevel := k8sutil.GetOperatorSetting("CSI_LOG_LEVEL", "")
+	logLevel := k8sutil.GetValue(r.opConfig.Parameters, "CSI_LOG_LEVEL", "")
 	CSIParam.LogLevel = defaultLogLevel
 	if logLevel != "" {
 		l, err := strconv.ParseUint(logLevel, 10, 8)
@@ -219,7 +207,7 @@ func (r *ReconcileCSI) setParams() error {
 		}
 	}
 
-	sidecarLogLevel := k8sutil.GetOperatorSetting("CSI_SIDECAR_LOG_LEVEL", "")
+	sidecarLogLevel := k8sutil.GetValue(r.opConfig.Parameters, "CSI_SIDECAR_LOG_LEVEL", "")
 	CSIParam.SidecarLogLevel = defaultSidecarLogLevel
 	if sidecarLogLevel != "" {
 		l, err := strconv.ParseUint(sidecarLogLevel, 10, 8)
@@ -230,7 +218,7 @@ func (r *ReconcileCSI) setParams() error {
 		}
 	}
 
-	leaderElectionLeaseDuration := k8sutil.GetOperatorSetting("CSI_LEADER_ELECTION_LEASE_DURATION", "")
+	leaderElectionLeaseDuration := k8sutil.GetValue(r.opConfig.Parameters, "CSI_LEADER_ELECTION_LEASE_DURATION", "")
 	CSIParam.LeaderElectionLeaseDuration = defaultLeaderElectionLeaseDuration
 	if leaderElectionLeaseDuration != "" {
 		d, err := time.ParseDuration(leaderElectionLeaseDuration)
@@ -241,7 +229,7 @@ func (r *ReconcileCSI) setParams() error {
 		}
 	}
 
-	leaderElectionRenewDeadline := k8sutil.GetOperatorSetting("CSI_LEADER_ELECTION_RENEW_DEADLINE", "")
+	leaderElectionRenewDeadline := k8sutil.GetValue(r.opConfig.Parameters, "CSI_LEADER_ELECTION_RENEW_DEADLINE", "")
 	CSIParam.LeaderElectionRenewDeadline = defaultLeaderElectionRenewDeadline
 	if leaderElectionRenewDeadline != "" {
 		d, err := time.ParseDuration(leaderElectionRenewDeadline)
@@ -252,7 +240,7 @@ func (r *ReconcileCSI) setParams() error {
 		}
 	}
 
-	leaderElectionRetryPeriod := k8sutil.GetOperatorSetting("CSI_LEADER_ELECTION_RETRY_PERIOD", "")
+	leaderElectionRetryPeriod := k8sutil.GetValue(r.opConfig.Parameters, "CSI_LEADER_ELECTION_RETRY_PERIOD", "")
 	CSIParam.LeaderElectionRetryPeriod = defaultLeaderElectionRetryPeriod
 	if leaderElectionRetryPeriod != "" {
 		d, err := time.ParseDuration(leaderElectionRetryPeriod)
@@ -269,7 +257,7 @@ func (r *ReconcileCSI) setParams() error {
 		if len(nodes.Items) == 1 {
 			CSIParam.ProvisionerReplicas = 1
 		} else {
-			replicaStr := k8sutil.GetOperatorSetting("CSI_PROVISIONER_REPLICAS", "2")
+			replicaStr := k8sutil.GetValue(r.opConfig.Parameters, "CSI_PROVISIONER_REPLICAS", "2")
 			replicas, err := strconv.ParseInt(replicaStr, 10, 32)
 			if err != nil {
 				logger.Errorf("failed to parse CSI_PROVISIONER_REPLICAS. Defaulting to %d. %v", defaultProvisionerReplicas, err)
@@ -281,39 +269,39 @@ func (r *ReconcileCSI) setParams() error {
 		logger.Errorf("failed to get nodes. Defaulting the number of replicas of provisioner pods to %d. %v", CSIParam.ProvisionerReplicas, err)
 	}
 
-	CSIParam.CSIPluginImage = getImage("ROOK_CSI_CEPH_IMAGE", DefaultCSIPluginImage)
-	CSIParam.RegistrarImage = getImage("ROOK_CSI_REGISTRAR_IMAGE", DefaultRegistrarImage)
-	CSIParam.ProvisionerImage = getImage("ROOK_CSI_PROVISIONER_IMAGE", DefaultProvisionerImage)
-	CSIParam.AttacherImage = getImage("ROOK_CSI_ATTACHER_IMAGE", DefaultAttacherImage)
-	CSIParam.SnapshotterImage = getImage("ROOK_CSI_SNAPSHOTTER_IMAGE", DefaultSnapshotterImage)
-	CSIParam.ResizerImage = getImage("ROOK_CSI_RESIZER_IMAGE", DefaultResizerImage)
-	CSIParam.KubeletDirPath = k8sutil.GetOperatorSetting("ROOK_CSI_KUBELET_DIR_PATH", DefaultKubeletDirPath)
-	CSIParam.CSIAddonsImage = getImage("ROOK_CSIADDONS_IMAGE", DefaultCSIAddonsImage)
-	CSIParam.CSIDomainLabels = k8sutil.GetOperatorSetting("CSI_TOPOLOGY_DOMAIN_LABELS", "")
-	csiCephFSPodLabels := k8sutil.GetOperatorSetting("ROOK_CSI_CEPHFS_POD_LABELS", "")
+	CSIParam.CSIPluginImage = getImage(r.opConfig.Parameters, "ROOK_CSI_CEPH_IMAGE", DefaultCSIPluginImage)
+	CSIParam.RegistrarImage = getImage(r.opConfig.Parameters, "ROOK_CSI_REGISTRAR_IMAGE", DefaultRegistrarImage)
+	CSIParam.ProvisionerImage = getImage(r.opConfig.Parameters, "ROOK_CSI_PROVISIONER_IMAGE", DefaultProvisionerImage)
+	CSIParam.AttacherImage = getImage(r.opConfig.Parameters, "ROOK_CSI_ATTACHER_IMAGE", DefaultAttacherImage)
+	CSIParam.SnapshotterImage = getImage(r.opConfig.Parameters, "ROOK_CSI_SNAPSHOTTER_IMAGE", DefaultSnapshotterImage)
+	CSIParam.ResizerImage = getImage(r.opConfig.Parameters, "ROOK_CSI_RESIZER_IMAGE", DefaultResizerImage)
+	CSIParam.KubeletDirPath = k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_KUBELET_DIR_PATH", DefaultKubeletDirPath)
+	CSIParam.CSIAddonsImage = getImage(r.opConfig.Parameters, "ROOK_CSIADDONS_IMAGE", DefaultCSIAddonsImage)
+	CSIParam.CSIDomainLabels = k8sutil.GetValue(r.opConfig.Parameters, "CSI_TOPOLOGY_DOMAIN_LABELS", "")
+	csiCephFSPodLabels := k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_CEPHFS_POD_LABELS", "")
 	CSIParam.CSICephFSPodLabels = k8sutil.ParseStringToLabels(csiCephFSPodLabels)
-	csiNFSPodLabels := k8sutil.GetOperatorSetting("ROOK_CSI_NFS_POD_LABELS", "")
+	csiNFSPodLabels := k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_NFS_POD_LABELS", "")
 	CSIParam.CSINFSPodLabels = k8sutil.ParseStringToLabels(csiNFSPodLabels)
-	csiRBDPodLabels := k8sutil.GetOperatorSetting("ROOK_CSI_RBD_POD_LABELS", "")
+	csiRBDPodLabels := k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_RBD_POD_LABELS", "")
 	CSIParam.CSIRBDPodLabels = k8sutil.ParseStringToLabels(csiRBDPodLabels)
-	CSIParam.CSIClusterName = k8sutil.GetOperatorSetting("CSI_CLUSTER_NAME", "")
-	CSIParam.ImagePullPolicy = k8sutil.GetOperatorSetting("ROOK_CSI_IMAGE_PULL_POLICY", DefaultCSIImagePullPolicy)
-	CSIParam.CephFSKernelMountOptions = k8sutil.GetOperatorSetting("CSI_CEPHFS_KERNEL_MOUNT_OPTIONS", "")
+	CSIParam.CSIClusterName = k8sutil.GetValue(r.opConfig.Parameters, "CSI_CLUSTER_NAME", "")
+	CSIParam.ImagePullPolicy = k8sutil.GetValue(r.opConfig.Parameters, "ROOK_CSI_IMAGE_PULL_POLICY", DefaultCSIImagePullPolicy)
+	CSIParam.CephFSKernelMountOptions = k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_KERNEL_MOUNT_OPTIONS", "")
 
 	CSIParam.CephFSAttachRequired = true
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_CEPHFS_ATTACH_REQUIRED", "true"), "false") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_ATTACH_REQUIRED", "true"), "false") {
 		CSIParam.CephFSAttachRequired = false
 	}
 	CSIParam.RBDAttachRequired = true
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_RBD_ATTACH_REQUIRED", "true"), "false") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_RBD_ATTACH_REQUIRED", "true"), "false") {
 		CSIParam.RBDAttachRequired = false
 	}
 	CSIParam.NFSAttachRequired = true
-	if strings.EqualFold(k8sutil.GetOperatorSetting("CSI_NFS_ATTACH_REQUIRED", "true"), "false") {
+	if strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_NFS_ATTACH_REQUIRED", "true"), "false") {
 		CSIParam.NFSAttachRequired = false
 	}
 
-	CSIParam.DriverNamePrefix = k8sutil.GetOperatorSetting("CSI_DRIVER_NAME_PREFIX", r.opConfig.OperatorNamespace)
+	CSIParam.DriverNamePrefix = k8sutil.GetValue(r.opConfig.Parameters, "CSI_DRIVER_NAME_PREFIX", r.opConfig.OperatorNamespace)
 
 	crd, err := r.context.ApiExtensionsClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), "volumegroupsnapshotclasses.groupsnapshot.storage.k8s.io", metav1.GetOptions{})
 	if err != nil && !kerrors.IsNotFound(err) {
@@ -324,7 +312,7 @@ func (r *ReconcileCSI) setParams() error {
 	if err == nil && len(crd.Spec.Versions) > 0 {
 		ver := crd.Spec.Versions[0]
 		// Determine if VolumeGroupSnapshot feature should be disabled
-		disableVGS := strings.EqualFold(k8sutil.GetOperatorSetting("CSI_ENABLE_VOLUME_GROUP_SNAPSHOT", "true"), "false")
+		disableVGS := strings.EqualFold(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_VOLUME_GROUP_SNAPSHOT", "true"), "false")
 		const (
 			enableVolumeGroupSnapshotFlag = "--enable-volume-group-snapshots="
 			featureGateFlag               = "--feature-gates=CSIVolumeGroupSnapshot="
@@ -346,7 +334,7 @@ func (r *ReconcileCSI) setParams() error {
 		}
 	}
 
-	kubeApiBurst := k8sutil.GetOperatorSetting("CSI_KUBE_API_BURST", "")
+	kubeApiBurst := k8sutil.GetValue(r.opConfig.Parameters, "CSI_KUBE_API_BURST", "")
 	CSIParam.KubeApiBurst = 0
 	if kubeApiBurst != "" {
 		k, err := strconv.ParseUint(kubeApiBurst, 10, 16)
@@ -357,7 +345,7 @@ func (r *ReconcileCSI) setParams() error {
 		}
 	}
 
-	kubeApiQPS := k8sutil.GetOperatorSetting("CSI_KUBE_API_QPS", "")
+	kubeApiQPS := k8sutil.GetValue(r.opConfig.Parameters, "CSI_KUBE_API_QPS", "")
 	CSIParam.KubeApiQPS = 0
 	if kubeApiQPS != "" {
 		k, err := strconv.ParseFloat(kubeApiQPS, 32)
diff --git a/pkg/operator/ceph/csi/operator_config.go b/pkg/operator/ceph/csi/operator_config.go
index 7e013245c..638e512b2 100644
--- a/pkg/operator/ceph/csi/operator_config.go
+++ b/pkg/operator/ceph/csi/operator_config.go
@@ -94,9 +94,9 @@ func (r *ReconcileCSI) generateCSIOpConfigSpec(cluster cephv1.CephCluster, opCon
 				PodCommonSpec: csiopv1a1.PodCommonSpec{
 					PrioritylClassName: &CSIParam.ProvisionerPriorityClassName,
 					Affinity: &v1.Affinity{
-						NodeAffinity: getNodeAffinity(pluginNodeAffinityEnv, &v1.NodeAffinity{}),
+						NodeAffinity: getNodeAffinity(r.opConfig.Parameters, pluginNodeAffinityEnv, &v1.NodeAffinity{}),
 					},
-					Tolerations: getToleration(pluginTolerationsEnv, []v1.Toleration{}),
+					Tolerations: getToleration(r.opConfig.Parameters, pluginTolerationsEnv, []v1.Toleration{}),
 				},
 				Resources:              csiopv1a1.NodePluginResourcesSpec{},
 				KubeletDirPath:         CSIParam.KubeletDirPath,
@@ -106,9 +106,9 @@ func (r *ReconcileCSI) generateCSIOpConfigSpec(cluster cephv1.CephCluster, opCon
 				PodCommonSpec: csiopv1a1.PodCommonSpec{
 					PrioritylClassName: &CSIParam.PluginPriorityClassName,
 					Affinity: &v1.Affinity{
-						NodeAffinity: getNodeAffinity(provisionerNodeAffinityEnv, &v1.NodeAffinity{}),
+						NodeAffinity: getNodeAffinity(r.opConfig.Parameters, provisionerNodeAffinityEnv, &v1.NodeAffinity{}),
 					},
-					Tolerations: getToleration(provisionerTolerationsEnv, []v1.Toleration{}),
+					Tolerations: getToleration(r.opConfig.Parameters, provisionerTolerationsEnv, []v1.Toleration{}),
 				},
 				Replicas:  &CSIParam.ProvisionerReplicas,
 				Resources: csiopv1a1.ControllerPluginResourcesSpec{},
diff --git a/pkg/operator/ceph/csi/operator_driver.go b/pkg/operator/ceph/csi/operator_driver.go
index 99c845a2b..f5457be45 100644
--- a/pkg/operator/ceph/csi/operator_driver.go
+++ b/pkg/operator/ceph/csi/operator_driver.go
@@ -92,11 +92,11 @@ func (r *ReconcileCSI) createOrUpdateRBDDriverResource(cluster cephv1.CephCluste
 		Spec: spec,
 	}
 
-	rbdDriver.Spec.ControllerPlugin.Resources = createDriverControllerPluginResources(rbdPluginResource)
+	rbdDriver.Spec.ControllerPlugin.Resources = createDriverControllerPluginResources(r.opConfig.Parameters, rbdPluginResource)
 	rbdDriver.Spec.Liveness = &csiopv1a1.LivenessSpec{
 		MetricsPort: int(CSIParam.RBDLivenessMetricsPort),
 	}
-	rbdDriver.Spec.NodePlugin.Resources = createDriverNodePluginResouces(rbdProvisionerResource)
+	rbdDriver.Spec.NodePlugin.Resources = createDriverNodePluginResouces(r.opConfig.Parameters, rbdProvisionerResource)
 	rbdDriver.Spec.NodePlugin.UpdateStrategy = &v1.DaemonSetUpdateStrategy{
 		Type: v1.RollingUpdateDaemonSetStrategyType,
 	}
@@ -143,12 +143,12 @@ func (r *ReconcileCSI) createOrUpdateCephFSDriverResource(cluster cephv1.CephClu
 		cephFsDriver.Spec.SnapshotPolicy = csiopv1a1.VolumeGroupSnapshotPolicy
 	}
 
-	cephFsDriver.Spec.ControllerPlugin.Resources = createDriverControllerPluginResources(cephFSPluginResource)
+	cephFsDriver.Spec.ControllerPlugin.Resources = createDriverControllerPluginResources(r.opConfig.Parameters, cephFSPluginResource)
 	cephFsDriver.Spec.Liveness = &csiopv1a1.LivenessSpec{
 		MetricsPort: int(CSIParam.CephFSLivenessMetricsPort),
 	}
 
-	cephFsDriver.Spec.NodePlugin.Resources = createDriverNodePluginResouces(cephFSProvisionerResource)
+	cephFsDriver.Spec.NodePlugin.Resources = createDriverNodePluginResouces(r.opConfig.Parameters, cephFSProvisionerResource)
 	cephFsDriver.Spec.NodePlugin.UpdateStrategy = &v1.DaemonSetUpdateStrategy{
 		Type: v1.RollingUpdateDaemonSetStrategyType,
 	}
@@ -190,9 +190,9 @@ func (r *ReconcileCSI) createOrUpdateNFSDriverResource(cluster cephv1.CephCluste
 		Spec: spec,
 	}
 
-	NFSDriver.Spec.ControllerPlugin.Resources = createDriverControllerPluginResources(nfsPluginResource)
+	NFSDriver.Spec.ControllerPlugin.Resources = createDriverControllerPluginResources(r.opConfig.Parameters, nfsPluginResource)
 
-	NFSDriver.Spec.NodePlugin.Resources = createDriverNodePluginResouces(nfsProvisionerResource)
+	NFSDriver.Spec.NodePlugin.Resources = createDriverNodePluginResouces(r.opConfig.Parameters, nfsProvisionerResource)
 	NFSDriver.Spec.NodePlugin.UpdateStrategy = &v1.DaemonSetUpdateStrategy{
 		Type: v1.RollingUpdateDaemonSetStrategyType,
 	}
@@ -270,9 +270,9 @@ func (r *ReconcileCSI) generateDriverSpec(clusterName string) (csiopv1a1.DriverS
 			PodCommonSpec: csiopv1a1.PodCommonSpec{
 				PrioritylClassName: &CSIParam.ProvisionerPriorityClassName,
 				Affinity: &corev1.Affinity{
-					NodeAffinity: getNodeAffinity(pluginNodeAffinityEnv, &corev1.NodeAffinity{}),
+					NodeAffinity: getNodeAffinity(r.opConfig.Parameters, pluginNodeAffinityEnv, &corev1.NodeAffinity{}),
 				},
-				Tolerations: getToleration(pluginTolerationsEnv, []corev1.Toleration{}),
+				Tolerations: getToleration(r.opConfig.Parameters, pluginTolerationsEnv, []corev1.Toleration{}),
 			},
 			Resources:              csiopv1a1.NodePluginResourcesSpec{},
 			KubeletDirPath:         CSIParam.KubeletDirPath,
@@ -282,9 +282,9 @@ func (r *ReconcileCSI) generateDriverSpec(clusterName string) (csiopv1a1.DriverS
 			PodCommonSpec: csiopv1a1.PodCommonSpec{
 				PrioritylClassName: &CSIParam.PluginPriorityClassName,
 				Affinity: &corev1.Affinity{
-					NodeAffinity: getNodeAffinity(provisionerNodeAffinityEnv, &corev1.NodeAffinity{}),
+					NodeAffinity: getNodeAffinity(r.opConfig.Parameters, provisionerNodeAffinityEnv, &corev1.NodeAffinity{}),
 				},
-				Tolerations: getToleration(provisionerTolerationsEnv, []corev1.Toleration{}),
+				Tolerations: getToleration(r.opConfig.Parameters, provisionerTolerationsEnv, []corev1.Toleration{}),
 			},
 			Replicas:  &CSIParam.ProvisionerReplicas,
 			Resources: csiopv1a1.ControllerPluginResourcesSpec{},
@@ -294,9 +294,9 @@ func (r *ReconcileCSI) generateDriverSpec(clusterName string) (csiopv1a1.DriverS
 	}, nil
 }
 
-func createDriverControllerPluginResources(key string) csiopv1a1.ControllerPluginResourcesSpec {
+func createDriverControllerPluginResources(opConfig map[string]string, key string) csiopv1a1.ControllerPluginResourcesSpec {
 	controllerPluginResources := csiopv1a1.ControllerPluginResourcesSpec{}
-	resource := getComputeResource(key)
+	resource := getComputeResource(opConfig, key)
 
 	for _, r := range resource {
 		if !reflect.DeepEqual(r.Resource, corev1.ResourceRequirements{}) {
@@ -347,9 +347,9 @@ func createDriverControllerPluginResources(key string) csiopv1a1.ControllerPlugi
 	return controllerPluginResources
 }
 
-func createDriverNodePluginResouces(key string) csiopv1a1.NodePluginResourcesSpec {
+func createDriverNodePluginResouces(opConfig map[string]string, key string) csiopv1a1.NodePluginResourcesSpec {
 	nodePluginResources := csiopv1a1.NodePluginResourcesSpec{}
-	resource := getComputeResource(key)
+	resource := getComputeResource(opConfig, key)
 
 	for _, r := range resource {
 		if !reflect.DeepEqual(r.Resource, corev1.ResourceRequirements{}) {
diff --git a/pkg/operator/ceph/csi/spec.go b/pkg/operator/ceph/csi/spec.go
index 5b968453f..9381619cc 100644
--- a/pkg/operator/ceph/csi/spec.go
+++ b/pkg/operator/ceph/csi/spec.go
@@ -83,8 +83,6 @@ type Param struct {
 	SidecarLogLevel                          uint8
 	CephFSLivenessMetricsPort                uint16
 	CSIAddonsPort                            uint16
-	CSIAddonsRBDProvisionerPort              uint16
-	CSIAddonsCephFSProvisionerPort           uint16
 	RBDLivenessMetricsPort                   uint16
 	KubeApiBurst                             uint16
 	KubeApiQPS                               float32
@@ -221,14 +219,12 @@ const (
 	// kubelet directory path
 	DefaultKubeletDirPath = "/var/lib/kubelet"
 
-	// gRPC metrics and liveness port for CephFS and RBD
-	DefaultCephFSGRPCMerticsPort          uint16 = 9091
-	DefaultCephFSLivenessMerticsPort      uint16 = 9081
-	DefaultRBDGRPCMerticsPort             uint16 = 9090
-	DefaultRBDLivenessMerticsPort         uint16 = 9080
-	DefaultCSIAddonsPort                  uint16 = 9070
-	DefaultCSIAddonsRBDProvisionerPort    uint16 = 9070
-	DefaultCSIAddonsCephFSProvisionerPort uint16 = 9070
+	// grpc metrics and liveness port for cephfs  and rbd
+	DefaultCephFSGRPCMerticsPort     uint16 = 9091
+	DefaultCephFSLivenessMerticsPort uint16 = 9081
+	DefaultRBDGRPCMerticsPort        uint16 = 9090
+	DefaultRBDLivenessMerticsPort    uint16 = 9080
+	DefaultCSIAddonsPort             uint16 = 9070
 
 	// default log level for csi containers
 	defaultLogLevel        uint8 = 0
@@ -426,25 +422,25 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 	}
 
 	// get common provisioner tolerations and node affinity
-	provisionerTolerations := getToleration(provisionerTolerationsEnv, []corev1.Toleration{})
-	provisionerNodeAffinity := getNodeAffinity(provisionerNodeAffinityEnv, &corev1.NodeAffinity{})
+	provisionerTolerations := getToleration(r.opConfig.Parameters, provisionerTolerationsEnv, []corev1.Toleration{})
+	provisionerNodeAffinity := getNodeAffinity(r.opConfig.Parameters, provisionerNodeAffinityEnv, &corev1.NodeAffinity{})
 
 	// get common plugin tolerations and node affinity
-	pluginTolerations := getToleration(pluginTolerationsEnv, []corev1.Toleration{})
-	pluginNodeAffinity := getNodeAffinity(pluginNodeAffinityEnv, &corev1.NodeAffinity{})
+	pluginTolerations := getToleration(r.opConfig.Parameters, pluginTolerationsEnv, []corev1.Toleration{})
+	pluginNodeAffinity := getNodeAffinity(r.opConfig.Parameters, pluginNodeAffinityEnv, &corev1.NodeAffinity{})
 
 	if rbdPlugin != nil {
 		// get RBD plugin tolerations and node affinity, defaults to common tolerations and node affinity if not specified
-		rbdPluginTolerations := getToleration(rbdPluginTolerationsEnv, pluginTolerations)
-		rbdPluginNodeAffinity := getNodeAffinity(rbdPluginNodeAffinityEnv, pluginNodeAffinity)
+		rbdPluginTolerations := getToleration(r.opConfig.Parameters, rbdPluginTolerationsEnv, pluginTolerations)
+		rbdPluginNodeAffinity := getNodeAffinity(r.opConfig.Parameters, rbdPluginNodeAffinityEnv, pluginNodeAffinity)
 		// apply RBD plugin tolerations and node affinity
 		applyToPodSpec(&rbdPlugin.Spec.Template.Spec, rbdPluginNodeAffinity, rbdPluginTolerations)
 		// apply resource request and limit to rbdplugin containers
-		applyResourcesToContainers(rbdPluginResource, &rbdPlugin.Spec.Template.Spec)
+		applyResourcesToContainers(r.opConfig.Parameters, rbdPluginResource, &rbdPlugin.Spec.Template.Spec)
 		// apply custom mounts to volumes
-		applyVolumeToPodSpec(rbdPluginVolume, &rbdPlugin.Spec.Template.Spec)
+		applyVolumeToPodSpec(r.opConfig.Parameters, rbdPluginVolume, &rbdPlugin.Spec.Template.Spec)
 		// apply custom mounts to volume mounts
-		applyVolumeMountToContainer(rbdPluginVolumeMount, "csi-rbdplugin", &rbdPlugin.Spec.Template.Spec)
+		applyVolumeMountToContainer(r.opConfig.Parameters, rbdPluginVolumeMount, "csi-rbdplugin", &rbdPlugin.Spec.Template.Spec)
 		err = ownerInfo.SetControllerReference(rbdPlugin)
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to rbd plugin daemonset %q", rbdPlugin.Name)
@@ -462,12 +458,12 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 
 	if rbdProvisionerDeployment != nil {
 		// get RBD provisioner tolerations and node affinity, defaults to common tolerations and node affinity if not specified
-		rbdProvisionerTolerations := getToleration(rbdProvisionerTolerationsEnv, provisionerTolerations)
-		rbdProvisionerNodeAffinity := getNodeAffinity(rbdProvisionerNodeAffinityEnv, provisionerNodeAffinity)
+		rbdProvisionerTolerations := getToleration(r.opConfig.Parameters, rbdProvisionerTolerationsEnv, provisionerTolerations)
+		rbdProvisionerNodeAffinity := getNodeAffinity(r.opConfig.Parameters, rbdProvisionerNodeAffinityEnv, provisionerNodeAffinity)
 		// apply RBD provisioner tolerations and node affinity
 		applyToPodSpec(&rbdProvisionerDeployment.Spec.Template.Spec, rbdProvisionerNodeAffinity, rbdProvisionerTolerations)
 		// apply resource request and limit to rbd provisioner containers
-		applyResourcesToContainers(rbdProvisionerResource, &rbdProvisionerDeployment.Spec.Template.Spec)
+		applyResourcesToContainers(r.opConfig.Parameters, rbdProvisionerResource, &rbdProvisionerDeployment.Spec.Template.Spec)
 		err = ownerInfo.SetControllerReference(rbdProvisionerDeployment)
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to rbd provisioner deployment %q", rbdProvisionerDeployment.Name)
@@ -504,16 +500,16 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 
 	if cephfsPlugin != nil {
 		// get CephFS plugin tolerations and node affinity, defaults to common tolerations and node affinity if not specified
-		cephFSPluginTolerations := getToleration(cephFSPluginTolerationsEnv, pluginTolerations)
-		cephFSPluginNodeAffinity := getNodeAffinity(cephFSPluginNodeAffinityEnv, pluginNodeAffinity)
+		cephFSPluginTolerations := getToleration(r.opConfig.Parameters, cephFSPluginTolerationsEnv, pluginTolerations)
+		cephFSPluginNodeAffinity := getNodeAffinity(r.opConfig.Parameters, cephFSPluginNodeAffinityEnv, pluginNodeAffinity)
 		// apply CephFS plugin tolerations and node affinity
 		applyToPodSpec(&cephfsPlugin.Spec.Template.Spec, cephFSPluginNodeAffinity, cephFSPluginTolerations)
 		// apply resource request and limit to cephfs plugin containers
-		applyResourcesToContainers(cephFSPluginResource, &cephfsPlugin.Spec.Template.Spec)
+		applyResourcesToContainers(r.opConfig.Parameters, cephFSPluginResource, &cephfsPlugin.Spec.Template.Spec)
 		// apply custom mounts to volumes
-		applyVolumeToPodSpec(cephFSPluginVolume, &cephfsPlugin.Spec.Template.Spec)
+		applyVolumeToPodSpec(r.opConfig.Parameters, cephFSPluginVolume, &cephfsPlugin.Spec.Template.Spec)
 		// apply custom mounts to volume mounts
-		applyVolumeMountToContainer(cephFSPluginVolumeMount, "csi-cephfsplugin", &cephfsPlugin.Spec.Template.Spec)
+		applyVolumeMountToContainer(r.opConfig.Parameters, cephFSPluginVolumeMount, "csi-cephfsplugin", &cephfsPlugin.Spec.Template.Spec)
 		err = ownerInfo.SetControllerReference(cephfsPlugin)
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to cephfs plugin daemonset %q", cephfsPlugin.Name)
@@ -532,13 +528,13 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 
 	if cephfsProvisionerDeployment != nil {
 		// get CephFS provisioner tolerations and node affinity, defaults to common tolerations and node affinity if not specified
-		cephFSProvisionerTolerations := getToleration(cephFSProvisionerTolerationsEnv, provisionerTolerations)
-		cephFSProvisionerNodeAffinity := getNodeAffinity(cephFSProvisionerNodeAffinityEnv, provisionerNodeAffinity)
+		cephFSProvisionerTolerations := getToleration(r.opConfig.Parameters, cephFSProvisionerTolerationsEnv, provisionerTolerations)
+		cephFSProvisionerNodeAffinity := getNodeAffinity(r.opConfig.Parameters, cephFSProvisionerNodeAffinityEnv, provisionerNodeAffinity)
 		// apply CephFS provisioner tolerations and node affinity
 		applyToPodSpec(&cephfsProvisionerDeployment.Spec.Template.Spec, cephFSProvisionerNodeAffinity, cephFSProvisionerTolerations)
 		// get resource details for cephfs provisioner
 		// apply resource request and limit to cephfs provisioner containers
-		applyResourcesToContainers(cephFSProvisionerResource, &cephfsProvisionerDeployment.Spec.Template.Spec)
+		applyResourcesToContainers(r.opConfig.Parameters, cephFSProvisionerResource, &cephfsProvisionerDeployment.Spec.Template.Spec)
 		err = ownerInfo.SetControllerReference(cephfsProvisionerDeployment)
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to cephfs provisioner deployment %q", cephfsProvisionerDeployment.Name)
@@ -574,16 +570,16 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 
 	if nfsPlugin != nil {
 		// get NFS plugin tolerations and node affinity, defaults to common tolerations and node affinity if not specified
-		nfsPluginTolerations := getToleration(nfsPluginTolerationsEnv, pluginTolerations)
-		nfsPluginNodeAffinity := getNodeAffinity(nfsPluginNodeAffinityEnv, pluginNodeAffinity)
+		nfsPluginTolerations := getToleration(r.opConfig.Parameters, nfsPluginTolerationsEnv, pluginTolerations)
+		nfsPluginNodeAffinity := getNodeAffinity(r.opConfig.Parameters, nfsPluginNodeAffinityEnv, pluginNodeAffinity)
 		// apply NFS plugin tolerations and node affinity
 		applyToPodSpec(&nfsPlugin.Spec.Template.Spec, nfsPluginNodeAffinity, nfsPluginTolerations)
 		// apply resource request and limit to nfs plugin containers
-		applyResourcesToContainers(nfsPluginResource, &nfsPlugin.Spec.Template.Spec)
+		applyResourcesToContainers(r.opConfig.Parameters, nfsPluginResource, &nfsPlugin.Spec.Template.Spec)
 		// apply custom mounts to volumes
-		applyVolumeToPodSpec(nfsPluginVolume, &nfsPlugin.Spec.Template.Spec)
+		applyVolumeToPodSpec(r.opConfig.Parameters, nfsPluginVolume, &nfsPlugin.Spec.Template.Spec)
 		// apply custom mounts to volume mounts
-		applyVolumeMountToContainer(nfsPluginVolumeMount, "csi-nfsplugin", &nfsPlugin.Spec.Template.Spec)
+		applyVolumeMountToContainer(r.opConfig.Parameters, nfsPluginVolumeMount, "csi-nfsplugin", &nfsPlugin.Spec.Template.Spec)
 		err = ownerInfo.SetControllerReference(nfsPlugin)
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to nfs plugin daemonset %q", nfsPlugin.Name)
@@ -602,13 +598,13 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 
 	if nfsProvisionerDeployment != nil {
 		// get NFS provisioner tolerations and node affinity, defaults to common tolerations and node affinity if not specified
-		nfsProvisionerTolerations := getToleration(nfsProvisionerTolerationsEnv, provisionerTolerations)
-		nfsProvisionerNodeAffinity := getNodeAffinity(nfsProvisionerNodeAffinityEnv, provisionerNodeAffinity)
+		nfsProvisionerTolerations := getToleration(r.opConfig.Parameters, nfsProvisionerTolerationsEnv, provisionerTolerations)
+		nfsProvisionerNodeAffinity := getNodeAffinity(r.opConfig.Parameters, nfsProvisionerNodeAffinityEnv, provisionerNodeAffinity)
 		// apply NFS provisioner tolerations and node affinity
 		applyToPodSpec(&nfsProvisionerDeployment.Spec.Template.Spec, nfsProvisionerNodeAffinity, nfsProvisionerTolerations)
 		// get resource details for nfs provisioner
 		// apply resource request and limit to nfs provisioner containers
-		applyResourcesToContainers(nfsProvisionerResource, &nfsProvisionerDeployment.Spec.Template.Spec)
+		applyResourcesToContainers(r.opConfig.Parameters, nfsProvisionerResource, &nfsProvisionerDeployment.Spec.Template.Spec)
 		err = ownerInfo.SetControllerReference(nfsProvisionerDeployment)
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to nfs provisioner deployment %q", nfsProvisionerDeployment.Name)
@@ -634,7 +630,7 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 	if EnableRBD {
 		err = csiDriverobj.createCSIDriverInfo(
 			r.opManagerContext, r.context.Clientset,
-			RBDDriverName, k8sutil.GetOperatorSetting("CSI_RBD_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
+			RBDDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_RBD_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
 			tp.Param.RBDAttachRequired, CSIParam.EnableCSIDriverSeLinuxMount)
 		if err != nil {
 			return errors.Wrapf(err, "failed to create CSI driver object for %q", RBDDriverName)
@@ -643,7 +639,7 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 	if EnableCephFS {
 		err = csiDriverobj.createCSIDriverInfo(
 			r.opManagerContext, r.context.Clientset,
-			CephFSDriverName, k8sutil.GetOperatorSetting("CSI_CEPHFS_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
+			CephFSDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_CEPHFS_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
 			tp.Param.CephFSAttachRequired, CSIParam.EnableCSIDriverSeLinuxMount)
 		if err != nil {
 			return errors.Wrapf(err, "failed to create CSI driver object for %q", CephFSDriverName)
@@ -651,7 +647,7 @@ func (r *ReconcileCSI) startDrivers(ownerInfo *k8sutil.OwnerInfo) error {
 	}
 	if EnableNFS {
 		err = csiDriverobj.createCSIDriverInfo(r.opManagerContext, r.context.Clientset,
-			NFSDriverName, k8sutil.GetOperatorSetting("CSI_NFS_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
+			NFSDriverName, k8sutil.GetValue(r.opConfig.Parameters, "CSI_NFS_FSGROUPPOLICY", string(k8scsi.FileFSGroupPolicy)),
 			tp.Param.NFSAttachRequired, CSIParam.EnableCSIDriverSeLinuxMount)
 		if err != nil {
 			return errors.Wrapf(err, "failed to create CSI driver object for %q", NFSDriverName)
diff --git a/pkg/operator/ceph/csi/template/cephfs/csi-cephfsplugin-provisioner-dep.yaml b/pkg/operator/ceph/csi/template/cephfs/csi-cephfsplugin-provisioner-dep.yaml
index ff9554ad7..5ed29f704 100644
--- a/pkg/operator/ceph/csi/template/cephfs/csi-cephfsplugin-provisioner-dep.yaml
+++ b/pkg/operator/ceph/csi/template/cephfs/csi-cephfsplugin-provisioner-dep.yaml
@@ -216,7 +216,7 @@ spec:
             - "--node-id=$(NODE_ID)"
             - "--v={{ .LogLevel }}"
             - "--csi-addons-address=$(CSIADDONS_ENDPOINT)"
-            - "--controller-port={{ .CSIAddonsCephFSProvisionerPort }}"
+            - "--controller-port={{ .CSIAddonsPort }}"
             - "--pod=$(POD_NAME)"
             - "--namespace=$(POD_NAMESPACE)"
             - "--pod-uid=$(POD_UID)"
@@ -231,7 +231,7 @@ spec:
             - "--log_file={{ .CsiLogRootPath }}/log/{{ .CsiComponentName }}/csi-addons.log"
             {{ end }}
           ports:
-            - containerPort: {{ .CSIAddonsCephFSProvisionerPort }}
+            - containerPort: {{ .CSIAddonsPort }}
           env:
             - name: NODE_ID
               valueFrom:
diff --git a/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin-provisioner-dep.yaml b/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin-provisioner-dep.yaml
index bacd76682..135338322 100644
--- a/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin-provisioner-dep.yaml
+++ b/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin-provisioner-dep.yaml
@@ -169,7 +169,7 @@ spec:
             - "--node-id=$(NODE_ID)"
             - "--v={{ .LogLevel }}"
             - "--csi-addons-address=$(CSIADDONS_ENDPOINT)"
-            - "--controller-port={{ .CSIAddonsRBDProvisionerPort }}"
+            - "--controller-port={{ .CSIAddonsPort }}"
             - "--pod=$(POD_NAME)"
             - "--namespace=$(POD_NAMESPACE)"
             - "--pod-uid=$(POD_UID)"
@@ -184,7 +184,7 @@ spec:
             - "--log_file={{ .CsiLogRootPath }}/log/{{ .CsiComponentName }}/csi-addons.log"
             {{ end }}
           ports:
-            - containerPort: {{ .CSIAddonsRBDProvisionerPort }}
+            - containerPort: {{ .CSIAddonsPort }}
           env:
             - name: NODE_ID
               valueFrom:
diff --git a/pkg/operator/ceph/csi/util.go b/pkg/operator/ceph/csi/util.go
index 60f549bb1..4c3e70827 100644
--- a/pkg/operator/ceph/csi/util.go
+++ b/pkg/operator/ceph/csi/util.go
@@ -98,8 +98,8 @@ func applyLogrotateSidecar(specTemplate *corev1.PodTemplateSpec, name, templateD
 	specTemplate.Spec.Containers = append(specTemplate.Spec.Containers, logrotateSidecarContainer)
 }
 
-func applyResourcesToContainers(key string, podspec *corev1.PodSpec) {
-	resource := getComputeResource(key)
+func applyResourcesToContainers(opConfig map[string]string, key string, podspec *corev1.PodSpec) {
+	resource := getComputeResource(opConfig, key)
 
 	for _, r := range resource {
 		for i, c := range podspec.Containers {
@@ -110,12 +110,12 @@ func applyResourcesToContainers(key string, podspec *corev1.PodSpec) {
 	}
 }
 
-func getComputeResource(key string) []k8sutil.ContainerResource {
+func getComputeResource(opConfig map[string]string, key string) []k8sutil.ContainerResource {
 	// Add Resource list if any
 	resource := []k8sutil.ContainerResource{}
 	var err error
 
-	if resourceRaw := k8sutil.GetOperatorSetting(key, ""); resourceRaw != "" {
+	if resourceRaw := k8sutil.GetValue(opConfig, key, ""); resourceRaw != "" {
 		resource, err = k8sutil.YamlToContainerResourceArray(resourceRaw)
 		if err != nil {
 			logger.Warningf("failed to parse %q. %v", resourceRaw, err)
@@ -124,9 +124,9 @@ func getComputeResource(key string) []k8sutil.ContainerResource {
 	return resource
 }
 
-func getToleration(tolerationsName string, defaultTolerations []corev1.Toleration) []corev1.Toleration {
+func getToleration(opConfig map[string]string, tolerationsName string, defaultTolerations []corev1.Toleration) []corev1.Toleration {
 	// Add toleration if any, otherwise return defaultTolerations
-	tolerationsRaw := k8sutil.GetOperatorSetting(tolerationsName, "")
+	tolerationsRaw := k8sutil.GetValue(opConfig, tolerationsName, "")
 	if tolerationsRaw == "" {
 		return defaultTolerations
 	}
@@ -147,9 +147,9 @@ func getToleration(tolerationsName string, defaultTolerations []corev1.Toleratio
 	return tolerations
 }
 
-func getNodeAffinity(nodeAffinityName string, defaultNodeAffinity *corev1.NodeAffinity) *corev1.NodeAffinity {
+func getNodeAffinity(opConfig map[string]string, nodeAffinityName string, defaultNodeAffinity *corev1.NodeAffinity) *corev1.NodeAffinity {
 	// Add NodeAffinity if any, otherwise return defaultNodeAffinity
-	nodeAffinity := k8sutil.GetOperatorSetting(nodeAffinityName, "")
+	nodeAffinity := k8sutil.GetValue(opConfig, nodeAffinityName, "")
 	if nodeAffinity == "" {
 		return defaultNodeAffinity
 	}
@@ -168,9 +168,9 @@ func applyToPodSpec(pod *corev1.PodSpec, n *corev1.NodeAffinity, t []corev1.Tole
 	}
 }
 
-func getPortFromConfig(env string, defaultPort uint16) (uint16, error) {
-	port := k8sutil.GetOperatorSetting(env, strconv.Itoa(int(defaultPort)))
-	if strings.TrimSpace(k8sutil.GetOperatorSetting(env, strconv.Itoa(int(defaultPort)))) == "" {
+func getPortFromConfig(data map[string]string, env string, defaultPort uint16) (uint16, error) {
+	port := k8sutil.GetValue(data, env, strconv.Itoa(int(defaultPort)))
+	if strings.TrimSpace(k8sutil.GetValue(data, env, strconv.Itoa(int(defaultPort)))) == "" {
 		return defaultPort, nil
 	}
 	p, err := strconv.ParseUint(port, 10, 64)
@@ -203,8 +203,8 @@ func GetPodAntiAffinity(key, value string) corev1.PodAntiAffinity {
 	}
 }
 
-func applyVolumeToPodSpec(configName string, podspec *corev1.PodSpec) {
-	volumesRaw := k8sutil.GetOperatorSetting(configName, "")
+func applyVolumeToPodSpec(opConfig map[string]string, configName string, podspec *corev1.PodSpec) {
+	volumesRaw := k8sutil.GetValue(opConfig, configName, "")
 	if volumesRaw == "" {
 		return
 	}
@@ -230,8 +230,8 @@ func applyVolumeToPodSpec(configName string, podspec *corev1.PodSpec) {
 	}
 }
 
-func applyVolumeMountToContainer(configName, containerName string, podspec *corev1.PodSpec) {
-	volumeMountsRaw := k8sutil.GetOperatorSetting(configName, "")
+func applyVolumeMountToContainer(opConfig map[string]string, configName, containerName string, podspec *corev1.PodSpec) {
+	volumeMountsRaw := k8sutil.GetValue(opConfig, configName, "")
 	if volumeMountsRaw == "" {
 		return
 	}
@@ -267,8 +267,8 @@ func applyVolumeMountToContainer(configName, containerName string, podspec *core
 
 // getImage returns the image for the given setting name. If the image does not contain version,
 // the default version is appended from the default image.
-func getImage(settingName, defaultImage string) string {
-	image := k8sutil.GetOperatorSetting(settingName, defaultImage)
+func getImage(data map[string]string, settingName, defaultImage string) string {
+	image := k8sutil.GetValue(data, settingName, defaultImage)
 	if !strings.Contains(image, ":") {
 		version := strings.SplitN(defaultImage, ":", 2)[1]
 		image = fmt.Sprintf("%s:%s", image, version)
diff --git a/pkg/operator/ceph/file/mds/livenessprobe.sh b/pkg/operator/ceph/file/mds/livenessprobe.sh
index 667bb8e4a..5cddfac15 100644
--- a/pkg/operator/ceph/file/mds/livenessprobe.sh
+++ b/pkg/operator/ceph/file/mds/livenessprobe.sh
@@ -7,8 +7,7 @@ FILESYSTEM_NAME="{{ .FilesystemName }}"
 KEYRING="{{ .Keyring }}"
 CMD_TIMEOUT="{{ .CmdTimeout }}"
 
-export CEPH_ARGS="--keyring $KEYRING" # workaround for https://tracker.ceph.com/issues/70167
-outp="$(ceph fs dump --mon-host="$ROOK_CEPH_MON_HOST" --mon-initial-members="$ROOK_CEPH_MON_INITIAL_MEMBERS" --name="mds.$MDS_ID" --connect-timeout="$CMD_TIMEOUT" --format json)"
+outp="$(ceph fs dump --mon-host="$ROOK_CEPH_MON_HOST" --mon-initial-members="$ROOK_CEPH_MON_INITIAL_MEMBERS" --keyring "$KEYRING" --connect-timeout="$CMD_TIMEOUT" --format json)"
 rc=$?
 if [ $rc -ne 0 ]; then
     echo "ceph MDS dump check failed with the following output:"
diff --git a/pkg/operator/ceph/object/bucket/controller.go b/pkg/operator/ceph/object/bucket/controller.go
index b9a4007f7..eed00adc9 100644
--- a/pkg/operator/ceph/object/bucket/controller.go
+++ b/pkg/operator/ceph/object/bucket/controller.go
@@ -36,6 +36,7 @@ import (
 	v1 "k8s.io/api/core/v1"
 	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
 )
 
 const (
@@ -139,6 +140,25 @@ func (r *ReconcileBucket) reconcile(request reconcile.Request) (reconcile.Result
 		return reconcile.Result{}, nil
 	}
 
+	// Fetch the operator's configmap. We force the NamespaceName to the operator since the request
+	// could be a CephCluster. If so the NamespaceName will be the one from the cluster and thus the
+	// CM won't be found
+	opNamespaceName := types.NamespacedName{Name: opcontroller.OperatorSettingConfigMapName, Namespace: r.opConfig.OperatorNamespace}
+	opConfig := &v1.ConfigMap{}
+	err = r.client.Get(r.opManagerContext, opNamespaceName, opConfig)
+	if err != nil {
+		if kerrors.IsNotFound(err) {
+			logger.Debug("operator's configmap resource not found. will use default value or env var.")
+			r.opConfig.Parameters = make(map[string]string)
+		} else {
+			// Error reading the object - requeue the request.
+			return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed to get operator's configmap")
+		}
+	} else {
+		// Populate the operator's config
+		r.opConfig.Parameters = opConfig.Data
+	}
+
 	// Populate clusterInfo during each reconcile
 	clusterInfo, _, _, err := opcontroller.LoadClusterInfo(r.context, r.opManagerContext, cephCluster.Namespace, &cephCluster.Spec)
 	if err != nil {
@@ -157,7 +177,7 @@ func (r *ReconcileBucket) reconcile(request reconcile.Request) (reconcile.Result
 
 	// note: the error return below is ignored and is expected to be removed from the
 	//   bucket library's `NewProvisioner` function
-	bucketController, _ := NewBucketController(r.context.KubeConfig, bucketProvisioner)
+	bucketController, _ := NewBucketController(r.context.KubeConfig, bucketProvisioner, r.opConfig.Parameters)
 
 	// We must run this in a go routine since RunWithContext() blocks and waits for the context to
 	// be Done. However, since it has a context, the go routine will exit on reload with SIGHUP
diff --git a/pkg/operator/ceph/object/bucket/util.go b/pkg/operator/ceph/object/bucket/util.go
index 7e8df47ea..19e294cb9 100644
--- a/pkg/operator/ceph/object/bucket/util.go
+++ b/pkg/operator/ceph/object/bucket/util.go
@@ -43,9 +43,9 @@ const (
 	objectStoreEndpoint  = "endpoint"
 )
 
-func NewBucketController(cfg *rest.Config, p *Provisioner) (*provisioner.Provisioner, error) {
+func NewBucketController(cfg *rest.Config, p *Provisioner, data map[string]string) (*provisioner.Provisioner, error) {
 	const allNamespaces = ""
-	provName, err := cephObject.GetObjectBucketProvisioner(p.clusterInfo.Namespace)
+	provName, err := cephObject.GetObjectBucketProvisioner(data, p.clusterInfo.Namespace)
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to get provisioner name")
 	}
diff --git a/pkg/operator/ceph/object/objectstore.go b/pkg/operator/ceph/object/objectstore.go
index 67a41626a..080367731 100644
--- a/pkg/operator/ceph/object/objectstore.go
+++ b/pkg/operator/ceph/object/objectstore.go
@@ -1137,10 +1137,10 @@ func poolName(poolPrefix, poolName string) string {
 }
 
 // GetObjectBucketProvisioner returns the bucket provisioner name appended with operator namespace if OBC is watching on it
-func GetObjectBucketProvisioner(namespace string) (string, error) {
+func GetObjectBucketProvisioner(data map[string]string, namespace string) (string, error) {
 	provName := bucketProvisionerName
-	obcWatchOnNamespace := k8sutil.GetOperatorSetting("ROOK_OBC_WATCH_OPERATOR_NAMESPACE", "false")
-	obcProvisionerNamePrefix := k8sutil.GetOperatorSetting("ROOK_OBC_PROVISIONER_NAME_PREFIX", "")
+	obcWatchOnNamespace := k8sutil.GetValue(data, "ROOK_OBC_WATCH_OPERATOR_NAMESPACE", "false")
+	obcProvisionerNamePrefix := k8sutil.GetValue(data, "ROOK_OBC_PROVISIONER_NAME_PREFIX", "")
 	if obcProvisionerNamePrefix != "" {
 		errList := validation.IsDNS1123Label(obcProvisionerNamePrefix)
 		if len(errList) > 0 {
diff --git a/pkg/operator/ceph/operator.go b/pkg/operator/ceph/operator.go
index 2674c41ab..e43ba8c78 100644
--- a/pkg/operator/ceph/operator.go
+++ b/pkg/operator/ceph/operator.go
@@ -129,11 +129,6 @@ func (o *Operator) runCRDManager() {
 	// Create the context and the cancellation function
 	opManagerContext, opManagerStop = context.WithCancel(context.Background())
 
-	// Initialize the operator settings from the configmap
-	if err := k8sutil.ApplyOperatorSettingsConfigmap(opManagerContext, o.context.Clientset); err != nil {
-		panic("failed to load operator settings configmap. " + err.Error())
-	}
-
 	// The operator config manager is also watching for changes here so if the operator config map
 	// content changes for ROOK_CURRENT_NAMESPACE_ONLY we must reload the operator CRD manager
 	o.namespaceToWatch()
@@ -154,7 +149,7 @@ func (o *Operator) runCRDManager() {
 }
 
 func (o *Operator) namespaceToWatch() {
-	currentNamespaceOnly := k8sutil.GetOperatorSetting("ROOK_CURRENT_NAMESPACE_ONLY", "true")
+	currentNamespaceOnly, _ := k8sutil.GetOperatorSetting(opManagerContext, o.context.Clientset, opcontroller.OperatorSettingConfigMapName, "ROOK_CURRENT_NAMESPACE_ONLY", "true")
 	if currentNamespaceOnly == "true" {
 		o.config.NamespaceToWatch = o.config.OperatorNamespace
 		logger.Infof("watching the current namespace %q for Ceph CRs", o.config.OperatorNamespace)
diff --git a/pkg/operator/discover/discover.go b/pkg/operator/discover/discover.go
index dca033d57..5b73b8cc0 100644
--- a/pkg/operator/discover/discover.go
+++ b/pkg/operator/discover/discover.go
@@ -73,16 +73,16 @@ func New(clientset kubernetes.Interface) *Discover {
 }
 
 // Start the discover
-func (d *Discover) Start(ctx context.Context, namespace, discoverImage, securityAccount string, useCephVolume bool) error {
-	err := d.createDiscoverDaemonSet(ctx, namespace, discoverImage, securityAccount, useCephVolume)
+func (d *Discover) Start(ctx context.Context, namespace, discoverImage, securityAccount string, data map[string]string, useCephVolume bool) error {
+	err := d.createDiscoverDaemonSet(ctx, namespace, discoverImage, securityAccount, data, useCephVolume)
 	if err != nil {
 		return fmt.Errorf("failed to start discover daemonset. %v", err)
 	}
 	return nil
 }
 
-func (d *Discover) createDiscoverDaemonSet(ctx context.Context, namespace, discoverImage, securityAccount string, useCephVolume bool) error {
-	discoveryInterval := k8sutil.GetOperatorSetting(discoverIntervalEnv, defaultDiscoverInterval)
+func (d *Discover) createDiscoverDaemonSet(ctx context.Context, namespace, discoverImage, securityAccount string, data map[string]string, useCephVolume bool) error {
+	discoveryInterval := k8sutil.GetValue(data, discoverIntervalEnv, defaultDiscoverInterval)
 
 	discoveryParameters := []string{"discover",
 		"--discover-interval", discoveryInterval}
@@ -90,7 +90,7 @@ func (d *Discover) createDiscoverDaemonSet(ctx context.Context, namespace, disco
 		discoveryParameters = append(discoveryParameters, "--use-ceph-volume")
 	}
 
-	discoverDaemonResourcesRaw := k8sutil.GetOperatorSetting(discoverDaemonResourcesEnv, "")
+	discoverDaemonResourcesRaw := k8sutil.GetValue(data, discoverDaemonResourcesEnv, "")
 	discoverDaemonResources, err := k8sutil.YamlToContainerResource(discoverDaemonResourcesRaw)
 	if err != nil {
 		logger.Warningf("failed to parse.%s %v", discoverDaemonResourcesRaw, err)
@@ -176,7 +176,7 @@ func (d *Discover) createDiscoverDaemonSet(ctx context.Context, namespace, disco
 						},
 					},
 					HostNetwork:       opcontroller.EnforceHostNetwork(),
-					PriorityClassName: k8sutil.GetOperatorSetting(discoverDaemonsetPriorityClassNameEnv, ""),
+					PriorityClassName: k8sutil.GetValue(data, discoverDaemonsetPriorityClassNameEnv, ""),
 					SecurityContext:   &v1.PodSecurityContext{},
 				},
 			},
@@ -191,18 +191,18 @@ func (d *Discover) createDiscoverDaemonSet(ctx context.Context, namespace, disco
 	}
 
 	// Add toleration if any
-	tolerationValue := k8sutil.GetOperatorSetting(discoverDaemonsetTolerationEnv, "")
+	tolerationValue := k8sutil.GetValue(data, discoverDaemonsetTolerationEnv, "")
 	if tolerationValue != "" {
 		ds.Spec.Template.Spec.Tolerations = []v1.Toleration{
 			{
 				Effect:   v1.TaintEffect(tolerationValue),
 				Operator: v1.TolerationOpExists,
-				Key:      k8sutil.GetOperatorSetting(discoverDaemonsetTolerationKeyEnv, ""),
+				Key:      k8sutil.GetValue(data, discoverDaemonsetTolerationKeyEnv, ""),
 			},
 		}
 	}
 
-	tolerationsRaw := k8sutil.GetOperatorSetting(discoverDaemonsetTolerationsEnv, "")
+	tolerationsRaw := k8sutil.GetValue(data, discoverDaemonsetTolerationsEnv, "")
 	tolerations, err := k8sutil.YamlToTolerations(tolerationsRaw)
 	if err != nil {
 		logger.Warningf("failed to parse %s. %+v", tolerationsRaw, err)
@@ -211,7 +211,7 @@ func (d *Discover) createDiscoverDaemonSet(ctx context.Context, namespace, disco
 	ds.Spec.Template.Spec.Tolerations = append(ds.Spec.Template.Spec.Tolerations, tolerations...)
 
 	// Add NodeAffinity if any
-	nodeAffinity := k8sutil.GetOperatorSetting(discoverDaemonSetNodeAffinityEnv, "")
+	nodeAffinity := k8sutil.GetValue(data, discoverDaemonSetNodeAffinityEnv, "")
 	if nodeAffinity != "" {
 		v1NodeAffinity, err := k8sutil.GenerateNodeAffinity(nodeAffinity)
 		if err != nil {
@@ -224,7 +224,7 @@ func (d *Discover) createDiscoverDaemonSet(ctx context.Context, namespace, disco
 		logger.Infof("nodeAffinity: %s", v1NodeAffinity)
 	}
 
-	podLabels := k8sutil.GetOperatorSetting(discoverDaemonSetPodLabelsEnv, "")
+	podLabels := k8sutil.GetValue(data, discoverDaemonSetPodLabelsEnv, "")
 	if podLabels != "" {
 		podLabels := k8sutil.ParseStringToLabels(podLabels)
 		// Override / Set the app label even if set by the user as
diff --git a/pkg/operator/k8sutil/configmap.go b/pkg/operator/k8sutil/configmap.go
index 7e57bb7d7..08b932430 100644
--- a/pkg/operator/k8sutil/configmap.go
+++ b/pkg/operator/k8sutil/configmap.go
@@ -20,17 +20,17 @@ import (
 	"context"
 	"fmt"
 	"os"
+	"sync"
 	"time"
 
 	"github.com/pkg/errors"
 	v1 "k8s.io/api/core/v1"
 	kerrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/client-go/kubernetes"
 )
 
-var loadedOperatorSettings bool
+var loggedOperatorSettings = sync.Map{}
 
 // DeleteConfigMap deletes a ConfigMap.
 func DeleteConfigMap(ctx context.Context, clientset kubernetes.Interface, cmName, namespace string, opts *DeleteOptions) error {
@@ -70,43 +70,50 @@ func CreateOrUpdateConfigMap(ctx context.Context, clientset kubernetes.Interface
 	return existingCm, nil
 }
 
-// GetOperatorSetting gets the operator setting from Env Var merged with ConfigMap
+// GetOperatorSetting gets the operator setting from ConfigMap or Env Var
 // returns defaultValue if setting is not found
-func GetOperatorSetting(settingName, defaultValue string) string {
-	if !loadedOperatorSettings {
-		logger.Warningf("WARNING: attempting to load operator setting %q before configmap is loaded", settingName)
-	}
-	if settingValue, ok := os.LookupEnv(settingName); ok {
-		return settingValue
+func GetOperatorSetting(context context.Context, clientset kubernetes.Interface, configMapName, settingName, defaultValue string) (string, error) {
+	// config must be in operator pod namespace
+	namespace := os.Getenv(PodNamespaceEnvVar)
+	cm, err := clientset.CoreV1().ConfigMaps(namespace).Get(context, configMapName, metav1.GetOptions{})
+	if err != nil {
+		if kerrors.IsNotFound(err) {
+			if settingValue, ok := os.LookupEnv(settingName); ok {
+				logger.Infof("%s=%q (env var)", settingName, settingValue)
+				return settingValue, nil
+			}
+			logger.Infof("%s=%q (default)", settingName, defaultValue)
+			return defaultValue, nil
+		}
+		return defaultValue, fmt.Errorf("error reading ConfigMap %q. %v", configMapName, err)
 	}
-	return defaultValue
+
+	return GetValue(cm.Data, settingName, defaultValue), nil
 }
 
-func ApplyOperatorSettingsConfigmap(ctx context.Context, clientset kubernetes.Interface) error {
-	namespacedName := types.NamespacedName{Namespace: os.Getenv(PodNamespaceEnvVar), Name: "rook-ceph-operator-config"}
-	logger.Debugf("loading operator settings configmap from %v", namespacedName)
-	opConfig, err := clientset.CoreV1().ConfigMaps(namespacedName.Namespace).Get(ctx, namespacedName.Name, metav1.GetOptions{})
+func GetValue(data map[string]string, settingName, defaultValue string) string {
+	settingValue := defaultValue
+	settingSource := "default"
 
-	if err != nil {
-		if kerrors.IsNotFound(err) {
-			loadedOperatorSettings = true
-			logger.Debug("operator's configmap resource not found. will use default value or env var.")
-			return nil
-		}
-		return err
+	if val, ok := data[settingName]; ok {
+		settingValue = val
+		settingSource = "configmap"
+	} else if val, ok := os.LookupEnv(settingName); ok {
+		settingValue = val
+		settingSource = "env var"
 	}
 
-	for key, value := range opConfig.Data {
-		currentValue := os.Getenv(key)
-		if currentValue == value {
-			continue
-		}
-		logger.Infof("operator setting %q = %q", key, value)
-		if err := os.Setenv(key, value); err != nil {
-			logger.Errorf("failed to set env var %q = %q. %v", key, value, err)
-		}
+	if logChangedSettings(settingName, settingValue) {
+		logger.Infof("%s=%q (%s)", settingName, settingValue, settingSource)
+	}
+
+	return settingValue
+}
+
+func logChangedSettings(settingName, settingValue string) bool {
+	if val, ok := loggedOperatorSettings.Load(settingName); !ok || val != settingValue {
+		loggedOperatorSettings.Store(settingName, settingValue)
+		return true
 	}
-	loadedOperatorSettings = true
-	logger.Debug("done loading operator settings configmap")
-	return nil
+	return false
 }


Test patch:
diff --git a/.github/workflows/integration-test-helm-suite.yaml b/.github/workflows/integration-test-helm-suite.yaml
index f5ec52506..5a847d84c 100644
--- a/.github/workflows/integration-test-helm-suite.yaml
+++ b/.github/workflows/integration-test-helm-suite.yaml
@@ -65,7 +65,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-helm-suite-artifact-${{ matrix.kubernetes-versions }}
diff --git a/.github/workflows/integration-test-keystone-auth-suite.yaml b/.github/workflows/integration-test-keystone-auth-suite.yaml
index 73873f084..dd7aa3ebb 100644
--- a/.github/workflows/integration-test-keystone-auth-suite.yaml
+++ b/.github/workflows/integration-test-keystone-auth-suite.yaml
@@ -63,7 +63,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-keystone-auth-suite-artifact-${{ matrix.kubernetes-versions }}
diff --git a/.github/workflows/integration-test-mgr-suite.yaml b/.github/workflows/integration-test-mgr-suite.yaml
index 1eda6481e..2b2f2de38 100644
--- a/.github/workflows/integration-test-mgr-suite.yaml
+++ b/.github/workflows/integration-test-mgr-suite.yaml
@@ -60,7 +60,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-mgr-suite-artifact-${{ matrix.kubernetes-versions }}
diff --git a/.github/workflows/integration-test-multi-cluster-suite.yaml b/.github/workflows/integration-test-multi-cluster-suite.yaml
index f2643dfd3..3604195dd 100644
--- a/.github/workflows/integration-test-multi-cluster-suite.yaml
+++ b/.github/workflows/integration-test-multi-cluster-suite.yaml
@@ -64,7 +64,7 @@ jobs:
           CLUSTER_NAMESPACE="multi-external" tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-multi-cluster-deploy-suite-artifact-${{ matrix.kubernetes-versions }}
diff --git a/.github/workflows/integration-test-object-suite.yaml b/.github/workflows/integration-test-object-suite.yaml
index 92127a4e1..98c7b5ada 100644
--- a/.github/workflows/integration-test-object-suite.yaml
+++ b/.github/workflows/integration-test-object-suite.yaml
@@ -61,7 +61,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-object-suite-artifact-${{ matrix.kubernetes-versions }}
diff --git a/.github/workflows/integration-test-smoke-suite.yaml b/.github/workflows/integration-test-smoke-suite.yaml
index b865f04d5..d7822dd13 100644
--- a/.github/workflows/integration-test-smoke-suite.yaml
+++ b/.github/workflows/integration-test-smoke-suite.yaml
@@ -61,7 +61,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-smoke-suite-artifact-${{ matrix.kubernetes-versions }}
diff --git a/.github/workflows/integration-test-upgrade-suite.yaml b/.github/workflows/integration-test-upgrade-suite.yaml
index 10ba2772c..16344d8d1 100644
--- a/.github/workflows/integration-test-upgrade-suite.yaml
+++ b/.github/workflows/integration-test-upgrade-suite.yaml
@@ -61,7 +61,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-upgrade-suite-artifact-${{ matrix.kubernetes-versions }}
@@ -109,7 +109,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-upgrade-helm-suite-artifact-${{ matrix.kubernetes-versions }}
diff --git a/.github/workflows/integration-tests-on-release.yaml b/.github/workflows/integration-tests-on-release.yaml
index e62cc10bc..2ae2efac9 100644
--- a/.github/workflows/integration-tests-on-release.yaml
+++ b/.github/workflows/integration-tests-on-release.yaml
@@ -50,7 +50,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-helm-suite-artifact-${{ matrix.kubernetes-versions }}
@@ -91,7 +91,7 @@ jobs:
           CLUSTER_NAMESPACE="multi-external" tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-multi-cluster-deploy-suite-artifact-${{ matrix.kubernetes-versions }}
@@ -129,7 +129,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-smoke-suite-artifact-${{ matrix.kubernetes-versions }}
@@ -167,7 +167,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-upgrade-suite-artifact-${{ matrix.kubernetes-versions }}
@@ -208,7 +208,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-upgrade-suite-artifact-${{ matrix.kubernetes-versions }}
@@ -246,7 +246,7 @@ jobs:
           tests/scripts/collect-logs.sh
 
       - name: Artifact
-        uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
+        uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
         if: failure()
         with:
           name: ceph-object-suite-artifact-${{ matrix.kubernetes-versions }}
diff --git a/pkg/operator/ceph/controller/controller_utils_test.go b/pkg/operator/ceph/controller/controller_utils_test.go
index d1eac8297..cda45d991 100644
--- a/pkg/operator/ceph/controller/controller_utils_test.go
+++ b/pkg/operator/ceph/controller/controller_utils_test.go
@@ -18,7 +18,6 @@ package controller
 
 import (
 	ctx "context"
-	"os"
 	"testing"
 	"time"
 
@@ -81,94 +80,83 @@ func TestCanIgnoreHealthErrStatusInReconcile(t *testing.T) {
 }
 
 func TestSetCephCommandsTimeout(t *testing.T) {
-	defer os.Unsetenv("ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS")
-
-	SetCephCommandsTimeout()
+	SetCephCommandsTimeout(map[string]string{})
 	assert.Equal(t, 15*time.Second, exec.CephCommandsTimeout)
 
 	exec.CephCommandsTimeout = 0
-	os.Setenv("ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS", "0")
-	SetCephCommandsTimeout()
+	SetCephCommandsTimeout(map[string]string{"ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS": "0"})
 	assert.Equal(t, 15*time.Second, exec.CephCommandsTimeout)
 
 	exec.CephCommandsTimeout = 0
-	os.Setenv("ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS", "1")
-	SetCephCommandsTimeout()
+	SetCephCommandsTimeout(map[string]string{"ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS": "1"})
 	assert.Equal(t, 1*time.Second, exec.CephCommandsTimeout)
 }
 
 func TestSetAllowLoopDevices(t *testing.T) {
-	defer os.Unsetenv("ROOK_CEPH_ALLOW_LOOP_DEVICES")
-
-	SetAllowLoopDevices()
+	SetAllowLoopDevices(map[string]string{})
 	assert.False(t, LoopDevicesAllowed())
 
-	os.Setenv("ROOK_CEPH_ALLOW_LOOP_DEVICES", "foo")
-	SetAllowLoopDevices()
+	SetAllowLoopDevices(map[string]string{"ROOK_CEPH_ALLOW_LOOP_DEVICES": "foo"})
 	assert.False(t, LoopDevicesAllowed())
 
-	os.Setenv("ROOK_CEPH_ALLOW_LOOP_DEVICES", "false")
-	SetAllowLoopDevices()
+	SetAllowLoopDevices(map[string]string{"ROOK_CEPH_ALLOW_LOOP_DEVICES": "false"})
 	assert.False(t, LoopDevicesAllowed())
 
-	os.Setenv("ROOK_CEPH_ALLOW_LOOP_DEVICES", "true")
-	SetAllowLoopDevices()
+	SetAllowLoopDevices(map[string]string{"ROOK_CEPH_ALLOW_LOOP_DEVICES": "true"})
 	assert.True(t, LoopDevicesAllowed())
 }
 
 func TestSetEnforceHostNetwork(t *testing.T) {
-	defer os.Unsetenv(enforceHostNetworkSettingName)
-
 	logger.Infof("testing default value for %v", enforceHostNetworkSettingName)
-	SetEnforceHostNetwork()
+	opConfig := map[string]string{}
+	SetEnforceHostNetwork(opConfig)
 	assert.False(t, EnforceHostNetwork())
 
 	// test invalid setting
 	var value string = "foo"
 	logger.Infof("testing invalid value'%v' for %v", value, enforceHostNetworkSettingName)
-	os.Setenv(enforceHostNetworkSettingName, value)
-	SetEnforceHostNetwork()
+	opConfig[enforceHostNetworkSettingName] = value
+	SetEnforceHostNetwork(opConfig)
 	assert.False(t, EnforceHostNetwork())
 
 	// test valid settings
 	value = "true"
 	logger.Infof("testing valid value'%v' for %v", value, enforceHostNetworkSettingName)
-	os.Setenv(enforceHostNetworkSettingName, value)
-	SetEnforceHostNetwork()
+	opConfig[enforceHostNetworkSettingName] = value
+	SetEnforceHostNetwork(opConfig)
 	assert.True(t, EnforceHostNetwork())
 
 	value = "false"
 	logger.Infof("testing valid value'%v' for %v", value, enforceHostNetworkSettingName)
-	os.Setenv(enforceHostNetworkSettingName, value)
-	SetEnforceHostNetwork()
+	opConfig[enforceHostNetworkSettingName] = value
+	SetEnforceHostNetwork(opConfig)
 	assert.False(t, EnforceHostNetwork())
 }
 
 func TestSetRevisionHistoryLimit(t *testing.T) {
-	defer os.Unsetenv(revisionHistoryLimitSettingName)
-
+	opConfig := map[string]string{}
 	t.Run("ROOK_REVISION_HISTORY_LIMIT: test default value", func(t *testing.T) {
-		SetRevisionHistoryLimit()
+		SetRevisionHistoryLimit(opConfig)
 		assert.Nil(t, RevisionHistoryLimit())
 	})
 
 	var value string = "foo"
 	t.Run("ROOK_REVISION_HISTORY_LIMIT: test invalid value 'foo'", func(t *testing.T) {
-		os.Setenv(revisionHistoryLimitSettingName, value)
-		SetRevisionHistoryLimit()
+		opConfig[revisionHistoryLimitSettingName] = value
+		SetRevisionHistoryLimit(opConfig)
 		assert.Nil(t, RevisionHistoryLimit())
 	})
 
 	t.Run("ROOK_REVISION_HISTORY_LIMIT: test empty string value", func(t *testing.T) {
 		value = ""
-		os.Setenv(revisionHistoryLimitSettingName, value)
-		SetRevisionHistoryLimit()
+		opConfig[revisionHistoryLimitSettingName] = value
+		SetRevisionHistoryLimit(opConfig)
 		assert.Nil(t, RevisionHistoryLimit())
 	})
 	t.Run("ROOK_REVISION_HISTORY_LIMIT:  test valig value '10'", func(t *testing.T) {
 		value = "10"
-		os.Setenv(revisionHistoryLimitSettingName, value)
-		SetRevisionHistoryLimit()
+		opConfig[revisionHistoryLimitSettingName] = value
+		SetRevisionHistoryLimit(opConfig)
 		assert.Equal(t, int32(10), *RevisionHistoryLimit())
 	})
 }
@@ -261,39 +249,36 @@ func TestIsReadyToReconcile(t *testing.T) {
 
 func TestObcAllowAdditionalConfigFields(t *testing.T) {
 	tests := []struct {
-		name             string
-		additionalConfig string
-		shouldAllow      []string
-		shouldDisallow   []string
+		name           string
+		data           map[string]string
+		shouldAllow    []string
+		shouldDisallow []string
 	}{
-		{"not set", "<notset>",
+		{"not set", map[string]string{},
 			[]string{"maxObjects", "maxSize"}, // default allowlist is unlikely to need changing EVER
 			[]string{"bucketMaxObjects", "bucketMaxSize", "bucketPolicy", "bucketLifecycle", "bucketOwner", "random"}},
-		{"set to empty", "",
+		{"set to empty", map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": ""},
 			[]string{}, // admin can allow no quota options if desired
 			[]string{"maxObjects", "maxSize", "bucketMaxObjects", "bucketMaxSize", "bucketPolicy", "bucketLifecycle", "bucketOwner", "random"}},
-		{"set to default", "maxObjects,maxSize",
+		{"set to default", map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "maxObjects,maxSize"},
 			[]string{"maxObjects", "maxSize"},
 			[]string{"bucketMaxObjects", "bucketMaxSize", "bucketPolicy", "bucketLifecycle", "bucketOwner", "random"}},
-		{"all quota fields", "maxObjects,maxSize,bucketMaxObjects,bucketMaxSize",
+		{"all quota fields", map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "maxObjects,maxSize,bucketMaxObjects,bucketMaxSize"},
 			[]string{"maxObjects", "maxSize", "bucketMaxObjects", "bucketMaxSize"},
 			[]string{"bucketPolicy", "bucketLifecycle", "bucketOwner", "random"}},
-		{"all fields", "maxObjects,maxSize,bucketMaxObjects,bucketMaxSize,bucketPolicy,bucketLifecycle,bucketOwner",
+		{"all fields", map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "maxObjects,maxSize,bucketMaxObjects,bucketMaxSize,bucketPolicy,bucketLifecycle,bucketOwner"},
 			[]string{"maxObjects", "maxSize", "bucketMaxObjects", "bucketMaxSize", "bucketPolicy", "bucketLifecycle", "bucketOwner"},
 			[]string{"random"}},
 		// this mechanism doesn't do any field checking - that isn't it's job - it merely handles
 		// allow-listing essentially arbitrary config keys
-		{"all fields including unknown", "maxObjects,maxSize,bucketMaxObjects,bucketMaxSize,bucketPolicy,bucketLifecycle,bucketOwner,random",
+		{"all fields including unknown", map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "maxObjects,maxSize,bucketMaxObjects,bucketMaxSize,bucketPolicy,bucketLifecycle,bucketOwner,random"},
 			[]string{"maxObjects", "maxSize", "bucketMaxObjects", "bucketMaxSize", "bucketPolicy", "bucketLifecycle", "bucketOwner", "random"},
 			[]string{"otherRandom"}},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if tt.additionalConfig != "<notset>" {
-				os.Setenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS", tt.additionalConfig)
-				defer os.Unsetenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS")
-			}
-			SetObcAllowAdditionalConfigFields()
+			SetObcAllowAdditionalConfigFields(tt.data)
+
 			for _, toAllow := range tt.shouldAllow {
 				assert.True(t, ObcAdditionalConfigKeyIsAllowed(toAllow))
 			}
diff --git a/pkg/operator/ceph/controller_test.go b/pkg/operator/ceph/controller_test.go
index a9f08b672..ed4485611 100644
--- a/pkg/operator/ceph/controller_test.go
+++ b/pkg/operator/ceph/controller_test.go
@@ -23,6 +23,7 @@ import (
 	"time"
 
 	"github.com/coreos/pkg/capnslog"
+	cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
 	rookclient "github.com/rook/rook/pkg/client/clientset/versioned/fake"
 	"github.com/rook/rook/pkg/client/clientset/versioned/scheme"
 	"github.com/rook/rook/pkg/clusterd"
@@ -30,7 +31,9 @@ import (
 	"github.com/rook/rook/pkg/operator/test"
 	"github.com/rook/rook/pkg/util/exec"
 	"github.com/stretchr/testify/assert"
+	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
 	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -61,6 +64,7 @@ func TestOperatorController(t *testing.T) {
 
 		// Register operator types with the runtime scheme.
 		s := scheme.Scheme
+		s.AddKnownTypes(cephv1.SchemeGroupVersion, &v1.ConfigMap{}, &v1.ConfigMapList{})
 
 		// Create a fake client to mock API calls.
 		cl := fake.NewClientBuilder().WithScheme(s).Build()
@@ -91,6 +95,7 @@ func TestOperatorController(t *testing.T) {
 
 		// Register operator types with the runtime scheme.
 		s := scheme.Scheme
+		s.AddKnownTypes(cephv1.SchemeGroupVersion, &v1.ConfigMap{}, &v1.ConfigMapList{})
 
 		// Create a fake client to mock API calls.
 		cl := fake.NewClientBuilder().WithScheme(s).Build()
@@ -123,12 +128,23 @@ func TestOperatorController(t *testing.T) {
 		// Register operator types with the runtime scheme.
 		// s := scheme.Scheme
 		s := clientgoscheme.Scheme
+		// s.AddKnownTypes(cephv1.SchemeGroupVersion, &v1.ConfigMap{})
 
-		os.Setenv("ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS", "20")
-		defer os.Unsetenv("ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS")
+		opConfigCM := &v1.ConfigMap{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      controller.OperatorSettingConfigMapName,
+				Namespace: namespace,
+			},
+			Data: map[string]string{
+				"ROOK_CEPH_COMMANDS_TIMEOUT_SECONDS": "20",
+			},
+		}
 
+		object := []runtime.Object{
+			opConfigCM,
+		}
 		// Create a fake client to mock API calls.
-		cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects().Build()
+		cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(object...).Build()
 
 		// Create a ReconcileCSI object with the scheme and fake client.
 		r := &ReconcileConfig{
@@ -157,6 +173,7 @@ func TestOperatorController(t *testing.T) {
 
 		// Register operator types with the runtime scheme.
 		s := scheme.Scheme
+		s.AddKnownTypes(cephv1.SchemeGroupVersion, &v1.ConfigMap{}, &v1.ConfigMapList{})
 
 		// Create a fake client to mock API calls.
 		cl := fake.NewClientBuilder().WithScheme(s).Build()
@@ -192,12 +209,23 @@ func TestOperatorController(t *testing.T) {
 		// Register operator types with the runtime scheme.
 		// s := scheme.Scheme
 		s := clientgoscheme.Scheme
+		// s.AddKnownTypes(cephv1.SchemeGroupVersion, &v1.ConfigMap{})
 
-		os.Setenv("ROOK_CEPH_ALLOW_LOOP_DEVICES", "true")
-		defer os.Unsetenv("ROOK_CEPH_ALLOW_LOOP_DEVICES")
+		opConfigCM := &v1.ConfigMap{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      controller.OperatorSettingConfigMapName,
+				Namespace: namespace,
+			},
+			Data: map[string]string{
+				"ROOK_CEPH_ALLOW_LOOP_DEVICES": "true",
+			},
+		}
 
+		object := []runtime.Object{
+			opConfigCM,
+		}
 		// Create a fake client to mock API calls.
-		cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects().Build()
+		cl := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(object...).Build()
 
 		// Create a ReconcileCSI object with the scheme and fake client.
 		r := &ReconcileConfig{
diff --git a/pkg/operator/ceph/csi/util_test.go b/pkg/operator/ceph/csi/util_test.go
index 74860696e..29f5cbced 100644
--- a/pkg/operator/ceph/csi/util_test.go
+++ b/pkg/operator/ceph/csi/util_test.go
@@ -47,27 +47,28 @@ func TestDeploymentTemplate(t *testing.T) {
 func TestGetPortFromConfig(t *testing.T) {
 	key := "TEST_CSI_PORT_ENV"
 	var defaultPort uint16 = 8000
+	data := map[string]string{}
 
 	// empty env variable
-	port, err := getPortFromConfig(key, defaultPort)
+	port, err := getPortFromConfig(data, key, defaultPort)
 	assert.Nil(t, err)
 	assert.Equal(t, port, defaultPort)
 
 	// valid port is set in env
 	t.Setenv(key, "9000")
-	port, err = getPortFromConfig(key, defaultPort)
+	port, err = getPortFromConfig(data, key, defaultPort)
 	assert.Nil(t, err)
 	assert.Equal(t, port, uint16(9000))
 
 	// higher port value is set in env
 	t.Setenv(key, "65536")
-	port, err = getPortFromConfig(key, defaultPort)
+	port, err = getPortFromConfig(data, key, defaultPort)
 	assert.Error(t, err)
 	assert.Equal(t, port, defaultPort)
 
 	// negative port is set in env
 	t.Setenv(key, "-1")
-	port, err = getPortFromConfig(key, defaultPort)
+	port, err = getPortFromConfig(data, key, defaultPort)
 	assert.Error(t, err)
 	assert.Equal(t, port, defaultPort)
 
@@ -79,6 +80,7 @@ func TestApplyingResourcesToRBDPlugin(t *testing.T) {
 	tp := templateParam{}
 	rbdPlugin, err := templateToDaemonSet("rbdplugin", RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
+	params := make(map[string]string)
 
 	// need to build using map[string]interface{} because the following resource
 	// doesn't serialise nicely
@@ -101,9 +103,8 @@ func TestApplyingResourcesToRBDPlugin(t *testing.T) {
 
 	resourceRaw, err := yaml.Marshal(resource)
 	assert.Nil(t, err)
-	os.Setenv(rbdPluginResource, string(resourceRaw))
-	defer os.Unsetenv(rbdPluginResource)
-	applyResourcesToContainers(rbdPluginResource, &rbdPlugin.Spec.Template.Spec)
+	params[rbdPluginResource] = string(resourceRaw)
+	applyResourcesToContainers(params, rbdPluginResource, &rbdPlugin.Spec.Template.Spec)
 	assert.Equal(t, rbdPlugin.Spec.Template.Spec.Containers[0].Resources.Requests.Memory().String(), "128Mi")
 	assert.Equal(t, rbdPlugin.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().String(), "256Mi")
 	assert.Equal(t, rbdPlugin.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu().String(), "100m")
@@ -112,6 +113,7 @@ func TestApplyingResourcesToRBDPlugin(t *testing.T) {
 
 func Test_applyVolumeToPodSpec(t *testing.T) {
 	// when no volumes specified
+	config := make(map[string]string)
 	configKey := "TEST_CSI_PLUGIN_VOLUME"
 	dsName := "test-ds"
 	tp := templateParam{
@@ -122,7 +124,7 @@ func Test_applyVolumeToPodSpec(t *testing.T) {
 	defaultVolumes := 11
 	ds, err := templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeToPodSpec(configKey, &ds.Spec.Template.Spec)
+	applyVolumeToPodSpec(config, configKey, &ds.Spec.Template.Spec)
 
 	assert.Len(t, ds.Spec.Template.Spec.Volumes, defaultVolumes)
 
@@ -130,7 +132,7 @@ func Test_applyVolumeToPodSpec(t *testing.T) {
 	tp.CSILogRotation = true
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeToPodSpec(configKey, &ds.Spec.Template.Spec)
+	applyVolumeToPodSpec(config, configKey, &ds.Spec.Template.Spec)
 	assert.Len(t, ds.Spec.Template.Spec.Volumes, defaultVolumes+2)
 	tp.CSILogRotation = false
 
@@ -143,11 +145,10 @@ func Test_applyVolumeToPodSpec(t *testing.T) {
 	}
 	volumeRaw, err := yaml.Marshal(volumes)
 	assert.Nil(t, err)
-	os.Setenv(configKey, string(volumeRaw))
-	defer os.Unsetenv(configKey)
+	config[configKey] = string(volumeRaw)
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeToPodSpec(configKey, &ds.Spec.Template.Spec)
+	applyVolumeToPodSpec(config, configKey, &ds.Spec.Template.Spec)
 
 	assert.Len(t, ds.Spec.Template.Spec.Volumes, defaultVolumes+1)
 	// add one more volume
@@ -157,10 +158,10 @@ func Test_applyVolumeToPodSpec(t *testing.T) {
 	})
 	volumeRaw, err = yaml.Marshal(volumes)
 	assert.Nil(t, err)
-	os.Setenv(configKey, string(volumeRaw))
+	config[configKey] = string(volumeRaw)
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeToPodSpec(configKey, &ds.Spec.Template.Spec)
+	applyVolumeToPodSpec(config, configKey, &ds.Spec.Template.Spec)
 	assert.Len(t, ds.Spec.Template.Spec.Volumes, defaultVolumes+2)
 	// override existing volume configuration
 	volumes[1].VolumeSource = corev1.VolumeSource{
@@ -168,10 +169,10 @@ func Test_applyVolumeToPodSpec(t *testing.T) {
 	}
 	volumeRaw, err = yaml.Marshal(volumes)
 	assert.Nil(t, err)
-	os.Setenv(configKey, string(volumeRaw))
+	config[configKey] = string(volumeRaw)
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeToPodSpec(configKey, &ds.Spec.Template.Spec)
+	applyVolumeToPodSpec(config, configKey, &ds.Spec.Template.Spec)
 	assert.Len(t, ds.Spec.Template.Spec.Volumes, defaultVolumes+2)
 	// remove existing volume configuration
 	volumes = []corev1.Volume{
@@ -182,15 +183,16 @@ func Test_applyVolumeToPodSpec(t *testing.T) {
 	}
 	volumeRaw, err = yaml.Marshal(volumes)
 	assert.Nil(t, err)
-	os.Setenv(configKey, string(volumeRaw))
+	config[configKey] = string(volumeRaw)
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeToPodSpec(configKey, &ds.Spec.Template.Spec)
+	applyVolumeToPodSpec(config, configKey, &ds.Spec.Template.Spec)
 	assert.Len(t, ds.Spec.Template.Spec.Volumes, defaultVolumes+1)
 }
 
 func Test_applyVolumeMountToContainer(t *testing.T) {
 	// when no volumes specified
+	config := make(map[string]string)
 	configKey := "TEST_CSI_PLUGIN_VOLUME_MOUNT"
 	dsName := "test-ds"
 	rbdContainerName := "csi-rbdplugin"
@@ -202,7 +204,7 @@ func Test_applyVolumeMountToContainer(t *testing.T) {
 	defaultVolumes := 10
 	ds, err := templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeMountToContainer(configKey, rbdContainerName, &ds.Spec.Template.Spec)
+	applyVolumeMountToContainer(config, configKey, rbdContainerName, &ds.Spec.Template.Spec)
 
 	assert.Len(t, ds.Spec.Template.Spec.Containers[1].VolumeMounts, defaultVolumes)
 
@@ -210,7 +212,7 @@ func Test_applyVolumeMountToContainer(t *testing.T) {
 	tp.CSILogRotation = true
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeMountToContainer(configKey, rbdContainerName, &ds.Spec.Template.Spec)
+	applyVolumeMountToContainer(config, configKey, rbdContainerName, &ds.Spec.Template.Spec)
 	assert.Len(t, ds.Spec.Template.Spec.Containers[1].VolumeMounts, defaultVolumes+1)
 	tp.CSILogRotation = false
 
@@ -223,11 +225,10 @@ func Test_applyVolumeMountToContainer(t *testing.T) {
 	}
 	volumeMountsRaw, err := yaml.Marshal(volumeMounts)
 	assert.Nil(t, err)
-	os.Setenv(configKey, string(volumeMountsRaw))
-	defer os.Unsetenv(configKey)
+	config[configKey] = string(volumeMountsRaw)
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeMountToContainer(configKey, rbdContainerName, &ds.Spec.Template.Spec)
+	applyVolumeMountToContainer(config, configKey, rbdContainerName, &ds.Spec.Template.Spec)
 
 	assert.Len(t, ds.Spec.Template.Spec.Containers[1].VolumeMounts, defaultVolumes+1)
 	// add one more volumemount
@@ -237,19 +238,19 @@ func Test_applyVolumeMountToContainer(t *testing.T) {
 	})
 	volumeMountsRaw, err = yaml.Marshal(volumeMounts)
 	assert.Nil(t, err)
-	os.Setenv(configKey, string(volumeMountsRaw))
+	config[configKey] = string(volumeMountsRaw)
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeMountToContainer(configKey, rbdContainerName, &ds.Spec.Template.Spec)
+	applyVolumeMountToContainer(config, configKey, rbdContainerName, &ds.Spec.Template.Spec)
 	assert.Len(t, ds.Spec.Template.Spec.Containers[1].VolumeMounts, defaultVolumes+2)
 	// override existing volume configuration
 	volumeMounts[1].MountPath = "/run/test/run"
 	volumeMountsRaw, err = yaml.Marshal(volumeMounts)
 	assert.Nil(t, err)
-	os.Setenv(configKey, string(volumeMountsRaw))
+	config[configKey] = string(volumeMountsRaw)
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeMountToContainer(configKey, rbdContainerName, &ds.Spec.Template.Spec)
+	applyVolumeMountToContainer(config, configKey, rbdContainerName, &ds.Spec.Template.Spec)
 	assert.Len(t, ds.Spec.Template.Spec.Containers[1].VolumeMounts, defaultVolumes+2)
 	// remove existing volume configuration
 	volumeMounts = []corev1.VolumeMount{
@@ -260,16 +261,17 @@ func Test_applyVolumeMountToContainer(t *testing.T) {
 	}
 	volumeMountsRaw, err = yaml.Marshal(volumeMounts)
 	assert.Nil(t, err)
-	os.Setenv(configKey, string(volumeMountsRaw))
+	config[configKey] = string(volumeMountsRaw)
 	ds, err = templateToDaemonSet(dsName, RBDPluginTemplatePath, tp)
 	assert.Nil(t, err)
-	applyVolumeMountToContainer(configKey, rbdContainerName, &ds.Spec.Template.Spec)
+	applyVolumeMountToContainer(config, configKey, rbdContainerName, &ds.Spec.Template.Spec)
 	assert.Len(t, ds.Spec.Template.Spec.Containers[1].VolumeMounts, defaultVolumes+1)
 }
 
 func Test_getImage(t *testing.T) {
 	type args struct {
-		userImage    string
+		data         map[string]string
+		settingName  string
 		defaultImage string
 	}
 	tests := []struct {
@@ -280,6 +282,8 @@ func Test_getImage(t *testing.T) {
 		{
 			name: "test with default image",
 			args: args{
+				data:         map[string]string{},
+				settingName:  "ROOK_CSI_CEPH_IMAGE",
 				defaultImage: "quay.io/cephcsi/cephcsi:v3.13.0",
 			},
 			want: DefaultCSIPluginImage,
@@ -287,7 +291,10 @@ func Test_getImage(t *testing.T) {
 		{
 			name: "test with user image",
 			args: args{
-				userImage:    "registry.io/private/cephcsi:v8",
+				data: map[string]string{
+					"ROOK_CSI_CEPH_IMAGE": "registry.io/private/cephcsi:v8",
+				},
+				settingName:  "ROOK_CSI_CEPH_IMAGE",
 				defaultImage: "quay.io/cephcsi/cephcsi:v3.11.0",
 			},
 			want: "registry.io/private/cephcsi:v8",
@@ -295,7 +302,10 @@ func Test_getImage(t *testing.T) {
 		{
 			name: "test with user image without version",
 			args: args{
-				userImage:    "registry.io/private/cephcsi",
+				data: map[string]string{
+					"ROOK_CSI_CEPH_IMAGE": "registry.io/private/cephcsi",
+				},
+				settingName:  "ROOK_CSI_CEPH_IMAGE",
 				defaultImage: "quay.io/cephcsi/cephcsi:v3.11.0",
 			},
 			want: "registry.io/private/cephcsi:v3.11.0",
@@ -303,11 +313,7 @@ func Test_getImage(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if tt.args.userImage != "" {
-				os.Setenv("ROOK_CSI_CEPH_IMAGE", tt.args.userImage)
-				defer os.Unsetenv("ROOK_CSI_CEPH_IMAGE")
-			}
-			got := getImage("ROOK_CSI_CEPH_IMAGE", tt.args.defaultImage)
+			got := getImage(tt.args.data, tt.args.settingName, tt.args.defaultImage)
 			assert.Equal(t, tt.want, got)
 		})
 	}
diff --git a/pkg/operator/ceph/object/bucket/provisioner_test.go b/pkg/operator/ceph/object/bucket/provisioner_test.go
index 0e44132a4..a098b51f9 100644
--- a/pkg/operator/ceph/object/bucket/provisioner_test.go
+++ b/pkg/operator/ceph/object/bucket/provisioner_test.go
@@ -22,7 +22,6 @@ import (
 	"fmt"
 	"io"
 	"net/http"
-	"os"
 	"strings"
 	"testing"
 
@@ -502,7 +501,7 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("maxObjects field should be set", func(t *testing.T) {
-		opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		spec, err := additionalConfigSpecFromMap(map[string]string{"maxObjects": "2"})
 		assert.NoError(t, err)
@@ -511,7 +510,7 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("maxSize field should be set", func(t *testing.T) {
-		opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		spec, err := additionalConfigSpecFromMap(map[string]string{"maxSize": "3"})
 		assert.NoError(t, err)
@@ -520,10 +519,8 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("bucketMaxObjects field should be set", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS", "bucketMaxObjects")
-		defer os.Unsetenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS")
-		opcontroller.SetObcAllowAdditionalConfigFields()
-		defer opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "bucketMaxObjects"})
+		defer opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		spec, err := additionalConfigSpecFromMap(map[string]string{"bucketMaxObjects": "4"})
 		assert.NoError(t, err)
@@ -531,10 +528,8 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("bucketMaxSize field should be set", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS", "bucketMaxSize")
-		defer os.Unsetenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS")
-		opcontroller.SetObcAllowAdditionalConfigFields()
-		defer opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "bucketMaxSize"})
+		defer opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		spec, err := additionalConfigSpecFromMap(map[string]string{"bucketMaxSize": "5"})
 		assert.NoError(t, err)
@@ -542,10 +537,8 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("bucketPolicy field should be set", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS", "bucketPolicy")
-		defer os.Unsetenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS")
-		opcontroller.SetObcAllowAdditionalConfigFields()
-		defer opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "bucketPolicy"})
+		defer opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		spec, err := additionalConfigSpecFromMap(map[string]string{"bucketPolicy": "foo"})
 		assert.NoError(t, err)
@@ -553,10 +546,8 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("bucketLifecycle field should be set", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS", "bucketLifecycle")
-		defer os.Unsetenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS")
-		opcontroller.SetObcAllowAdditionalConfigFields()
-		defer opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "bucketLifecycle"})
+		defer opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		spec, err := additionalConfigSpecFromMap(map[string]string{"bucketLifecycle": "foo"})
 		assert.NoError(t, err)
@@ -564,10 +555,8 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("bucketOwner field should be set", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS", "bucketOwner")
-		defer os.Unsetenv("ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS")
-		opcontroller.SetObcAllowAdditionalConfigFields()
-		defer opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{"ROOK_OBC_ALLOW_ADDITIONAL_CONFIG_FIELDS": "bucketOwner"})
+		defer opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		spec, err := additionalConfigSpecFromMap(map[string]string{"bucketOwner": "foo"})
 		assert.NoError(t, err)
@@ -575,7 +564,7 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("fields disallowed by default", func(t *testing.T) {
-		opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		for _, configKey := range []string{"bucketMaxObjects", "bucketMaxSize", "bucketPolicy", "bucketLifecycle", "bucketOwner"} {
 			_, err := additionalConfigSpecFromMap(map[string]string{configKey: "foo"})
@@ -584,7 +573,7 @@ func TestProvisioner_additionalConfigSpecFromMap(t *testing.T) {
 	})
 
 	t.Run("does not fail on empty map", func(t *testing.T) {
-		opcontroller.SetObcAllowAdditionalConfigFields()
+		opcontroller.SetObcAllowAdditionalConfigFields(map[string]string{})
 
 		spec, err := additionalConfigSpecFromMap(map[string]string{})
 		assert.NoError(t, err)
diff --git a/pkg/operator/ceph/object/objectstore_test.go b/pkg/operator/ceph/object/objectstore_test.go
index 8359e9897..f384d6c70 100644
--- a/pkg/operator/ceph/object/objectstore_test.go
+++ b/pkg/operator/ceph/object/objectstore_test.go
@@ -517,43 +517,36 @@ func TestGetObjectBucketProvisioner(t *testing.T) {
 	t.Setenv(k8sutil.PodNamespaceEnvVar, testNamespace)
 
 	t.Run("watch ceph cluster namespace", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_WATCH_OPERATOR_NAMESPACE", "true")
-		defer os.Unsetenv("ROOK_OBC_WATCH_OPERATOR_NAMESPACE")
-		bktprovisioner, err := GetObjectBucketProvisioner(testNamespace)
+		data := map[string]string{"ROOK_OBC_WATCH_OPERATOR_NAMESPACE": "true"}
+		bktprovisioner, err := GetObjectBucketProvisioner(data, testNamespace)
 		assert.Equal(t, fmt.Sprintf("%s.%s", testNamespace, bucketProvisionerName), bktprovisioner)
 		assert.NoError(t, err)
 	})
 
 	t.Run("watch all namespaces", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_WATCH_OPERATOR_NAMESPACE", "false")
-		defer os.Unsetenv("ROOK_OBC_WATCH_OPERATOR_NAMESPACE")
-		bktprovisioner, err := GetObjectBucketProvisioner(testNamespace)
+		data := map[string]string{"ROOK_OBC_WATCH_OPERATOR_NAMESPACE": "false"}
+		bktprovisioner, err := GetObjectBucketProvisioner(data, testNamespace)
 		assert.Equal(t, bucketProvisionerName, bktprovisioner)
 		assert.NoError(t, err)
 	})
 
 	t.Run("prefix object provisioner", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_PROVISIONER_NAME_PREFIX", "my-prefix")
-		defer os.Unsetenv("ROOK_OBC_PROVISIONER_NAME_PREFIX")
-		bktprovisioner, err := GetObjectBucketProvisioner(testNamespace)
+		data := map[string]string{"ROOK_OBC_PROVISIONER_NAME_PREFIX": "my-prefix"}
+		bktprovisioner, err := GetObjectBucketProvisioner(data, testNamespace)
 		assert.Equal(t, "my-prefix."+bucketProvisionerName, bktprovisioner)
 		assert.NoError(t, err)
 	})
 
 	t.Run("watch ceph cluster namespace and prefix object provisioner", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_WATCH_OPERATOR_NAMESPACE", "true")
-		os.Setenv("ROOK_OBC_PROVISIONER_NAME_PREFIX", "my-prefix")
-		defer os.Unsetenv("ROOK_OBC_WATCH_OPERATOR_NAMESPACE")
-		defer os.Unsetenv("ROOK_OBC_PROVISIONER_NAME_PREFIX")
-		bktprovisioner, err := GetObjectBucketProvisioner(testNamespace)
+		data := map[string]string{"ROOK_OBC_WATCH_OPERATOR_NAMESPACE": "true", "ROOK_OBC_PROVISIONER_NAME_PREFIX": "my-prefix"}
+		bktprovisioner, err := GetObjectBucketProvisioner(data, testNamespace)
 		assert.Equal(t, "my-prefix."+bucketProvisionerName, bktprovisioner)
 		assert.NoError(t, err)
 	})
 
 	t.Run("invalid prefix value for object provisioner", func(t *testing.T) {
-		os.Setenv("ROOK_OBC_PROVISIONER_NAME_PREFIX", "my-prefix.")
-		defer os.Unsetenv("ROOK_OBC_PROVISIONER_NAME_PREFIX")
-		_, err := GetObjectBucketProvisioner(testNamespace)
+		data := map[string]string{"ROOK_OBC_PROVISIONER_NAME_PREFIX": "my-prefix."}
+		_, err := GetObjectBucketProvisioner(data, testNamespace)
 		assert.Error(t, err)
 	})
 
diff --git a/pkg/operator/discover/discover_test.go b/pkg/operator/discover/discover_test.go
index ec19cc16e..667e88bdc 100644
--- a/pkg/operator/discover/discover_test.go
+++ b/pkg/operator/discover/discover_test.go
@@ -19,12 +19,12 @@ package discover
 
 import (
 	"context"
-	"os"
 	"testing"
 
 	cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
 	"github.com/rook/rook/pkg/clusterd"
 	discoverDaemon "github.com/rook/rook/pkg/daemon/discover"
+	"github.com/rook/rook/pkg/operator/ceph/controller"
 	"github.com/rook/rook/pkg/operator/k8sutil"
 	"github.com/rook/rook/pkg/operator/test"
 
@@ -63,7 +63,7 @@ func TestStartDiscoveryDaemonset(t *testing.T) {
 	_, err := clientset.CoreV1().Pods("rook-system").Create(ctx, &pod, metav1.CreateOptions{})
 	assert.NoError(t, err)
 	// start a basic cluster
-	err = a.Start(ctx, namespace, "rook/rook:myversion", "mysa", false)
+	err = a.Start(ctx, namespace, "rook/rook:myversion", "mysa", map[string]string{}, false)
 	assert.Nil(t, err)
 
 	// check daemonset parameters
@@ -86,11 +86,21 @@ func TestStartDiscoveryDaemonset(t *testing.T) {
 	assert.Nil(t, agentDS.Spec.Template.Spec.Tolerations)
 
 	// Test with rook override configmap setting
-	os.Setenv("DISCOVER_TOLERATIONS", "- effect: NoSchedule\n  key: node-role.kubernetes.io/control-plane\n  operator: Exists\n- effect: NoExecute\n  key: node-role.kubernetes.io/etcd\n  operator: Exists")
-	defer os.Unsetenv("DISCOVER_TOLERATIONS")
+	opConfigCM := &v1.ConfigMap{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      controller.OperatorSettingConfigMapName,
+			Namespace: namespace,
+		},
+		Data: map[string]string{
+			"DISCOVER_TOLERATIONS": "- effect: NoSchedule\n  key: node-role.kubernetes.io/control-plane\n  operator: Exists\n- effect: NoExecute\n  key: node-role.kubernetes.io/etcd\n  operator: Exists",
+		},
+	}
+
+	cm, err := clientset.CoreV1().ConfigMaps(namespace).Create(ctx, opConfigCM, metav1.CreateOptions{})
+	assert.NoError(t, err)
 
 	// start a basic cluster
-	err = a.Start(ctx, namespace, "rook/rook:myversion", "mysa", false)
+	err = a.Start(ctx, namespace, "rook/rook:myversion", "mysa", cm.Data, false)
 	assert.Nil(t, err)
 
 	agentDS, err = clientset.AppsV1().DaemonSets(namespace).Get(ctx, "rook-discover", metav1.GetOptions{})
diff --git a/pkg/operator/k8sutil/configmap_test.go b/pkg/operator/k8sutil/configmap_test.go
index d4577b0fc..cc03f1fcc 100644
--- a/pkg/operator/k8sutil/configmap_test.go
+++ b/pkg/operator/k8sutil/configmap_test.go
@@ -63,7 +63,7 @@ func TestGetOperatorSetting(t *testing.T) {
 	k8s := fake.NewSimpleClientset()
 	ctx := context.TODO()
 
-	operatorSettingConfigMapName := "rook-ceph-operator-config"
+	operatorSettingConfigMapName := "rook-operator-config"
 	testNamespace := "test-namespace"
 	cm := &v1.ConfigMap{
 		ObjectMeta: metav1.ObjectMeta{
@@ -81,41 +81,63 @@ func TestGetOperatorSetting(t *testing.T) {
 	cmSettingValue := "storage=rook, worker"
 	defaultValue := ""
 
-	// ConfigMap is not yet applied so we expect the default value
-	setting := GetOperatorSetting(nodeAffinity, defaultValue)
-	assert.Equal(t, defaultValue, setting)
+	// ConfigMap is not found
+	setting, err := GetOperatorSetting(ctx, k8s, operatorSettingConfigMapName, nodeAffinity, defaultValue)
+	assert.NoError(t, err)
 
+	// Env Var doesn't exist
+	assert.Equal(t, defaultValue, setting)
 	// Env Var exists
 	t.Setenv(nodeAffinity, envSettingValue)
-	setting = GetOperatorSetting(nodeAffinity, defaultValue)
+	setting, err = GetOperatorSetting(ctx, k8s, operatorSettingConfigMapName, nodeAffinity, defaultValue)
+	assert.NoError(t, err)
 	assert.Equal(t, envSettingValue, setting)
 
 	// ConfigMap is found
 	t.Setenv("POD_NAMESPACE", testNamespace)
-	_, err := k8s.CoreV1().ConfigMaps(testNamespace).Create(ctx, cm, metav1.CreateOptions{})
-	assert.NoError(t, err)
-	err = ApplyOperatorSettingsConfigmap(ctx, k8s)
+	_, err = k8s.CoreV1().ConfigMaps(testNamespace).Create(ctx, cm, metav1.CreateOptions{})
 	assert.NoError(t, err)
 
 	// Setting exists in ConfigMap
-	setting = GetOperatorSetting(nodeAffinity, defaultValue)
+	setting, err = GetOperatorSetting(ctx, k8s, operatorSettingConfigMapName, nodeAffinity, defaultValue)
+	assert.NoError(t, err)
+	// Env Var exists
 	assert.Equal(t, cmSettingValue, setting)
-
 	// Env Var doesn't exist
 	err = os.Unsetenv(nodeAffinity)
 	assert.NoError(t, err)
 	assert.Equal(t, cmSettingValue, setting)
 
-	// Setting doesn't exist in ConfigMap, expect the default value
-	setting = GetOperatorSetting(podAffinity, defaultValue)
+	// Setting doesn't exist in ConfigMap
+	setting, err = GetOperatorSetting(ctx, k8s, operatorSettingConfigMapName, podAffinity, defaultValue)
+	assert.NoError(t, err)
+	// Env Var doesn't exist
 	assert.Equal(t, defaultValue, setting)
 	// Env Var exists
 	t.Setenv(podAffinity, envSettingValue)
-	setting = GetOperatorSetting(podAffinity, defaultValue)
+	setting, err = GetOperatorSetting(ctx, k8s, operatorSettingConfigMapName, podAffinity, defaultValue)
 	assert.NoError(t, err)
 	assert.Equal(t, envSettingValue, setting)
 }
 
+func TestLogChangedSettings(t *testing.T) {
+	key := "Node_Affinity"
+	value := "storage=rook, worker"
+
+	// When the key is not in the map, it should be added and return true for logging
+	ok := logChangedSettings(key, value)
+	assert.True(t, true, ok)
+
+	// When the key is already present in the map and value is same, it should return false for logging
+	ok = logChangedSettings(key, value)
+	assert.False(t, false, ok)
+
+	// When the key is already present in the map and value is updated, it should return true for logging
+	value = "storage=rook, test"
+	ok = logChangedSettings(key, value)
+	assert.True(t, true, ok)
+}
+
 func TestCreateOrUpdateConfigMap(t *testing.T) {
 	k8s := fake.NewSimpleClientset()
 	ctx := context.TODO()