diff --git a/CHANGELOG.md b/CHANGELOG.md index 195f16280f0db..9a7e8bde58288 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Adding BackWardCompatibility test for remote publication enabled cluster ([#20221](https://github.com/opensearch-project/OpenSearch/pull/20221)) - Support for hll field mapper to support cardinality rollups ([#20129](https://github.com/opensearch-project/OpenSearch/pull/20129)) - Introduce new libs/netty4 module to share common implementation between netty-based plugins and modules (transport-netty4, transport-reactor-netty4) ([#20447](https://github.com/opensearch-project/OpenSearch/pull/20447)) +- Add validation to make crypto store settings immutable ([#20123](https://github.com/opensearch-project/OpenSearch/pull/20123)) ### Changed - Handle custom metadata files in subdirectory-store ([#20157](https://github.com/opensearch-project/OpenSearch/pull/20157)) @@ -85,4 +86,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Remove identity-shiro from plugins folder ([#20305](https://github.com/opensearch-project/OpenSearch/pull/20305)) -[Unreleased 3.x]: https://github.com/opensearch-project/OpenSearch/compare/3.4...main +[Unreleased 3.x]: https://github.com/opensearch-project/OpenSearch/compare/3.4...main \ No newline at end of file diff --git a/server/src/main/java/org/opensearch/cluster/metadata/MetadataUpdateSettingsService.java b/server/src/main/java/org/opensearch/cluster/metadata/MetadataUpdateSettingsService.java index fb512a0f7ea13..e57a2635b8a68 100644 --- a/server/src/main/java/org/opensearch/cluster/metadata/MetadataUpdateSettingsService.java +++ b/server/src/main/java/org/opensearch/cluster/metadata/MetadataUpdateSettingsService.java @@ -142,6 +142,7 @@ public void updateSettings( validateRefreshIntervalSettings(normalizedSettings, clusterService.getClusterSettings()); validateTranslogDurabilitySettings(normalizedSettings, clusterService.getClusterSettings(), clusterService.getSettings()); validateIndexTotalPrimaryShardsPerNodeSetting(normalizedSettings, clusterService); + validateCryptoStoreSettings(normalizedSettings, request.indices(), clusterService.state()); final int defaultReplicaCount = clusterService.getClusterSettings().get(Metadata.DEFAULT_REPLICA_COUNT_SETTING); Settings.Builder settingsForClosedIndices = Settings.builder(); @@ -589,4 +590,33 @@ public static void validateIndexTotalPrimaryShardsPerNodeSetting(Settings indexS ); } } + + /** + * Validates crypto store settings are immutable after index creation. + */ + public static void validateCryptoStoreSettings(Settings indexSettings, Index[] indices, ClusterState clusterState) { + final String storeTypeKey = "index.store.type"; + + // Only validate if store.type is being explicitly modified + if (!indexSettings.keySet().contains(storeTypeKey)) { + return; + } + + for (Index index : indices) { + String currentStoreType = clusterState.metadata().getIndexSafe(index).getSettings().get(storeTypeKey, ""); + String newStoreType = indexSettings.get(storeTypeKey); + + // Prevent changing FROM cryptofs to anything else (including null) + if ("cryptofs".equals(currentStoreType) && !"cryptofs".equals(newStoreType)) { + throw new IllegalArgumentException( + "Cannot change store type from 'cryptofs' for index [" + index.getName() + "] - cryptofs store type is immutable" + ); + } + + // Prevent changing TO cryptofs from any other type + if (!"cryptofs".equals(currentStoreType) && "cryptofs".equals(newStoreType)) { + throw new IllegalArgumentException("Cannot change store type to 'cryptofs' for index [" + index.getName() + "]"); + } + } + } }