Ver Fonte

Filtering setting deprecation info API messages based on a setting (#78725) (#79184)

This commit adds the ability to configure a list of settings that will be ignored by the deprecation info
API. Any deprecation messages for any of the settings given will be suppressed. This can be used to hide
settings that users do not have the ability to change.
Relates #78725
Keith Massey há 4 anos atrás
pai
commit
87fa61cc3f

+ 13 - 0
docs/reference/migration/apis/deprecation.asciidoc

@@ -39,6 +39,19 @@ expressions are supported.
 When you specify this parameter, only deprecations for the specified
 data streams or indices are returned.
 
+[[migration-api-settings]]
+==== Settings
+
+You can use the following settings to control the behavior of the deprecation info API:
+
+[[skip_deprecated_settings]]
+// tag::skip_deprecated_settings-tag[]
+`deprecation.skip_deprecated_settings`
+(<<dynamic-cluster-setting,Dynamic>>)
+Defaults to an empty list. Set to a list of setting names to be ignored by the deprecation info API. Any
+deprecations related to settings in this list will not be returned by the API. Simple wildcard matching is supported.
+// end::skip_deprecated_settings-tag[]
+
 [[migration-api-example]]
 ==== {api-examples-title}
 

+ 5 - 1
x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/Deprecation.java

@@ -40,6 +40,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.function.Supplier;
 
+import static org.elasticsearch.xpack.deprecation.DeprecationChecks.SKIP_DEPRECATIONS_SETTING;
 
 /**
  * The plugin class for the Deprecation API
@@ -116,6 +117,9 @@ public class Deprecation extends Plugin implements ActionPlugin {
 
     @Override
     public List<Setting<?>> getSettings() {
-        return List.of(USE_X_OPAQUE_ID_IN_FILTERING, WRITE_DEPRECATION_LOGS_TO_INDEX);
+        return List.of(
+            USE_X_OPAQUE_ID_IN_FILTERING,
+            WRITE_DEPRECATION_LOGS_TO_INDEX,
+            SKIP_DEPRECATIONS_SETTING);
     }
 }

+ 10 - 0
x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationChecks.java

@@ -9,6 +9,7 @@ package org.elasticsearch.xpack.deprecation;
 import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
+import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
 
@@ -25,6 +26,15 @@ import java.util.stream.Collectors;
  */
 public class DeprecationChecks {
 
+    public static final Setting<List<String>> SKIP_DEPRECATIONS_SETTING =
+        Setting.listSetting(
+            "deprecation.skip_deprecated_settings",
+            Collections.emptyList(),
+            Function.identity(),
+            Setting.Property.NodeScope,
+            Setting.Property.Dynamic
+        );
+
     private DeprecationChecks() {
     }
 

+ 40 - 5
x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/DeprecationInfoAction.java

@@ -18,8 +18,12 @@ import org.elasticsearch.action.support.master.MasterNodeReadRequest;
 import org.elasticsearch.cluster.ClusterState;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.common.collect.ImmutableOpenMap;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.regex.Regex;
+import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.set.Sets;
 import org.elasticsearch.xcontent.ToXContentObject;
 import org.elasticsearch.xcontent.XContentBuilder;
@@ -194,16 +198,18 @@ public class DeprecationInfoAction extends ActionType<DeprecationInfoAction.Resp
                                                           NodesDeprecationCheckResponse nodeDeprecationResponse,
                                                           List<Function<IndexMetadata, DeprecationIssue>> indexSettingsChecks,
                                                           List<Function<ClusterState, DeprecationIssue>> clusterSettingsChecks,
-                                                          Map<String, List<DeprecationIssue>> pluginSettingIssues) {
+                                                          Map<String, List<DeprecationIssue>> pluginSettingIssues,
+                                                          List<String> skipTheseDeprecatedSettings) {
+            // Allow system index access here to prevent deprecation warnings when we call this API
+            String[] concreteIndexNames = indexNameExpressionResolver.concreteIndexNames(state, request);
+            ClusterState stateWithSkippedSettingsRemoved = removeSkippedSettings(state, concreteIndexNames, skipTheseDeprecatedSettings);
             List<DeprecationIssue> clusterSettingsIssues = filterChecks(clusterSettingsChecks,
-                (c) -> c.apply(state));
+                (c) -> c.apply(stateWithSkippedSettingsRemoved));
             List<DeprecationIssue> nodeSettingsIssues = mergeNodeIssues(nodeDeprecationResponse);
 
-            String[] concreteIndexNames = indexNameExpressionResolver.concreteIndexNames(state, request);
-
             Map<String, List<DeprecationIssue>> indexSettingsIssues = new HashMap<>();
             for (String concreteIndex : concreteIndexNames) {
-                IndexMetadata indexMetadata = state.getMetadata().index(concreteIndex);
+                IndexMetadata indexMetadata = stateWithSkippedSettingsRemoved.getMetadata().index(concreteIndex);
                 List<DeprecationIssue> singleIndexIssues = filterChecks(indexSettingsChecks,
                     c -> c.apply(indexMetadata));
                 if (singleIndexIssues.size() > 0) {
@@ -223,6 +229,35 @@ public class DeprecationInfoAction extends ActionType<DeprecationInfoAction.Resp
         }
     }
 
+    /**
+     *
+     * @param state The cluster state to modify
+     * @param indexNames The names of the indexes whose settings need to be filtered
+     * @param skipTheseDeprecatedSettings The settings that will be removed from cluster metadata and the index metadata of all the
+     *                                    indexes specified by indexNames
+     * @return A modified cluster state with the given settings removed
+     */
+    private static ClusterState removeSkippedSettings(ClusterState state, String[] indexNames, List<String> skipTheseDeprecatedSettings) {
+        ClusterState.Builder clusterStateBuilder = new ClusterState.Builder(state);
+        Metadata.Builder metadataBuilder = new Metadata.Builder(state.metadata());
+        metadataBuilder.transientSettings(
+            metadataBuilder.transientSettings().filter(setting -> Regex.simpleMatch(skipTheseDeprecatedSettings, setting) == false));
+        metadataBuilder.persistentSettings(
+            metadataBuilder.persistentSettings().filter(setting -> Regex.simpleMatch(skipTheseDeprecatedSettings, setting) == false));
+        ImmutableOpenMap.Builder<String, IndexMetadata> indicesBuilder = ImmutableOpenMap.builder(state.getMetadata().indices());
+        for (String indexName : indexNames) {
+            IndexMetadata indexMetadata = state.getMetadata().index(indexName);
+            IndexMetadata.Builder filteredIndexMetadataBuilder = new IndexMetadata.Builder(indexMetadata);
+            Settings filteredSettings =
+                indexMetadata.getSettings().filter(setting -> Regex.simpleMatch(skipTheseDeprecatedSettings, setting) == false);
+            filteredIndexMetadataBuilder.settings(filteredSettings);
+            indicesBuilder.put(indexName, filteredIndexMetadataBuilder.build());
+        }
+        metadataBuilder.indices(indicesBuilder.build());
+        clusterStateBuilder.metadata(metadataBuilder);
+        return clusterStateBuilder.build();
+    }
+
     public static class Request extends MasterNodeReadRequest<Request> implements IndicesRequest.Replaceable {
 
         private static final IndicesOptions INDICES_OPTIONS = IndicesOptions.fromOptions(false, true, true, true);

+ 23 - 4
x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/TransportDeprecationInfoAction.java

@@ -46,6 +46,7 @@ public class TransportDeprecationInfoAction extends TransportMasterNodeReadActio
     private final IndexNameExpressionResolver indexNameExpressionResolver;
     private final Settings settings;
     private final NamedXContentRegistry xContentRegistry;
+    private volatile List<String> skipTheseDeprecations;
 
     @Inject
     public TransportDeprecationInfoAction(Settings settings, TransportService transportService, ClusterService clusterService,
@@ -58,6 +59,14 @@ public class TransportDeprecationInfoAction extends TransportMasterNodeReadActio
         this.indexNameExpressionResolver = indexNameExpressionResolver;
         this.settings = settings;
         this.xContentRegistry = xContentRegistry;
+        skipTheseDeprecations = DeprecationChecks.SKIP_DEPRECATIONS_SETTING.get(settings);
+        // Safe to register this here because it happens synchronously before the cluster service is started:
+        clusterService.getClusterSettings().addSettingsUpdateConsumer(DeprecationChecks.SKIP_DEPRECATIONS_SETTING,
+            this::setSkipDeprecations);
+    }
+
+    private <T> void setSkipDeprecations(List<String> skipDeprecations) {
+        this.skipTheseDeprecations = Collections.unmodifiableList(skipDeprecations);
     }
 
     @Override
@@ -89,10 +98,20 @@ public class TransportDeprecationInfoAction extends TransportMasterNodeReadActio
                 new OriginSettingClient(client, ClientHelper.DEPRECATION_ORIGIN)
             );
             pluginSettingIssues(PLUGIN_CHECKERS, components, ActionListener.wrap(
-                deprecationIssues -> listener.onResponse(
-                    DeprecationInfoAction.Response.from(state, indexNameExpressionResolver,
-                        request, response, INDEX_SETTINGS_CHECKS, CLUSTER_SETTINGS_CHECKS,
-                        deprecationIssues)),
+                deprecationIssues -> {
+                    listener.onResponse(
+                        DeprecationInfoAction.Response.from(
+                            state,
+                            indexNameExpressionResolver,
+                            request,
+                            response,
+                            INDEX_SETTINGS_CHECKS,
+                            CLUSTER_SETTINGS_CHECKS,
+                            deprecationIssues,
+                            skipTheseDeprecations
+                        )
+                    );
+                },
                 listener::onFailure
             ));
 

+ 22 - 3
x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/TransportNodeDeprecationCheckAction.java

@@ -8,12 +8,14 @@
 package org.elasticsearch.xpack.deprecation;
 
 import org.elasticsearch.action.FailedNodeException;
+import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules;
 import org.elasticsearch.action.support.ActionFilters;
 import org.elasticsearch.action.support.nodes.TransportNodesAction;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.regex.Regex;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.plugins.PluginsService;
 import org.elasticsearch.tasks.Task;
@@ -22,7 +24,9 @@ import org.elasticsearch.transport.TransportService;
 import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
 
 import java.io.IOException;
+import java.util.Collections;
 import java.util.List;
+import java.util.function.BiFunction;
 
 public class TransportNodeDeprecationCheckAction extends TransportNodesAction<NodesDeprecationCheckRequest,
     NodesDeprecationCheckResponse,
@@ -31,6 +35,7 @@ public class TransportNodeDeprecationCheckAction extends TransportNodesAction<No
 
     private final Settings settings;
     private final PluginsService pluginsService;
+    private volatile List<String> skipTheseDeprecations;
 
     @Inject
     public TransportNodeDeprecationCheckAction(Settings settings, ThreadPool threadPool,
@@ -43,6 +48,14 @@ public class TransportNodeDeprecationCheckAction extends TransportNodesAction<No
             NodesDeprecationCheckAction.NodeResponse.class);
         this.settings = settings;
         this.pluginsService = pluginsService;
+        skipTheseDeprecations = DeprecationChecks.SKIP_DEPRECATIONS_SETTING.get(settings);
+        // Safe to register this here because it happens synchronously before the cluster service is started:
+        clusterService.getClusterSettings().addSettingsUpdateConsumer(DeprecationChecks.SKIP_DEPRECATIONS_SETTING,
+            this::setSkipDeprecations);
+    }
+
+    private <T> void setSkipDeprecations(List<String> skipDeprecations) {
+        this.skipTheseDeprecations = Collections.unmodifiableList(skipDeprecations);
     }
 
     @Override
