Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cluster setting cluster.restrict.index.replication_type t… (#10866) #10876

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading