Skip to content

Commit e3dc205

Browse files
parkertimminsrjernst
authored andcommitted
Filter deprecated settings in CreateIndexFromSourceAction (elastic#120163)
When creating a destination index, filter any deprecated settings before copying the source settings to the dest index. Specifically, filter out settings with the property IndexSettingDeprecatedInV7AndRemovedInV8 or settings from a specific list which do not have this property but have no effect in v8. This also includes a change which reverts the changes that elastic#116996 made to MetadataCreateIndexService. That change factored the method copySettingsFromSource out of prepareResizeIndexSettings so it could be used to filter settings in CreateIndexFromSourceAction. The additional filtering of deprecated property caused the requirements in CreateIndexFromSourceAction and MetadataCreateIndexService to diverge. So this change reverts the original refactor to MetadataCreateIndexService and adds a method similar to copySettingsFromSource to CreateIndexFromSourceAction.
1 parent dd3cb9e commit e3dc205

File tree

4 files changed

+92
-36
lines changed

4 files changed

+92
-36
lines changed

docs/changelog/120163.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 120163
2+
summary: Filter deprecated settings when making dest index
3+
area: Data streams
4+
type: enhancement
5+
issues: []

server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexService.java

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,11 +1670,23 @@ static void prepareResizeIndexSettings(
16701670
throw new IllegalStateException("unknown resize type is " + type);
16711671
}
16721672

1673-
final Settings.Builder builder;
1673+
final Settings.Builder builder = Settings.builder();
16741674
if (copySettings) {
1675-
builder = copySettingsFromSource(true, sourceMetadata.getSettings(), indexScopedSettings, indexSettingsBuilder);
1675+
// copy all settings and non-copyable settings and settings that have already been set (e.g., from the request)
1676+
for (final String key : sourceMetadata.getSettings().keySet()) {
1677+
final Setting<?> setting = indexScopedSettings.get(key);
1678+
if (setting == null) {
1679+
assert indexScopedSettings.isPrivateSetting(key) : key;
1680+
} else if (setting.getProperties().contains(Setting.Property.NotCopyableOnResize)) {
1681+
continue;
1682+
}
1683+
// do not override settings that have already been set (for example, from the request)
1684+
if (indexSettingsBuilder.keys().contains(key)) {
1685+
continue;
1686+
}
1687+
builder.copy(key, sourceMetadata.getSettings());
1688+
}
16761689
} else {
1677-
builder = Settings.builder();
16781690
final Predicate<String> sourceSettingsPredicate = (s) -> (s.startsWith("index.similarity.")
16791691
|| s.startsWith("index.analysis.")
16801692
|| s.startsWith("index.sort.")
@@ -1692,36 +1704,6 @@ static void prepareResizeIndexSettings(
16921704
}
16931705
}
16941706

1695-
public static Settings.Builder copySettingsFromSource(
1696-
boolean copyPrivateSettings,
1697-
Settings sourceSettings,
1698-
IndexScopedSettings indexScopedSettings,
1699-
Settings.Builder indexSettingsBuilder
1700-
) {
1701-
final Settings.Builder builder = Settings.builder();
1702-
for (final String key : sourceSettings.keySet()) {
1703-
final Setting<?> setting = indexScopedSettings.get(key);
1704-
if (setting == null) {
1705-
assert indexScopedSettings.isPrivateSetting(key) : key;
1706-
if (copyPrivateSettings == false) {
1707-
continue;
1708-
}
1709-
} else if (setting.getProperties().contains(Setting.Property.NotCopyableOnResize)) {
1710-
continue;
1711-
} else if (setting.isPrivateIndex()) {
1712-
if (copyPrivateSettings == false) {
1713-
continue;
1714-
}
1715-
}
1716-
// do not override settings that have already been set (for example, from the request)
1717-
if (indexSettingsBuilder.keys().contains(key)) {
1718-
continue;
1719-
}
1720-
builder.copy(key, sourceSettings);
1721-
}
1722-
return builder;
1723-
}
1724-
17251707
/**
17261708
* Returns a default number of routing shards based on the number of shards of the index. The default number of routing shards will
17271709
* allow any index to be split at least once and at most 10 times by a factor of two. The closer the number or shards gets to 1024

x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceActionIT.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,41 @@ protected Collection<Class<? extends Plugin>> nodePlugins() {
4141
return List.of(MigratePlugin.class, ReindexPlugin.class, MockTransportService.TestPlugin.class, DataStreamsPlugin.class);
4242
}
4343

44+
public void testOldSettingsManuallyFiltered() throws Exception {
45+
assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled());
46+
47+
var numShards = randomIntBetween(1, 10);
48+
var staticSettings = Settings.builder()
49+
// setting to filter
50+
.put("index.soft_deletes.enabled", true)
51+
// good setting to keep
52+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, numShards)
53+
.build();
54+
55+
// start with a static setting
56+
var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT);
57+
indicesAdmin().create(new CreateIndexRequest(sourceIndex, staticSettings)).get();
58+
59+
// create from source
60+
var destIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT);
61+
assertAcked(
62+
client().execute(CreateIndexFromSourceAction.INSTANCE, new CreateIndexFromSourceAction.Request(sourceIndex, destIndex))
63+
);
64+
65+
// assert both static and dynamic settings set on dest index
66+
var settingsResponse = indicesAdmin().getSettings(new GetSettingsRequest().indices(sourceIndex, destIndex)).actionGet();
67+
var destSettings = settingsResponse.getIndexToSettings().get(destIndex);
68+
var sourceSettings = settingsResponse.getIndexToSettings().get(sourceIndex);
69+
70+
// sanity check that source settings were added
71+
assertEquals(true, sourceSettings.getAsBoolean("index.soft_deletes.enabled", false));
72+
assertEquals(numShards, Integer.parseInt(destSettings.get(IndexMetadata.SETTING_NUMBER_OF_SHARDS)));
73+
74+
// check that old setting was not added to index
75+
assertNull(destSettings.get("index.soft_deletes.enabled"));
76+
assertEquals(numShards, Integer.parseInt(destSettings.get(IndexMetadata.SETTING_NUMBER_OF_SHARDS)));
77+
}
78+
4479
public void testDestIndexCreated() throws Exception {
4580
assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled());
4681

x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceTransportAction.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@
1616
import org.elasticsearch.client.internal.Client;
1717
import org.elasticsearch.cluster.metadata.IndexMetadata;
1818
import org.elasticsearch.cluster.metadata.MappingMetadata;
19-
import org.elasticsearch.cluster.metadata.MetadataCreateIndexService;
2019
import org.elasticsearch.cluster.service.ClusterService;
2120
import org.elasticsearch.common.compress.CompressedXContent;
2221
import org.elasticsearch.common.settings.IndexScopedSettings;
22+
import org.elasticsearch.common.settings.Setting;
2323
import org.elasticsearch.common.settings.Settings;
2424
import org.elasticsearch.common.xcontent.XContentHelper;
2525
import org.elasticsearch.core.Nullable;
2626
import org.elasticsearch.index.IndexNotFoundException;
27+
import org.elasticsearch.index.IndexSettings;
2728
import org.elasticsearch.injection.guice.Inject;
2829
import org.elasticsearch.tasks.Task;
2930
import org.elasticsearch.tasks.TaskId;
@@ -35,6 +36,7 @@
3536
import java.util.HashMap;
3637
import java.util.Map;
3738
import java.util.Optional;
39+
import java.util.Set;
3840

3941
public class CreateIndexFromSourceTransportAction extends HandledTransportAction<
4042
CreateIndexFromSourceAction.Request,
@@ -122,7 +124,39 @@ private static Map<String, Object> mergeMappings(@Nullable MappingMetadata sourc
122124
// https://github.com/elastic/kibana/blob/8a8363f02cc990732eb9cbb60cd388643a336bed/x-pack
123125
// /plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts#L155
124126
private Settings filterSettings(IndexMetadata sourceIndex) {
125-
return MetadataCreateIndexService.copySettingsFromSource(false, sourceIndex.getSettings(), indexScopedSettings, Settings.builder())
126-
.build();
127+
Settings sourceSettings = sourceIndex.getSettings();
128+
final Settings.Builder builder = Settings.builder();
129+
for (final String key : sourceSettings.keySet()) {
130+
final Setting<?> setting = indexScopedSettings.get(key);
131+
if (setting == null) {
132+
assert indexScopedSettings.isPrivateSetting(key) : key;
133+
continue;
134+
}
135+
if (setting.isPrivateIndex()) {
136+
continue;
137+
}
138+
if (setting.getProperties().contains(Setting.Property.NotCopyableOnResize)) {
139+
continue;
140+
}
141+
if (setting.getProperties().contains(Setting.Property.IndexSettingDeprecatedInV7AndRemovedInV8)) {
142+
continue;
143+
}
144+
if (SPECIFIC_SETTINGS_TO_REMOVE.contains(key)) {
145+
continue;
146+
}
147+
builder.copy(key, sourceSettings);
148+
}
149+
return builder.build();
127150
}
151+
152+
private static final Set<String> SPECIFIC_SETTINGS_TO_REMOVE = Set.of(
153+
/**
154+
* These 3 settings were removed from indices created by UA in https://github.com/elastic/kibana/pull/93293
155+
* That change only removed `index.translog.retention.size` and `index.translog.retention.age` if
156+
* soft deletes were enabled. Since soft deletes are always enabled in v8, we can remove all three settings.
157+
*/
158+
IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(),
159+
IndexSettings.INDEX_TRANSLOG_RETENTION_SIZE_SETTING.getKey(),
160+
IndexSettings.INDEX_TRANSLOG_RETENTION_AGE_SETTING.getKey()
161+
);
128162
}

0 commit comments

Comments
 (0)