diff --git a/docs/changelog/99644.yaml b/docs/changelog/99644.yaml new file mode 100644 index 0000000000000..10c10448c074c --- /dev/null +++ b/docs/changelog/99644.yaml @@ -0,0 +1,6 @@ +pr: 99644 +summary: Add links to docs from failing bootstrap checks +area: Infra/Node Lifecycle +type: enhancement +issues: [99614] + diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilBootstrapChecksTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilBootstrapChecksTests.java index eda3c337c98f4..58bf1760551d4 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilBootstrapChecksTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilBootstrapChecksTests.java @@ -9,6 +9,7 @@ package org.elasticsearch.bootstrap; import org.apache.logging.log4j.Logger; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.core.SuppressForbidden; import org.elasticsearch.node.NodeValidationException; import org.elasticsearch.test.AbstractBootstrapCheckTestCase; @@ -49,7 +50,17 @@ public void tearDown() throws Exception { public void testEnforceBootstrapChecks() throws NodeValidationException { setEsEnforceBootstrapChecks("true"); - final List checks = Collections.singletonList(context -> BootstrapCheck.BootstrapCheckResult.failure("error")); + final List checks = Collections.singletonList(new BootstrapCheck() { + @Override + public BootstrapCheckResult check(BootstrapContext context) { + return BootstrapCheck.BootstrapCheckResult.failure("error"); + } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECKS; + } + }); final Logger logger = mock(Logger.class); diff --git a/server/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java b/server/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java index 75e5fcfa3fa0f..6a32959b7e5f7 100644 --- a/server/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java +++ b/server/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java @@ -8,6 +8,8 @@ package org.elasticsearch.bootstrap; +import org.elasticsearch.common.ReferenceDocs; + import java.util.Objects; /** @@ -59,4 +61,6 @@ default boolean alwaysEnforce() { return false; } + ReferenceDocs referenceDocs(); + } diff --git a/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java b/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java index b9610c689f92e..a99ed225b244b 100644 --- a/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java +++ b/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java @@ -12,6 +12,7 @@ import org.apache.logging.log4j.Logger; import org.apache.lucene.util.Constants; import org.elasticsearch.cluster.coordination.ClusterBootstrapService; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; @@ -131,10 +132,11 @@ static void check(final BootstrapContext context, final boolean enforceLimits, f for (final BootstrapCheck check : checks) { final BootstrapCheck.BootstrapCheckResult result = check.check(context); if (result.isFailure()) { + final String message = result.getMessage() + "; for more information see [" + check.referenceDocs() + "]"; if (enforceLimits == false && enforceBootstrapChecks == false && check.alwaysEnforce() == false) { - ignoredErrors.add(result.getMessage()); + ignoredErrors.add(message); } else { - errors.add(result.getMessage()); + errors.add(message); } } } @@ -150,7 +152,9 @@ static void check(final BootstrapContext context, final boolean enforceLimits, f + errors.size() + "] bootstrap checks failed. You must address the points described in the following [" + errors.size() - + "] lines before starting Elasticsearch." + + "] lines before starting Elasticsearch. For more information see [" + + ReferenceDocs.BOOTSTRAP_CHECKS + + "]" ); for (int i = 0; i < errors.size(); i++) { messages.add("bootstrap check failure [" + (i + 1) + "] of [" + errors.size() + "]: " + errors.get(i)); @@ -240,6 +244,11 @@ public BootstrapCheckResult check(BootstrapContext context) { } } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_HEAP_SIZE; + } + // visible for testing long getInitialHeapSize() { return JvmInfo.jvmInfo().getConfiguredInitialHeapSize(); @@ -298,6 +307,11 @@ public final BootstrapCheckResult check(BootstrapContext context) { } } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_FILE_DESCRIPTOR; + } + // visible for testing long getMaxFileDescriptorCount() { return ProcessProbe.getMaxFileDescriptorCount(); @@ -321,6 +335,11 @@ boolean isMemoryLocked() { return Natives.isMemoryLocked(); } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_MEMORY_LOCK; + } + } static class MaxNumberOfThreadsCheck implements BootstrapCheck { @@ -349,6 +368,10 @@ long getMaxNumberOfThreads() { return JNANatives.MAX_NUMBER_OF_THREADS; } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_MAX_NUMBER_THREADS; + } } static class MaxSizeVirtualMemoryCheck implements BootstrapCheck { @@ -378,6 +401,10 @@ long getMaxSizeVirtualMemory() { return JNANatives.MAX_SIZE_VIRTUAL_MEMORY; } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_MAX_SIZE_VIRTUAL_MEMORY; + } } /** @@ -409,6 +436,10 @@ long getMaxFileSize() { return JNANatives.MAX_FILE_SIZE; } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_MAX_FILE_SIZE; + } } static class MaxMapCountCheck implements BootstrapCheck { @@ -478,6 +509,10 @@ static long parseProcSysVmMaxMapCount(final String procSysVmMaxMapCount) throws return Long.parseLong(procSysVmMaxMapCount); } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_MAXIMUM_MAP_COUNT; + } } static class ClientJvmCheck implements BootstrapCheck { @@ -501,6 +536,10 @@ String getVmName() { return JvmInfo.jvmInfo().getVmName(); } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_CLIENT_JVM; + } } /** @@ -529,6 +568,10 @@ String getUseSerialGC() { return JvmInfo.jvmInfo().useSerialGC(); } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_USE_SERIAL_COLLECTOR; + } } /** @@ -551,6 +594,10 @@ boolean isSystemCallFilterInstalled() { return Natives.isSystemCallFilterInstalled(); } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_SYSTEM_CALL_FILTER; + } } abstract static class MightForkCheck implements BootstrapCheck { @@ -579,6 +626,11 @@ public final boolean alwaysEnforce() { return true; } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_ONERROR_AND_ONOUTOFMEMORYERROR; + } + } static class OnErrorCheck extends MightForkCheck { @@ -658,6 +710,11 @@ String javaVersion() { return Constants.JAVA_VERSION; } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_EARLY_ACCESS; + } + } static class AllPermissionCheck implements BootstrapCheck { @@ -681,6 +738,10 @@ boolean isAllPermissionGranted() { return true; } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_ALL_PERMISSION; + } } static class DiscoveryConfiguredCheck implements BootstrapCheck { @@ -703,6 +764,11 @@ public BootstrapCheckResult check(BootstrapContext context) { ) ); } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_DISCOVERY_CONFIGURATION; + } } static class ByteOrderCheck implements BootstrapCheck { @@ -718,5 +784,10 @@ public BootstrapCheckResult check(BootstrapContext context) { ByteOrder nativeByteOrder() { return ByteOrder.nativeOrder(); } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECKS; + } } } diff --git a/server/src/main/java/org/elasticsearch/common/ReferenceDocs.java b/server/src/main/java/org/elasticsearch/common/ReferenceDocs.java index 0f60dbff56cfa..1ff42b16252c8 100644 --- a/server/src/main/java/org/elasticsearch/common/ReferenceDocs.java +++ b/server/src/main/java/org/elasticsearch/common/ReferenceDocs.java @@ -46,6 +46,28 @@ public enum ReferenceDocs { CONCURRENT_REPOSITORY_WRITERS, ARCHIVE_INDICES, HTTP_TRACER, + BOOTSTRAP_CHECK_HEAP_SIZE, + BOOTSTRAP_CHECK_FILE_DESCRIPTOR, + BOOTSTRAP_CHECK_MEMORY_LOCK, + BOOTSTRAP_CHECK_MAX_NUMBER_THREADS, + BOOTSTRAP_CHECK_MAX_FILE_SIZE, + BOOTSTRAP_CHECK_MAX_SIZE_VIRTUAL_MEMORY, + BOOTSTRAP_CHECK_MAXIMUM_MAP_COUNT, + BOOTSTRAP_CHECK_CLIENT_JVM, + BOOTSTRAP_CHECK_USE_SERIAL_COLLECTOR, + BOOTSTRAP_CHECK_SYSTEM_CALL_FILTER, + BOOTSTRAP_CHECK_ONERROR_AND_ONOUTOFMEMORYERROR, + BOOTSTRAP_CHECK_EARLY_ACCESS, + BOOTSTRAP_CHECK_G1GC, + BOOTSTRAP_CHECK_ALL_PERMISSION, + BOOTSTRAP_CHECK_DISCOVERY_CONFIGURATION, + BOOTSTRAP_CHECKS, + BOOTSTRAP_CHECK_ENCRYPT_SENSITIVE_DATA, + BOOTSTRAP_CHECK_PKI_REALM, + BOOTSTRAP_CHECK_ROLE_MAPPINGS, + BOOTSTRAP_CHECK_TLS, + BOOTSTRAP_CHECK_TOKEN_SSL, + BOOTSTRAP_CHECK_SECURITY_MINIMAL_SETUP, // this comment keeps the ';' on the next line so every entry above has a trailing ',' which makes the diff for adding new links cleaner ; diff --git a/server/src/main/resources/org/elasticsearch/common/reference-docs-links.json b/server/src/main/resources/org/elasticsearch/common/reference-docs-links.json index 4de327d203d16..b162aa5b6c31a 100644 --- a/server/src/main/resources/org/elasticsearch/common/reference-docs-links.json +++ b/server/src/main/resources/org/elasticsearch/common/reference-docs-links.json @@ -6,5 +6,27 @@ "SHARD_LOCK_TROUBLESHOOTING": "troubleshooting-unstable-cluster.html#_diagnosing_shardlockobtainfailedexception_failures_2", "CONCURRENT_REPOSITORY_WRITERS": "add-repository.html", "ARCHIVE_INDICES": "archive-indices.html", - "HTTP_TRACER": "modules-network.html#http-rest-request-tracer" + "HTTP_TRACER": "modules-network.html#http-rest-request-tracer", + "BOOTSTRAP_CHECK_HEAP_SIZE": "_heap_size_check.html", + "BOOTSTRAP_CHECK_FILE_DESCRIPTOR": "_file_descriptor_check.html", + "BOOTSTRAP_CHECK_MEMORY_LOCK": "_memory_lock_check.html", + "BOOTSTRAP_CHECK_MAX_NUMBER_THREADS": "max-number-threads-check.html", + "BOOTSTRAP_CHECK_MAX_FILE_SIZE": "_max_file_size_check.html", + "BOOTSTRAP_CHECK_MAX_SIZE_VIRTUAL_MEMORY": "max-size-virtual-memory-check.html", + "BOOTSTRAP_CHECK_MAXIMUM_MAP_COUNT": "_maximum_map_count_check.html", + "BOOTSTRAP_CHECK_CLIENT_JVM": "_client_jvm_check.html", + "BOOTSTRAP_CHECK_USE_SERIAL_COLLECTOR": "_use_serial_collector_check.html", + "BOOTSTRAP_CHECK_SYSTEM_CALL_FILTER": "_system_call_filter_check.html", + "BOOTSTRAP_CHECK_ONERROR_AND_ONOUTOFMEMORYERROR": "_onerror_and_onoutofmemoryerror_checks.html", + "BOOTSTRAP_CHECK_EARLY_ACCESS": "_early_access_check.html", + "BOOTSTRAP_CHECK_G1GC": "_g1gc_check.html", + "BOOTSTRAP_CHECK_ALL_PERMISSION": "_all_permission_check.html", + "BOOTSTRAP_CHECK_DISCOVERY_CONFIGURATION": "_discovery_configuration_check.html", + "BOOTSTRAP_CHECKS": "bootstrap-checks.html", + "BOOTSTRAP_CHECK_ENCRYPT_SENSITIVE_DATA": "bootstrap-checks-xpack.html#_encrypt_sensitive_data_check", + "BOOTSTRAP_CHECK_PKI_REALM": "bootstrap-checks-xpack.html#_pki_realm_check", + "BOOTSTRAP_CHECK_ROLE_MAPPINGS": "bootstrap-checks-xpack.html#_role_mappings_check", + "BOOTSTRAP_CHECK_TLS": "bootstrap-checks-xpack.html#bootstrap-checks-tls", + "BOOTSTRAP_CHECK_TOKEN_SSL": "bootstrap-checks-xpack.html#_token_ssl_check", + "BOOTSTRAP_CHECK_SECURITY_MINIMAL_SETUP": "security-minimal-setup.html" } diff --git a/server/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java b/server/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java index 843a65aa877ac..09ef0b6affc23 100644 --- a/server/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java +++ b/server/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java @@ -12,6 +12,7 @@ import org.apache.lucene.util.Constants; import org.elasticsearch.cluster.coordination.ClusterBootstrapService; import org.elasticsearch.cluster.metadata.Metadata; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.BoundTransportAddress; import org.elasticsearch.common.transport.TransportAddress; @@ -128,10 +129,27 @@ public void testEnforceLimitsWhenPublishingToNonLocalAddress() { } public void testExceptionAggregation() { - final List checks = Arrays.asList( - context -> BootstrapCheck.BootstrapCheckResult.failure("first"), - context -> BootstrapCheck.BootstrapCheckResult.failure("second") - ); + final List checks = Arrays.asList(new BootstrapCheck() { + @Override + public BootstrapCheckResult check(BootstrapContext context) { + return BootstrapCheck.BootstrapCheckResult.failure("first"); + } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECKS; + } + }, new BootstrapCheck() { + @Override + public BootstrapCheckResult check(BootstrapContext context) { + return BootstrapCheck.BootstrapCheckResult.failure("second"); + } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECKS; + } + }); final NodeValidationException e = expectThrows( NodeValidationException.class, @@ -146,7 +164,8 @@ public void testExceptionAggregation() { containsString("bootstrap check failure [1] of [2]:"), containsString("first"), containsString("bootstrap check failure [2] of [2]:"), - containsString("second") + containsString("second"), + containsString("For more information see [https://www.elastic.co/guide/en/elasticsearch/reference/") ) ) ); @@ -194,6 +213,7 @@ boolean isMemoryLocked() { "initial heap size [" + initialHeapSize.get() + "] " + "not equal to maximum heap size [" + maxHeapSize.get() + "]" ) ); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); final String memoryLockingMessage = "and prevents memory locking from locking the entire heap"; final Matcher memoryLockingMatcher; if (isMemoryLocked) { @@ -243,6 +263,7 @@ long getMaxFileDescriptorCount() { () -> BootstrapChecks.check(emptyContext, true, Collections.singletonList(check)) ); assertThat(e.getMessage(), containsString("max file descriptors")); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); maxFileDescriptorCount.set(randomIntBetween(limit + 1, Integer.MAX_VALUE)); @@ -300,6 +321,10 @@ boolean isMemoryLocked() { () -> BootstrapChecks.check(bootstrapContext, true, Collections.singletonList(check)) ); assertThat(e.getMessage(), containsString("memory locking requested for elasticsearch process but memory is not locked")); + assertThat( + e.getMessage(), + containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/") + ); } else { // nothing should happen BootstrapChecks.check(bootstrapContext, true, Collections.singletonList(check)); @@ -322,6 +347,7 @@ long getMaxNumberOfThreads() { () -> BootstrapChecks.check(emptyContext, true, Collections.singletonList(check)) ); assertThat(e.getMessage(), containsString("max number of threads")); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); maxNumberOfThreads.set(randomIntBetween(limit + 1, Integer.MAX_VALUE)); @@ -353,6 +379,7 @@ long getRlimInfinity() { () -> BootstrapChecks.check(emptyContext, true, Collections.singletonList(check)) ); assertThat(e.getMessage(), containsString("max size virtual memory")); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); maxSizeVirtualMemory.set(rlimInfinity); @@ -383,6 +410,7 @@ long getRlimInfinity() { () -> BootstrapChecks.check(emptyContext, true, Collections.singletonList(check)) ); assertThat(e.getMessage(), containsString("max file size")); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); maxFileSize.set(rlimInfinity); @@ -413,6 +441,7 @@ String getVmName() { + "but should be using a server VM for the best performance" ) ); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); vmName.set("Java HotSpot(TM) 32-Bit Server VM"); BootstrapChecks.check(emptyContext, true, Collections.singletonList(check)); @@ -441,6 +470,7 @@ String getUseSerialGC() { + "] or -XX:+UseSerialGC was explicitly specified" ) ); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); useSerialGC.set("false"); BootstrapChecks.check(emptyContext, true, Collections.singletonList(check)); @@ -464,6 +494,7 @@ boolean isSystemCallFilterInstalled() { () -> BootstrapChecks.check(context, true, Collections.singletonList(systemCallFilterEnabledCheck)) ); assertThat(e.getMessage(), containsString("system call filters failed to install; check the logs and fix your configuration")); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); isSystemCallFilterInstalled.set(true); BootstrapChecks.check(context, true, Collections.singletonList(systemCallFilterEnabledCheck)); @@ -489,13 +520,13 @@ String message(BootstrapContext context) { } }; - runMightForkTest( - check, - isSystemCallFilterInstalled, - () -> mightFork.set(false), - () -> mightFork.set(true), - e -> assertThat(e.getMessage(), containsString("error")) - ); + runMightForkTest(check, isSystemCallFilterInstalled, () -> mightFork.set(false), () -> mightFork.set(true), e -> { + assertThat(e.getMessage(), containsString("error")); + assertThat( + e.getMessage(), + containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/") + ); + }); } public void testOnErrorCheck() throws NodeValidationException { @@ -521,15 +552,21 @@ String onError() { isSystemCallFilterInstalled, () -> onError.set(randomBoolean() ? "" : null), () -> onError.set(command), - e -> assertThat( - e.getMessage(), - containsString( - "OnError [" - + command - + "] requires forking but is prevented by system call filters;" - + " upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError" - ) - ) + e -> { + assertThat( + e.getMessage(), + containsString( + "OnError [" + + command + + "] requires forking but is prevented by system call filters;" + + " upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError" + ) + ); + assertThat( + e.getMessage(), + containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/") + ); + } ); } @@ -556,16 +593,22 @@ String onOutOfMemoryError() { isSystemCallFilterInstalled, () -> onOutOfMemoryError.set(randomBoolean() ? "" : null), () -> onOutOfMemoryError.set(command), - e -> assertThat( - e.getMessage(), - containsString( - "OnOutOfMemoryError [" - + command - + "]" - + " requires forking but is prevented by system call filters;" - + " upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError" - ) - ) + e -> { + assertThat( + e.getMessage(), + containsString( + "OnOutOfMemoryError [" + + command + + "]" + + " requires forking but is prevented by system call filters;" + + " upgrade to at least Java 8u92 and use ExitOnOutOfMemoryError" + ) + ); + assertThat( + e.getMessage(), + containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/") + ); + } ); } @@ -629,6 +672,7 @@ String javaVersion() { e.getMessage(), containsString("Java version [" + javaVersion.get() + "] is an early-access build, only use release builds") ); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); // if not on an early-access build, nothing should happen javaVersion.set(randomFrom("1.8.0_152", "9")); @@ -651,6 +695,7 @@ boolean isAllPermissionGranted() { () -> BootstrapChecks.check(emptyContext, true, checks) ); assertThat(e, hasToString(containsString("granting the all permission effectively disables security"))); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); // if all permissions are not granted, nothing should happen isAllPermissionGranted.set(false); @@ -668,6 +713,11 @@ public BootstrapCheckResult check(BootstrapContext context) { public boolean alwaysEnforce() { return true; } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECKS; + } }; final NodeValidationException alwaysEnforced = expectThrows( @@ -678,7 +728,8 @@ public boolean alwaysEnforce() { } public void testDiscoveryConfiguredCheck() throws NodeValidationException { - final List checks = Collections.singletonList(new BootstrapChecks.DiscoveryConfiguredCheck()); + final BootstrapChecks.DiscoveryConfiguredCheck check = new BootstrapChecks.DiscoveryConfiguredCheck(); + final List checks = Collections.singletonList(check); final BootstrapContext zen2Context = createTestContext( Settings.builder().put(DiscoveryModule.DISCOVERY_TYPE_SETTING.getKey(), MULTI_NODE_DISCOVERY_TYPE).build(), @@ -713,6 +764,7 @@ public void testDiscoveryConfiguredCheck() throws NodeValidationException { ) ) ); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); CheckedConsumer ensureChecksPass = b -> { final BootstrapContext context = createTestContext( @@ -741,6 +793,7 @@ ByteOrder nativeByteOrder() { () -> BootstrapChecks.check(emptyContext, true, List.of(byteOrderCheck)) ); assertThat(e.getMessage(), containsString("Little-endian native byte order is required to run Elasticsearch")); + assertThat(e.getMessage(), containsString("; for more information see [https://www.elastic.co/guide/en/elasticsearch/reference/")); reference[0] = ByteOrder.LITTLE_ENDIAN; BootstrapChecks.check(emptyContext, true, List.of(byteOrderCheck)); diff --git a/server/src/test/java/org/elasticsearch/node/NodeTests.java b/server/src/test/java/org/elasticsearch/node/NodeTests.java index 0a0040eebea39..e5ecb63fe2137 100644 --- a/server/src/test/java/org/elasticsearch/node/NodeTests.java +++ b/server/src/test/java/org/elasticsearch/node/NodeTests.java @@ -16,6 +16,7 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.routing.allocation.AllocationService; import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.common.breaker.CircuitBreaker; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.component.AbstractLifecycleComponent; @@ -93,7 +94,17 @@ public class NodeTests extends ESTestCase { public static class CheckPlugin extends Plugin { - public static final BootstrapCheck CHECK = context -> BootstrapCheck.BootstrapCheckResult.success(); + public static final BootstrapCheck CHECK = new BootstrapCheck() { + @Override + public BootstrapCheckResult check(BootstrapContext context) { + return BootstrapCheck.BootstrapCheckResult.success(); + } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECKS; + } + }; @Override public List getBootstrapChecks() { diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/TransportTLSBootstrapCheck.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/TransportTLSBootstrapCheck.java index 5899736481884..5c5d556181343 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/TransportTLSBootstrapCheck.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/TransportTLSBootstrapCheck.java @@ -8,6 +8,7 @@ import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.bootstrap.BootstrapContext; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.xpack.core.XPackSettings; /** @@ -27,4 +28,9 @@ public BootstrapCheckResult check(BootstrapContext context) { } return BootstrapCheckResult.success(); } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_TLS; + } } diff --git a/x-pack/plugin/ml-package-loader/src/main/java/org/elasticsearch/xpack/ml/packageloader/MachineLearningPackageLoader.java b/x-pack/plugin/ml-package-loader/src/main/java/org/elasticsearch/xpack/ml/packageloader/MachineLearningPackageLoader.java index 46ba695624f60..2afeda1f13512 100644 --- a/x-pack/plugin/ml-package-loader/src/main/java/org/elasticsearch/xpack/ml/packageloader/MachineLearningPackageLoader.java +++ b/x-pack/plugin/ml-package-loader/src/main/java/org/elasticsearch/xpack/ml/packageloader/MachineLearningPackageLoader.java @@ -11,6 +11,7 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.bootstrap.BootstrapContext; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.plugins.ActionPlugin; @@ -88,6 +89,11 @@ public BootstrapCheckResult check(BootstrapContext context) { public boolean alwaysEnforce() { return true; } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECKS; + } }); } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/PkiRealmBootstrapCheck.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/PkiRealmBootstrapCheck.java index eac48d3fe7950..26112ed11231f 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/PkiRealmBootstrapCheck.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/PkiRealmBootstrapCheck.java @@ -8,6 +8,7 @@ import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.bootstrap.BootstrapContext; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.ssl.SslConfiguration; import org.elasticsearch.xpack.core.XPackSettings; @@ -78,4 +79,9 @@ private List getSslContextNames(Settings settings) { public boolean alwaysEnforce() { return true; } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_PKI_REALM; + } } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityImplicitBehaviorBootstrapCheck.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityImplicitBehaviorBootstrapCheck.java index ab9aa32c9b859..c6396f886b4bc 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityImplicitBehaviorBootstrapCheck.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityImplicitBehaviorBootstrapCheck.java @@ -10,6 +10,7 @@ import org.elasticsearch.Version; import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.bootstrap.BootstrapContext; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.env.NodeMetadata; import org.elasticsearch.license.ClusterStateLicenseService; import org.elasticsearch.license.License; @@ -44,11 +45,9 @@ public BootstrapCheckResult check(BootstrapContext context) { + "] has changed in the current version. " + " Security features were implicitly disabled for this node but they would now be enabled, possibly" + " preventing access to the node. " - + "See https://www.elastic.co/guide/en/elasticsearch/reference/" - + Version.CURRENT.major - + "." - + Version.CURRENT.minor - + "/security-minimal-setup.html to configure security, or explicitly disable security by " + + "See " + + this.referenceDocs() + + " to configure security, or explicitly disable security by " + "setting [xpack.security.enabled] to \"false\" in elasticsearch.yml before restarting the node." ); } @@ -59,4 +58,9 @@ public BootstrapCheckResult check(BootstrapContext context) { public boolean alwaysEnforce() { return true; } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_SECURITY_MINIMAL_SETUP; + } } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/TokenSSLBootstrapCheck.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/TokenSSLBootstrapCheck.java index 1c2fbb3df425b..7611ef8d258ce 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/TokenSSLBootstrapCheck.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/TokenSSLBootstrapCheck.java @@ -8,6 +8,7 @@ import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.bootstrap.BootstrapContext; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.xpack.core.XPackSettings; import java.util.Locale; @@ -35,4 +36,8 @@ public BootstrapCheckResult check(BootstrapContext context) { } } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_TOKEN_SSL; + } } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/RoleMappingFileBootstrapCheck.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/RoleMappingFileBootstrapCheck.java index b76124d5c4631..d70552f016bbf 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/RoleMappingFileBootstrapCheck.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/RoleMappingFileBootstrapCheck.java @@ -9,6 +9,7 @@ import org.apache.logging.log4j.LogManager; import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.bootstrap.BootstrapContext; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.xpack.core.security.authc.RealmConfig; import org.elasticsearch.xpack.core.security.authc.support.DnRoleMapperSettings; @@ -51,4 +52,8 @@ public static BootstrapCheck create(RealmConfig realmConfig) { return null; } + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_ROLE_MAPPINGS; + } } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityImplicitBehaviorBootstrapCheckTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityImplicitBehaviorBootstrapCheckTests.java index 3a1ae84b7c682..9775e461c4165 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityImplicitBehaviorBootstrapCheckTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityImplicitBehaviorBootstrapCheckTests.java @@ -10,6 +10,7 @@ import org.elasticsearch.Version; import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.cluster.metadata.Metadata; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.TimeValue; import org.elasticsearch.env.NodeMetadata; @@ -53,11 +54,9 @@ public void testFailureUpgradeFrom7xWithImplicitSecuritySettings() throws Except + "] has changed in the current version. " + " Security features were implicitly disabled for this node but they would now be enabled, possibly" + " preventing access to the node. " - + "See https://www.elastic.co/guide/en/elasticsearch/reference/" - + Version.CURRENT.major - + "." - + Version.CURRENT.minor - + "/security-minimal-setup.html to configure security, or explicitly disable security by " + + "See " + + ReferenceDocs.BOOTSTRAP_CHECK_SECURITY_MINIMAL_SETUP + + " to configure security, or explicitly disable security by " + "setting [xpack.security.enabled] to \"false\" in elasticsearch.yml before restarting the node." ) ); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/EncryptSensitiveDataBootstrapCheck.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/EncryptSensitiveDataBootstrapCheck.java index 555787f577efe..430d6985e3444 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/EncryptSensitiveDataBootstrapCheck.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/EncryptSensitiveDataBootstrapCheck.java @@ -8,6 +8,7 @@ import org.elasticsearch.bootstrap.BootstrapCheck; import org.elasticsearch.bootstrap.BootstrapContext; +import org.elasticsearch.common.ReferenceDocs; import org.elasticsearch.xpack.core.XPackPlugin; import org.elasticsearch.xpack.core.watcher.WatcherField; @@ -50,4 +51,9 @@ public BootstrapCheckResult check(BootstrapContext context) { public boolean alwaysEnforce() { return true; } + + @Override + public ReferenceDocs referenceDocs() { + return ReferenceDocs.BOOTSTRAP_CHECK_ENCRYPT_SENSITIVE_DATA; + } }