From ccbd7a726020cecb9b2c744793088f5449d18862 Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Fri, 16 Oct 2020 10:25:46 -0600 Subject: [PATCH] Make stack.templates.enabled a dynamic setting (#63764) * Make stack.templates.enabled a dynamic setting This change allows the setting for disabling the automatically installed stack templates (the `logs-*-*`, `metrics-*-*`, and `synthetics-*-*` templates) to be changed dynamically. As a byproduct, it also moves thes `IndexTemplateRegistry` to use an `initialize()` method so that constructors are not tempted to use a `this` reference in the constructor (see #37861 for more information about why to avoid that). Resolves #62835 --- .../core/template/IndexTemplateRegistry.java | 6 +++ .../xpack/ilm/IndexLifecycle.java | 6 +-- .../xpack/ml/MachineLearning.java | 3 +- .../xpack/stack/StackPlugin.java | 13 ++----- .../xpack/stack/StackTemplateRegistry.java | 37 ++++++++++++++++++- .../stack/StackTemplateRegistryTests.java | 2 +- .../elasticsearch/xpack/watcher/Watcher.java | 4 +- .../rest-api-spec/test/stack/10_stack.yml | 19 ++++++++++ 8 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 x-pack/qa/core-rest-tests-with-security/src/test/resources/rest-api-spec/test/stack/10_stack.yml diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistry.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistry.java index 2200ffc8ca05b..31c35f1af5120 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistry.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistry.java @@ -72,6 +72,12 @@ public IndexTemplateRegistry(Settings nodeSettings, ClusterService clusterServic this.threadPool = threadPool; this.xContentRegistry = xContentRegistry; this.clusterService = clusterService; + } + + /** + * Initialize the template registry, adding it as a listener so templates will be installed as necessary + */ + public void initialize() { clusterService.addListener(this); } diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java index 37a5bb8b4f264..6e14db874462d 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java @@ -193,20 +193,18 @@ public Collection createComponents(Client client, ClusterService cluster return Collections.emptyList(); } final List components = new ArrayList<>(); - // This registers a cluster state listener, so appears unused but is not. - @SuppressWarnings("unused") ILMHistoryTemplateRegistry ilmTemplateRegistry = new ILMHistoryTemplateRegistry(settings, clusterService, threadPool, client, xContentRegistry); + ilmTemplateRegistry.initialize(); ilmHistoryStore.set(new ILMHistoryStore(settings, new OriginSettingClient(client, INDEX_LIFECYCLE_ORIGIN), clusterService, threadPool)); indexLifecycleInitialisationService.set(new IndexLifecycleService(settings, client, clusterService, threadPool, getClock(), System::currentTimeMillis, xContentRegistry, ilmHistoryStore.get())); components.add(indexLifecycleInitialisationService.get()); - // the template registry is a cluster state listener - @SuppressWarnings("unused") SnapshotLifecycleTemplateRegistry templateRegistry = new SnapshotLifecycleTemplateRegistry(settings, clusterService, threadPool, client, xContentRegistry); + templateRegistry.initialize(); snapshotHistoryStore.set(new SnapshotHistoryStore(settings, new OriginSettingClient(client, INDEX_LIFECYCLE_ORIGIN), clusterService)); snapshotLifecycleService.set(new SnapshotLifecycleService(settings, diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java index 5f1764d192097..ecb9030431101 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java @@ -570,7 +570,8 @@ public Collection createComponents(Client client, ClusterService cluster this.mlUpgradeModeActionFilter.set(new MlUpgradeModeActionFilter(clusterService)); - new MlIndexTemplateRegistry(settings, clusterService, threadPool, client, xContentRegistry); + MlIndexTemplateRegistry registry = new MlIndexTemplateRegistry(settings, clusterService, threadPool, client, xContentRegistry); + registry.initialize(); AnomalyDetectionAuditor anomalyDetectionAuditor = new AnomalyDetectionAuditor(client, clusterService); DataFrameAnalyticsAuditor dataFrameAnalyticsAuditor = new DataFrameAnalyticsAuditor(client, clusterService); diff --git a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackPlugin.java b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackPlugin.java index 3e491aced83dd..d7de7ccb02d76 100644 --- a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackPlugin.java +++ b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackPlugin.java @@ -21,7 +21,6 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.watcher.ResourceWatcherService; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -30,19 +29,13 @@ public class StackPlugin extends Plugin implements ActionPlugin { private final Settings settings; - public static final Setting STACK_TEMPLATES_ENABLED = Setting.boolSetting( - "stack.templates.enabled", - true, - Setting.Property.NodeScope - ); - public StackPlugin(Settings settings) { this.settings = settings; } @Override public List> getSettings() { - return Collections.singletonList(STACK_TEMPLATES_ENABLED); + return Collections.singletonList(StackTemplateRegistry.STACK_TEMPLATES_ENABLED); } @Override @@ -59,8 +52,8 @@ public Collection createComponents( IndexNameExpressionResolver indexNameExpressionResolver, Supplier repositoriesServiceSupplier ) { - final List components = new ArrayList<>(); StackTemplateRegistry templateRegistry = new StackTemplateRegistry(settings, clusterService, threadPool, client, xContentRegistry); - return components; + templateRegistry.initialize(); + return Collections.singleton(templateRegistry); } } diff --git a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackTemplateRegistry.java b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackTemplateRegistry.java index 424539b9aeda9..f3e0cf4cb32e0 100644 --- a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackTemplateRegistry.java +++ b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackTemplateRegistry.java @@ -6,8 +6,11 @@ package org.elasticsearch.xpack.stack; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.threadpool.ThreadPool; @@ -19,8 +22,11 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; public class StackTemplateRegistry extends IndexTemplateRegistry { + private static final Logger logger = LogManager.getLogger(StackTemplateRegistry.class); + // The stack template registry should remain at version 0. This is because templates and // policies will be changed by the ingest manager once they exist, and ES should only ever put // the template in place if it does not exist. If this were incremented we could accidentally @@ -28,8 +34,15 @@ public class StackTemplateRegistry extends IndexTemplateRegistry { public static final int REGISTRY_VERSION = 0; public static final String TEMPLATE_VERSION_VARIABLE = "xpack.stack.template.version"; + public static final Setting STACK_TEMPLATES_ENABLED = Setting.boolSetting( + "stack.templates.enabled", + true, + Setting.Property.NodeScope, + Setting.Property.Dynamic + ); - private final boolean stackTemplateEnabled; + private final ClusterService clusterService; + private volatile boolean stackTemplateEnabled; ////////////////////////////////////////////////////////// // Logs components (for matching logs-*-* indices) @@ -129,7 +142,27 @@ public StackTemplateRegistry( NamedXContentRegistry xContentRegistry ) { super(nodeSettings, clusterService, threadPool, client, xContentRegistry); - this.stackTemplateEnabled = StackPlugin.STACK_TEMPLATES_ENABLED.get(nodeSettings); + this.clusterService = clusterService; + this.stackTemplateEnabled = STACK_TEMPLATES_ENABLED.get(nodeSettings); + } + + @Override + public void initialize() { + super.initialize(); + clusterService.getClusterSettings().addSettingsUpdateConsumer(STACK_TEMPLATES_ENABLED, this::updateEnabledSetting); + } + + private void updateEnabledSetting(boolean newValue) { + if (newValue) { + this.stackTemplateEnabled = true; + } else { + logger.info( + "stack composable templates [{}] and component templates [{}] will not be installed or reinstalled", + getComposableTemplateConfigs().stream().map(IndexTemplateConfig::getTemplateName).collect(Collectors.joining(",")), + getComponentTemplateConfigs().stream().map(IndexTemplateConfig::getTemplateName).collect(Collectors.joining(",")) + ); + this.stackTemplateEnabled = false; + } } @Override diff --git a/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackTemplateRegistryTests.java b/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackTemplateRegistryTests.java index fcfa904f97464..b77fe71f9a886 100644 --- a/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackTemplateRegistryTests.java +++ b/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackTemplateRegistryTests.java @@ -105,7 +105,7 @@ public void tearDown() throws Exception { } public void testDisabledDoesNotAddTemplates() { - Settings settings = Settings.builder().put(StackPlugin.STACK_TEMPLATES_ENABLED.getKey(), false).build(); + Settings settings = Settings.builder().put(StackTemplateRegistry.STACK_TEMPLATES_ENABLED.getKey(), false).build(); StackTemplateRegistry disabledRegistry = new StackTemplateRegistry(settings, clusterService, threadPool, client, xContentRegistry); assertThat(disabledRegistry.getComponentTemplateConfigs(), hasSize(0)); assertThat(disabledRegistry.getComposableTemplateConfigs(), hasSize(0)); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java index d1f6d179abaae..0fb127a78bcee 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java @@ -276,7 +276,9 @@ public Collection createComponents(Client client, ClusterService cluster throw new UncheckedIOException(e); } - new WatcherIndexTemplateRegistry(environment.settings(), clusterService, threadPool, client, xContentRegistry); + WatcherIndexTemplateRegistry templateRegistry = new WatcherIndexTemplateRegistry(environment.settings(), + clusterService, threadPool, client, xContentRegistry); + templateRegistry.initialize(); final SSLService sslService = getSslService(); // http client diff --git a/x-pack/qa/core-rest-tests-with-security/src/test/resources/rest-api-spec/test/stack/10_stack.yml b/x-pack/qa/core-rest-tests-with-security/src/test/resources/rest-api-spec/test/stack/10_stack.yml new file mode 100644 index 0000000000000..31f8cecdb1ce3 --- /dev/null +++ b/x-pack/qa/core-rest-tests-with-security/src/test/resources/rest-api-spec/test/stack/10_stack.yml @@ -0,0 +1,19 @@ +"Stack templates can be disabled": + - do: + cluster.put_settings: + body: + transient: + stack.templates.enabled: false + + - do: + indices.get_index_template: + name: logs + + - do: + indices.delete_index_template: + name: logs + + - do: + catch: missing + indices.get_index_template: + name: logs