@@ -64,11 +77,17 @@ public class TransportNodeDeprecationCheckAction extends TransportNodesAction<No
 
     @Override
     protected NodesDeprecationCheckAction.NodeResponse nodeOperation(NodesDeprecationCheckAction.NodeRequest request, Task task) {
-        List<DeprecationIssue> issues = DeprecationInfoAction.filterChecks(DeprecationChecks.NODE_SETTINGS_CHECKS,
-            (c) -> c.apply(settings, pluginsService.info()));
+        return nodeOperation(request, DeprecationChecks.NODE_SETTINGS_CHECKS);
+    }
+
+    NodesDeprecationCheckAction.NodeResponse nodeOperation(NodesDeprecationCheckAction.NodeRequest request,
+                                                           List<BiFunction<Settings, PluginsAndModules,
+                                                               DeprecationIssue>> nodeSettingsChecks) {
+        Settings filteredSettings = settings.filter(setting -> Regex.simpleMatch(skipTheseDeprecations, setting) == false);
+        List<DeprecationIssue> issues = DeprecationInfoAction.filterChecks(nodeSettingsChecks,
+            (c) -> c.apply(filteredSettings, pluginsService.info()));
 
         return new NodesDeprecationCheckAction.NodeResponse(transportService.getLocalNode(), issues);
     }
 
