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

Always enforce a default tier preference (ENFORCE_DEFAULT_TIER_PREFERENCE must always be true) #79723

Closed
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ public MetadataCreateIndexService(
this.shardLimitValidator = shardLimitValidator;

enforceDefaultTierPreference = DataTier.ENFORCE_DEFAULT_TIER_PREFERENCE_SETTING.get(settings);
assert enforceDefaultTierPreference;

clusterService.getClusterSettings().addSettingsUpdateConsumer(DataTier.ENFORCE_DEFAULT_TIER_PREFERENCE_SETTING,
this::setEnforceDefaultTierPreference);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.index.IndexModule;
import org.elasticsearch.index.shard.IndexSettingProvider;
import org.elasticsearch.snapshots.SearchableSnapshotsSettings;
Expand Down Expand Up @@ -50,7 +51,17 @@ public class DataTier {
// it will be removed as a breaking change in some future version, likely 9.0.
public static final String ENFORCE_DEFAULT_TIER_PREFERENCE = "cluster.routing.allocation.enforce_default_tier_preference";
public static final Setting<Boolean> ENFORCE_DEFAULT_TIER_PREFERENCE_SETTING =
Setting.boolSetting(ENFORCE_DEFAULT_TIER_PREFERENCE, true, Property.Dynamic, Property.NodeScope);
Setting.boolSetting(ENFORCE_DEFAULT_TIER_PREFERENCE, true,
new Setting.Validator<>() {
@Override
public void validate(Boolean value) {
if (value != Boolean.TRUE) {
throw new SettingsException("setting [{}={}}] is not allowed, only true is valid",
ENFORCE_DEFAULT_TIER_PREFERENCE_SETTING.getKey(), value);
}
}
},
Property.Dynamic, Property.NodeScope);

public static final String TIER_PREFERENCE = "index.routing.allocation.include._tier_preference";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
Expand Down Expand Up @@ -66,7 +65,6 @@
public class DiskThresholdDecider extends AllocationDecider {

private static final Logger logger = LogManager.getLogger(DiskThresholdDecider.class);
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(DiskThresholdDecider.class);

public static final String NAME = "disk_threshold";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.elasticsearch.action.admin.indices.segments.IndexShardSegments;
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentResponse;
import org.elasticsearch.action.admin.indices.segments.ShardSegments;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequestBuilder;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequestBuilder;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
Expand Down Expand Up @@ -68,7 +69,6 @@
import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.cluster.routing.UnassignedInfo;
import org.elasticsearch.cluster.routing.allocation.DataTier;
import org.elasticsearch.cluster.routing.allocation.DiskThresholdSettings;
import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
import org.elasticsearch.cluster.service.ClusterService;
Expand Down Expand Up @@ -781,6 +781,15 @@ public CreateIndexRequestBuilder prepareCreate(String index, int numNodes, Setti
return client().admin().indices().prepareCreate(index).setSettings(builder.build());
}

/**
* updates the settings for an index
*/
public void updateIndexSettings(String index, Settings.Builder settingsBuilder) {
UpdateSettingsRequestBuilder settingsRequest = client().admin().indices().prepareUpdateSettings(index);
settingsRequest.setSettings(settingsBuilder);
assertAcked(settingsRequest.execute().actionGet());
}

private Settings.Builder getExcludeSettings(int num, Settings.Builder builder) {
String exclude = String.join(",", internalCluster().allDataNodesButN(num));
builder.put("index.routing.allocation.exclude._name", exclude);
Expand Down Expand Up @@ -1756,8 +1765,6 @@ protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) {
.put(IndicesStore.INDICES_STORE_DELETE_SHARD_TIMEOUT.getKey(), new TimeValue(1, TimeUnit.SECONDS))
// randomly enable low-level search cancellation to make sure it does not alter results
.put(SearchService.LOW_LEVEL_CANCELLATION_SETTING.getKey(), randomBoolean())
// randomly enable enforcing a default tier_preference to make sure it does not alter results
.put(DataTier.ENFORCE_DEFAULT_TIER_PREFERENCE_SETTING.getKey(), randomBoolean())
.putList(DISCOVERY_SEED_HOSTS_SETTING.getKey()) // empty list disables a port scan for other nodes
.putList(DISCOVERY_SEED_PROVIDERS_SETTING.getKey(), "file")
.put(TransportSearchAction.DEFAULT_PRE_FILTER_SHARD_SIZE.getKey(), randomFrom(1, 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

package org.elasticsearch.xpack.autoscaling.storage;

import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
Expand Down Expand Up @@ -152,10 +151,6 @@ public void testScaleFromEmptyLegacy() {
)
);

// if we inject a default tier preference, then this test wouldn't be valid anymore,
// so let's turn that off
enforceDefaultTierPreference(false);

Comment on lines -155 to -158
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this invalidates the purpose of the test. And on 8.0 we may still see indices with no tier preference (since they could have been created in 7.x). So ideally we would allow the test to create data with no tier preference somehow.

I would be Ok to defer that test to a follow-up though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

72dee11 should handle these -- I've gone back to the original intent of the tests by manually setting the tier preference back to null.

putAutoscalingPolicy("hot", DataTier.DATA_HOT);
putAutoscalingPolicy("warm", DataTier.DATA_WARM);
putAutoscalingPolicy("cold", DataTier.DATA_COLD);
Expand Down Expand Up @@ -185,6 +180,10 @@ public void testScaleFromEmptyLegacy() {
.build()
)
);

// the tier preference will have defaulted to data_content, set it back to null
updateIndexSettings(indexName, Settings.builder().putNull(DataTier.TIER_PREFERENCE));

refresh(indexName);
assertThat(capacity().results().get("warm").requiredCapacity().total().storage().getBytes(), Matchers.equalTo(0L));
assertThat(capacity().results().get("cold").requiredCapacity().total().storage().getBytes(), Matchers.equalTo(0L));
Expand Down Expand Up @@ -249,10 +248,4 @@ private void putAutoscalingPolicy(String policyName, String role) {
);
assertAcked(client().execute(PutAutoscalingPolicyAction.INSTANCE, request).actionGet());
}

public void enforceDefaultTierPreference(boolean enforceDefaultTierPreference) {
ClusterUpdateSettingsRequest request = new ClusterUpdateSettingsRequest();
request.transientSettings(Settings.builder().put(DataTier.ENFORCE_DEFAULT_TIER_PREFERENCE, enforceDefaultTierPreference).build());
assertAcked(client().admin().cluster().updateSettings(request).actionGet());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@

package org.elasticsearch.xpack.cluster.routing.allocation;

import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.admin.indices.template.put.PutComposableIndexTemplateAction;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Template;
import org.elasticsearch.cluster.routing.allocation.DataTier;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.cluster.routing.allocation.DataTier;
import org.elasticsearch.xpack.core.DataTiersFeatureSetUsage;
import org.elasticsearch.xpack.core.action.XPackUsageRequestBuilder;
import org.elasticsearch.xpack.core.action.XPackUsageResponse;
Expand All @@ -28,7 +27,6 @@
import java.util.Collections;
import java.util.Map;

import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;

Expand Down Expand Up @@ -86,51 +84,9 @@ public void testOverrideDefaultAllocation() {
ensureYellow(index);
}

public void testRequestSettingOverridesAllocation() {
startWarmOnlyNode();
startColdOnlyNode();
ensureGreen();
enforceDefaultTierPreference(false);

client().admin().indices().prepareCreate(index)
.setWaitForActiveShards(0)
.setSettings(Settings.builder()
.putNull(DataTier.TIER_PREFERENCE))
.get();

Settings idxSettings = client().admin().indices().prepareGetIndex().addIndices(index).get().getSettings().get(index);
assertThat(DataTier.TIER_PREFERENCE_SETTING.get(idxSettings), equalTo(""));
// Even the key shouldn't exist if it has been nulled out
assertFalse(idxSettings.keySet().toString(), idxSettings.keySet().contains(DataTier.TIER_PREFERENCE));

// index should be yellow
logger.info("--> waiting for {} to be yellow", index);
ensureYellow(index);

client().admin().indices().prepareDelete(index).get();

// Now test it overriding the "require" setting, in which case the preference should be skipped
client().admin().indices().prepareCreate(index)
.setWaitForActiveShards(0)
.setSettings(Settings.builder()
.put(IndexMetadata.INDEX_ROUTING_REQUIRE_GROUP_PREFIX + ".box", "cold"))
.get();

idxSettings = client().admin().indices().prepareGetIndex().addIndices(index).get().getSettings().get(index);
assertThat(DataTier.TIER_PREFERENCE_SETTING.get(idxSettings), equalTo(""));
// The key should not be put in place since it was overridden
assertFalse(idxSettings.keySet().contains(DataTier.TIER_PREFERENCE));
assertThat(idxSettings.get(IndexMetadata.INDEX_ROUTING_REQUIRE_GROUP_PREFIX + ".box"), equalTo("cold"));

// index should be yellow
logger.info("--> waiting for {} to be yellow", index);
ensureYellow(index);
}

public void testRequestSettingOverriddenIfEnforced() {
public void testRequestSettingOverridden() {
startContentOnlyNode();
ensureGreen();
enforceDefaultTierPreference(true);

client().admin().indices().prepareCreate(index)
.setWaitForActiveShards(0)
Expand Down Expand Up @@ -184,48 +140,8 @@ public void testShrinkStaysOnTier() {
.get();
}

public void testTemplateOverridesDefaults() {
startWarmOnlyNode();
enforceDefaultTierPreference(false);

Template t = new Template(Settings.builder()
.put(IndexMetadata.INDEX_ROUTING_REQUIRE_GROUP_PREFIX + ".box", "warm")
.build(), null, null);
ComposableIndexTemplate ct = new ComposableIndexTemplate.Builder()
.indexPatterns(Collections.singletonList(index))
.template(t).build();
client().execute(PutComposableIndexTemplateAction.INSTANCE,
new PutComposableIndexTemplateAction.Request("template").indexTemplate(ct)).actionGet();

client().admin().indices().prepareCreate(index).setWaitForActiveShards(0).get();

Settings idxSettings = client().admin().indices().prepareGetIndex().addIndices(index).get().getSettings().get(index);
assertThat(idxSettings.keySet().contains(DataTier.TIER_PREFERENCE), equalTo(false));

// index should be yellow
ensureYellow(index);

client().admin().indices().prepareDelete(index).get();

t = new Template(Settings.builder()
.putNull(DataTier.TIER_PREFERENCE)
.build(), null, null);
ct = new ComposableIndexTemplate.Builder().indexPatterns(Collections.singletonList(index))
.template(t).build();
client().execute(PutComposableIndexTemplateAction.INSTANCE,
new PutComposableIndexTemplateAction.Request("template").indexTemplate(ct)).actionGet();

client().admin().indices().prepareCreate(index).setWaitForActiveShards(0).get();

idxSettings = client().admin().indices().prepareGetIndex().addIndices(index).get().getSettings().get(index);
assertThat(idxSettings.keySet().contains(DataTier.TIER_PREFERENCE), equalTo(false));

ensureYellow(index);
}

public void testTemplateOverriddenIfEnforced() {
public void testTemplateOverridden() {
startContentOnlyNode();
enforceDefaultTierPreference(true);

Template t = new Template(Settings.builder()
.putNull(DataTier.TIER_PREFERENCE)
Expand Down Expand Up @@ -376,10 +292,4 @@ public void startFrozenOnlyNode() {
.build();
internalCluster().startNode(nodeSettings);
}

public void enforceDefaultTierPreference(boolean enforceDefaultTierPreference) {
ClusterUpdateSettingsRequest request = new ClusterUpdateSettingsRequest();
request.transientSettings(Settings.builder().put(DataTier.ENFORCE_DEFAULT_TIER_PREFERENCE, enforceDefaultTierPreference).build());
assertAcked(client().admin().cluster().updateSettings(request).actionGet());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ private DeprecationChecks() {
NodeDeprecationChecks::checkScriptContextCache,
NodeDeprecationChecks::checkScriptContextCompilationsRateLimitSetting,
NodeDeprecationChecks::checkScriptContextCacheSizeSetting,
NodeDeprecationChecks::checkScriptContextCacheExpirationSetting
NodeDeprecationChecks::checkScriptContextCacheExpirationSetting,
NodeDeprecationChecks::checkEnforceDefaultTierPreferenceSetting
);

static List<Function<IndexMetadata, DeprecationIssue>> INDEX_SETTINGS_CHECKS = List.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package org.elasticsearch.xpack.deprecation;

import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules;
import org.elasticsearch.cluster.routing.allocation.DataTier;
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
import org.elasticsearch.common.settings.SecureSetting;
import org.elasticsearch.common.settings.Setting;
Expand Down Expand Up @@ -441,4 +442,18 @@ static DeprecationIssue checkScriptContextCacheExpirationSetting(final Settings
}
return null;
}

static DeprecationIssue checkEnforceDefaultTierPreferenceSetting(final Settings settings, final PluginsAndModules pluginsAndModules) {
if (DataTier.ENFORCE_DEFAULT_TIER_PREFERENCE_SETTING.exists(settings)) {
String key = DataTier.ENFORCE_DEFAULT_TIER_PREFERENCE_SETTING.getKey();
return new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
String.format(Locale.ROOT, "setting [%s] is deprecated and will not be available in a future version", key),
"https://www.elastic.co/guide/en/elasticsearch/reference/current/data-tiers.html",
String.format(Locale.ROOT, "found [%s] configured. Discontinue use of this setting.", key),
false, null);
}

return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package org.elasticsearch.xpack.deprecation;

import org.elasticsearch.cluster.routing.allocation.DataTier;
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.MockSecureSettings;
Expand Down Expand Up @@ -459,4 +460,23 @@ public void testScriptContextCacheExpirationSetting() {
"[script.context.moving-function.cache_expire] setting was deprecated in Elasticsearch and will be removed in a future" +
" release! See the breaking changes documentation for the next major version.");
}

public void testEnforceDefaultTierPreferenceSetting() {
Settings settings = Settings.builder()
.put(DataTier.ENFORCE_DEFAULT_TIER_PREFERENCE_SETTING.getKey(), true)
.build();

List<DeprecationIssue> issues = DeprecationChecks.filterChecks(NODE_SETTINGS_CHECKS, c -> c.apply(settings, null));

final String expectedUrl = "https://www.elastic.co/guide/en/elasticsearch/reference/current/data-tiers.html";
assertThat(issues, hasItem(
new DeprecationIssue(DeprecationIssue.Level.CRITICAL,
"setting [cluster.routing.allocation.enforce_default_tier_preference] is deprecated and" +
" will not be available in a future version",
expectedUrl,
"found [cluster.routing.allocation.enforce_default_tier_preference] configured." +
" Discontinue use of this setting.",
false, null)));
}

}
Loading