Skip to content

Commit

Permalink
Add cluster setting cluster.restrict.index.replication_type t… (#10866)…
Browse files Browse the repository at this point in the history
… (#10876)

* Add cluster setting CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING to restrict setting of index setting replication type



* Add Changelog entry



* refactoring



---------

Signed-off-by: Poojita Raj <[email protected]>
  • Loading branch information
Poojita-Raj authored Oct 24, 2023
1 parent eda0b82 commit 83b0371
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- [Remote cluster state] Make index and global metadata upload timeout dynamic cluster settings ([#10814](https://github.com/opensearch-project/OpenSearch/pull/10814))
- Add search query categorizor ([#10255](https://github.com/opensearch-project/OpenSearch/pull/10255))
- Per request phase latency ([#10351](https://github.com/opensearch-project/OpenSearch/issues/10351))
- Added cluster setting cluster.restrict.index.replication_type to restrict setting of index setting replication type ([#10866](https://github.com/opensearch-project/OpenSearch/pull/10866))

### Dependencies
- Bumps jetty version to 9.4.52.v20230823 to fix GMS-2023-1857 ([#9822](https://github.com/opensearch-project/OpenSearch/pull/9822))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.opensearch.test.OpenSearchIntegTestCase;

import static org.opensearch.cluster.metadata.IndexMetadata.SETTING_REPLICATION_TYPE;
import static org.opensearch.indices.IndicesService.CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING;
import static org.opensearch.indices.IndicesService.CLUSTER_SETTING_REPLICATION_TYPE;

@OpenSearchIntegTestCase.ClusterScope(scope = OpenSearchIntegTestCase.Scope.TEST, numDataNodes = 0)
Expand Down Expand Up @@ -123,4 +124,30 @@ public void testIndexReplicationSettingOverridesDocRepClusterSetting() throws Ex
assertEquals(indicesService.indexService(anotherIndex).getIndexSettings().isSegRepEnabled(), false);
}

public void testIndexReplicationTypeWhenRestrictSettingTrue() {
testRestrictIndexReplicationTypeSetting(true, randomFrom(ReplicationType.values()));
}

public void testIndexReplicationTypeWhenRestrictSettingFalse() {
testRestrictIndexReplicationTypeSetting(false, randomFrom(ReplicationType.values()));
}

private void testRestrictIndexReplicationTypeSetting(boolean setRestrict, ReplicationType replicationType) {
String expectedExceptionMsg =
"Validation Failed: 1: index setting [index.replication.type] is not allowed to be set as [cluster.restrict.index.replication_type=true];";
String clusterManagerName = internalCluster().startNode(
Settings.builder().put(CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING.getKey(), setRestrict).build()
);
internalCluster().startDataOnlyNodes(1);

// Test create index fails
Settings indexSettings = Settings.builder().put(indexSettings()).put(SETTING_REPLICATION_TYPE, replicationType).build();
if (setRestrict) {
IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> createIndex(INDEX_NAME, indexSettings));
assertEquals(expectedExceptionMsg, exception.getMessage());
} else {
createIndex(INDEX_NAME, indexSettings);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,7 @@ List<String> getIndexSettingsValidationErrors(
if (forbidPrivateIndexSettings) {
validationErrors.addAll(validatePrivateSettingsNotExplicitlySet(settings, indexScopedSettings));
}
validateIndexReplicationTypeSettings(settings, clusterService.getClusterSettings()).ifPresent(validationErrors::add);
if (indexName.isEmpty() || indexName.get().charAt(0) != '.') {
// Apply aware replica balance validation only to non system indices
int replicaCount = settings.getAsInt(
Expand Down Expand Up @@ -1328,6 +1329,24 @@ private static List<String> validateIndexCustomPath(Settings settings, @Nullable
return validationErrors;
}

/**
* Validates {@code index.replication.type} is not set if {@code cluster.restrict.index.replication_type} is set to true.
*
* @param requestSettings settings passed in during index create request
* @param clusterSettings cluster setting
*/
private static Optional<String> validateIndexReplicationTypeSettings(Settings requestSettings, ClusterSettings clusterSettings) {
if (requestSettings.hasValue(SETTING_REPLICATION_TYPE)
&& clusterSettings.get(IndicesService.CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING)) {
return Optional.of(
"index setting [index.replication.type] is not allowed to be set as ["
+ IndicesService.CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING.getKey()
+ "=true]"
);
}
return Optional.empty();
}

/**
* Validates the settings and mappings for shrinking an index.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,8 @@ public void apply(Settings value, Settings current, Settings previous) {
RemoteClusterStateService.GLOBAL_METADATA_UPLOAD_TIMEOUT_SETTING,
RemoteStoreNodeService.REMOTE_STORE_COMPATIBILITY_MODE_SETTING,
IndicesService.CLUSTER_REMOTE_TRANSLOG_BUFFER_INTERVAL_SETTING,
IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING
IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING,
IndicesService.CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING
)
)
);
Expand Down
11 changes: 11 additions & 0 deletions server/src/main/java/org/opensearch/indices/IndicesService.java
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,17 @@ public class IndicesService extends AbstractLifecycleComponent
Property.Final
);

/**
* This setting is used to restrict creation of index where the 'index.replication.type' index setting is set.
* If disabled, the replication type can be specified.
*/
public static final Setting<Boolean> CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING = Setting.boolSetting(
"cluster.restrict.index.replication_type",
false,
Property.NodeScope,
Property.Final
);

/**
* The node's settings.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
import static org.opensearch.indices.IndicesService.CLUSTER_MINIMUM_INDEX_REFRESH_INTERVAL_SETTING;
import static org.opensearch.indices.IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING;
import static org.opensearch.indices.IndicesService.CLUSTER_REPLICATION_TYPE_SETTING;
import static org.opensearch.indices.IndicesService.CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING;
import static org.opensearch.indices.ShardLimitValidatorTests.createTestShardLimitService;
import static org.opensearch.node.Node.NODE_ATTRIBUTES;
import static org.opensearch.node.remotestore.RemoteStoreNodeAttribute.REMOTE_STORE_SEGMENT_REPOSITORY_NAME_ATTRIBUTE_KEY;
Expand Down Expand Up @@ -1186,6 +1187,8 @@ public void testvalidateIndexSettings() {
.put(AwarenessAllocationDecider.CLUSTER_ROUTING_ALLOCATION_AWARENESS_FORCE_GROUP_SETTING.getKey() + "zone.values", "a, b")
.put(AwarenessAllocationDecider.CLUSTER_ROUTING_ALLOCATION_AWARENESS_FORCE_GROUP_SETTING.getKey() + "rack.values", "c, d, e")
.put(AwarenessReplicaBalance.CLUSTER_ROUTING_ALLOCATION_AWARENESS_BALANCE_SETTING.getKey(), true)
.put(CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING.getKey(), true)
.put(SETTING_REPLICATION_TYPE, randomFrom(ReplicationType.values()))
.build();
ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
when(clusterService.getSettings()).thenReturn(settings);
Expand All @@ -1209,17 +1212,26 @@ public void testvalidateIndexSettings() {
);

List<String> validationErrors = checkerService.getIndexSettingsValidationErrors(settings, false, Optional.empty());
assertThat(validationErrors.size(), is(1));
assertThat(validationErrors.get(0), is("expected total copies needs to be a multiple of total awareness attributes [3]"));
assertThat(validationErrors.size(), is(2));
assertThat(
validationErrors.get(0),
is("index setting [index.replication.type] is not allowed to be set as [cluster.restrict.index.replication_type=true]")
);
assertThat(validationErrors.get(1), is("expected total copies needs to be a multiple of total awareness attributes [3]"));

settings = Settings.builder()
.put(AwarenessAllocationDecider.CLUSTER_ROUTING_ALLOCATION_AWARENESS_ATTRIBUTE_SETTING.getKey(), "zone, rack")
.put(AwarenessAllocationDecider.CLUSTER_ROUTING_ALLOCATION_AWARENESS_FORCE_GROUP_SETTING.getKey() + "zone.values", "a, b")
.put(AwarenessAllocationDecider.CLUSTER_ROUTING_ALLOCATION_AWARENESS_FORCE_GROUP_SETTING.getKey() + "rack.values", "c, d, e")
.put(AwarenessReplicaBalance.CLUSTER_ROUTING_ALLOCATION_AWARENESS_BALANCE_SETTING.getKey(), true)
.put(SETTING_NUMBER_OF_REPLICAS, 2)
.put(CLUSTER_RESTRICT_INDEX_REPLICATION_TYPE_SETTING.getKey(), false)
.put(SETTING_REPLICATION_TYPE, randomFrom(ReplicationType.values()))
.build();

clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
when(clusterService.getClusterSettings()).thenReturn(clusterSettings);

validationErrors = checkerService.getIndexSettingsValidationErrors(settings, false, Optional.empty());
assertThat(validationErrors.size(), is(0));

Expand Down

0 comments on commit 83b0371

Please sign in to comment.