-
 }

+ 70 - 1
x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/DeprecationInfoActionResponseTests.java

@@ -25,14 +25,17 @@ import org.elasticsearch.indices.TestIndexNameExpressionResolver;
 import org.elasticsearch.test.AbstractWireSerializingTestCase;
 import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
 import org.elasticsearch.xpack.core.deprecation.DeprecationIssue.Level;
+import org.junit.Assert;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -108,7 +111,8 @@ public class DeprecationInfoActionResponseTests extends AbstractWireSerializingT
             nodeDeprecationIssues,
             indexSettingsChecks,
             clusterSettingsChecks,
-            Collections.emptyMap());
+            Collections.emptyMap(),
+            Collections.emptyList());
 
         if (clusterIssueFound) {
             assertThat(response.getClusterSettingsIssues(), equalTo(Collections.singletonList(foundIssue)));
@@ -134,6 +138,71 @@ public class DeprecationInfoActionResponseTests extends AbstractWireSerializingT
         }
     }
 
+    public void testRemoveSkippedSettings() throws IOException {
+
+        Settings.Builder settingsBuilder = settings(Version.CURRENT);
+        settingsBuilder.put("some.deprecated.property", "someValue1");
+        settingsBuilder.put("some.other.bad.deprecated.property", "someValue2");
+        settingsBuilder.put("some.undeprecated.property", "someValue3");
+        settingsBuilder.putList("some.undeprecated.list.property", List.of("someValue4", "someValue5"));
+        Settings inputSettings = settingsBuilder.build();
+        Metadata metadata = Metadata.builder().put(IndexMetadata.builder("test")
+            .settings(inputSettings)
+            .numberOfShards(1)
+            .numberOfReplicas(0))
+            .persistentSettings(inputSettings)
+            .build();
+
+        ClusterState state = ClusterState.builder(ClusterName.DEFAULT).metadata(metadata).build();
+        IndexNameExpressionResolver resolver = TestIndexNameExpressionResolver.newInstance();
+        AtomicReference<Settings> visibleClusterSettings = new AtomicReference<>();
+        List<Function<ClusterState, DeprecationIssue>> clusterSettingsChecks =
+            Collections.unmodifiableList(Arrays.asList(
+                (s) -> {
+                    visibleClusterSettings.set(s.getMetadata().settings());
+                    return null;
+                }
+            ));
+        AtomicReference<Settings> visibleIndexSettings = new AtomicReference<>();
+        List<Function<IndexMetadata, DeprecationIssue>> indexSettingsChecks =
+            Collections.unmodifiableList(Arrays.asList(
+                (idx) -> {
+                    visibleIndexSettings.set(idx.getSettings());
+                    return null;
+                }
+            ));
+
+        NodesDeprecationCheckResponse nodeDeprecationIssues = new NodesDeprecationCheckResponse(
+            new ClusterName(randomAlphaOfLength(5)),
+            emptyList(),
+            emptyList());
+
+        DeprecationInfoAction.Request request = new DeprecationInfoAction.Request(Strings.EMPTY_ARRAY);
+        DeprecationInfoAction.Response.from(state,
+            resolver,
+            request,
+            nodeDeprecationIssues,
+            indexSettingsChecks,
+            clusterSettingsChecks,
+            Collections.emptyMap(),
+            List.of("some.deprecated.property", "some.other.*.deprecated.property"));
+
+        settingsBuilder = settings(Version.CURRENT);
+        settingsBuilder.put("some.undeprecated.property", "someValue3");
+        settingsBuilder.putList("some.undeprecated.list.property", List.of("someValue4", "someValue5"));
+        Settings expectedSettings = settingsBuilder.build();
+        Settings resultClusterSettings = visibleClusterSettings.get();
+        Assert.assertNotNull(resultClusterSettings);
+        Assert.assertEquals(expectedSettings, visibleClusterSettings.get());
+        Settings resultIndexSettings = visibleIndexSettings.get();
+        Assert.assertNotNull(resultIndexSettings);
+        Assert.assertTrue(resultIndexSettings.get("some.undeprecated.property").equals("someValue3"));
+        Assert.assertTrue(resultIndexSettings.getAsList("some.undeprecated.list.property")
+            .equals(List.of("someValue4", "someValue5")));
+        Assert.assertFalse(resultIndexSettings.hasValue("some.deprecated.property"));
+        Assert.assertFalse(resultIndexSettings.hasValue("some.other.bad.deprecated.property"));
+    }
+
     public void testCtorFailure() {
         Map<String, List<DeprecationIssue>> indexNames = Stream.generate(() -> randomAlphaOfLength(10))
             .limit(10)

+ 98 - 0
x-pack/plugin/deprecation/src/test/java/org/elasticsearch/xpack/deprecation/TransportNodeDeprecationCheckActionTests.java

@@ -0,0 +1,98 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.deprecation;
+
+import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules;
+import org.elasticsearch.action.support.ActionFilters;
+import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.cluster.metadata.Metadata;
+import org.elasticsearch.cluster.node.DiscoveryNode;
+import org.elasticsearch.cluster.service.ClusterService;
+import org.elasticsearch.common.settings.ClusterSettings;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.license.XPackLicenseState;
+import org.elasticsearch.plugins.PluginsService;
+import org.elasticsearch.test.ESTestCase;
+import org.elasticsearch.threadpool.ThreadPool;
+import org.elasticsearch.transport.TransportService;
+import org.elasticsearch.xpack.core.deprecation.DeprecationIssue;
+import org.junit.Assert;
+import org.mockito.Mockito;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiFunction;
+
+public class TransportNodeDeprecationCheckActionTests extends ESTestCase {
+
+    public void testNodeOperation() {
+        Settings.Builder settingsBuilder = Settings.builder();
+        settingsBuilder.put("some.deprecated.property", "someValue1");
+        settingsBuilder.put("some.other.bad.deprecated.property", "someValue2");
+        settingsBuilder.put("some.undeprecated.property", "someValue3");
+        settingsBuilder.putList("some.undeprecated.list.property", List.of("someValue4", "someValue5"));
+        settingsBuilder.putList(DeprecationChecks.SKIP_DEPRECATIONS_SETTING.getKey(),
+            List.of("some.deprecated.property", "some.other.*.deprecated.property"));
+        Settings inputSettings = settingsBuilder.build();
+        ThreadPool threadPool = null;
+        final XPackLicenseState licenseState = null;
+        Metadata metadata = Mockito.mock(Metadata.class);
+        ClusterState clusterState = Mockito.mock(ClusterState.class);
+        Mockito.when(clusterState.metadata()).thenReturn(metadata);
+        ClusterService clusterService = Mockito.mock(ClusterService.class);
+        Mockito.when(clusterService.state()).thenReturn(clusterState);
+        ClusterSettings clusterSettings = new ClusterSettings(inputSettings, Set.of(DeprecationChecks.SKIP_DEPRECATIONS_SETTING));
+        Mockito.when((clusterService.getClusterSettings())).thenReturn(clusterSettings);
+        DiscoveryNode node = Mockito.mock(DiscoveryNode.class);
+        TransportService transportService = Mockito.mock(TransportService.class);
+        Mockito.when(transportService.getLocalNode()).thenReturn(node);
+        PluginsService pluginsService = Mockito.mock(PluginsService.class);
+        ActionFilters actionFilters = Mockito.mock(ActionFilters.class);
+        TransportNodeDeprecationCheckAction transportNodeDeprecationCheckAction = new TransportNodeDeprecationCheckAction(
+            inputSettings,
+            threadPool,
+            clusterService,
+            transportService,
+            pluginsService,
+            actionFilters
+        );
+        NodesDeprecationCheckAction.NodeRequest nodeRequest = null;
+        AtomicReference<Settings> visibleSettings = new AtomicReference<>();
+        BiFunction<Settings, PluginsAndModules, DeprecationIssue> nodeSettingCheck = (settings, p) -> {
+            visibleSettings.set(settings);
+            return null;
+        };
+        java.util.List<BiFunction<Settings, PluginsAndModules, DeprecationIssue>> nodeSettingsChecks = List.of(nodeSettingCheck);
+        transportNodeDeprecationCheckAction.nodeOperation(nodeRequest, nodeSettingsChecks);
+        settingsBuilder = Settings.builder();
+        settingsBuilder.put("some.undeprecated.property", "someValue3");
+        settingsBuilder.putList("some.undeprecated.list.property", List.of("someValue4", "someValue5"));
+        settingsBuilder.putList(DeprecationChecks.SKIP_DEPRECATIONS_SETTING.getKey(),
+            List.of("some.deprecated.property", "some.other.*.deprecated.property"));
+        Settings expectedSettings = settingsBuilder.build();
+        Assert.assertNotNull(visibleSettings.get());
+        Assert.assertEquals(expectedSettings, visibleSettings.get());
+
+        // Testing that the setting is dynamically updatable:
+        Settings newSettings = Settings.builder().putList(DeprecationChecks.SKIP_DEPRECATIONS_SETTING.getKey(),
+            List.of("some.undeprecated.property")).build();
+        clusterSettings.applySettings(newSettings);
+        transportNodeDeprecationCheckAction.nodeOperation(nodeRequest, nodeSettingsChecks);
+        settingsBuilder = Settings.builder();
+        settingsBuilder.put("some.deprecated.property", "someValue1");
+        settingsBuilder.put("some.other.bad.deprecated.property", "someValue2");
+        settingsBuilder.putList("some.undeprecated.list.property", List.of("someValue4", "someValue5"));
+        // This is the node setting (since this is the node deprecation check), not the cluster setting:
+        settingsBuilder.putList(DeprecationChecks.SKIP_DEPRECATIONS_SETTING.getKey(),
+            List.of("some.deprecated.property", "some.other.*.deprecated.property"));
+        expectedSettings = settingsBuilder.build();
+        Assert.assertNotNull(visibleSettings.get());
+        Assert.assertEquals(expectedSettings, visibleSettings.get());
+    }
+}