Skip to content

Commit 326f9e1

Browse files
Merge branch 'main' into 2025/06/30/add-node-level-write-load-stats
2 parents fb05d84 + a10f8b1 commit 326f9e1

File tree

24 files changed

+452
-83
lines changed

24 files changed

+452
-83
lines changed

docs/changelog/130427.yaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
pr: 130427
2-
summary: Disallow brackets in unquoted index pattersn
2+
summary: Disallow brackets in unquoted index patterns
33
area: ES|QL
4-
type: bug
5-
issues: []
4+
type: breaking
5+
issues:
6+
- 130378
7+
breaking:
8+
title: Unquoted index patterns do not allow `(` and `)` characters
9+
area: ES|QL
10+
details: >-
11+
Previously, ES|QL accepted unquoted index patterns containing brackets, such as `FROM index(1) | ENRICH policy(2)`.
12+
13+
This query syntax is no longer valid because it could conflict with subquery syntax, where brackets are used as delimiters.
14+
15+
Brackets are now only allowed in quoted index patterns. For example: `FROM "index(1)" | ENRICH "policy(2)"`.
16+
impact: "This affects existing queries containing brackets in index or policy names, i.e. in FROM, ENRICH, and LOOKUP JOIN commands."
17+
notable: false

docs/changelog/130909.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 130909
2+
summary: Allow adjustment of transport TLS handshake timeout
3+
area: Network
4+
type: enhancement
5+
issues: []

docs/changelog/130914.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 130914
2+
summary: Fix LIMIT NPE with null value
3+
area: ES|QL
4+
type: bug
5+
issues:
6+
- 130908

docs/reference/elasticsearch/configuration-reference/security-settings.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,6 +1933,8 @@ You can configure the following TLS/SSL settings.
19331933
`xpack.security.transport.ssl.trust_restrictions.x509_fields` ![logo cloud](https://doc-icons.s3.us-east-2.amazonaws.com/logo_cloud.svg "Supported on Elastic Cloud Hosted")
19341934
: Specifies which field(s) from the TLS certificate is used to match for the restricted trust management that is used for remote clusters connections. This should only be set when a self managed cluster can not create certificates that follow the Elastic Cloud pattern. The default value is ["subjectAltName.otherName.commonName"], the Elastic Cloud pattern. "subjectAltName.dnsName" is also supported and can be configured in addition to or in replacement of the default.
19351935

1936+
`xpack.security.transport.ssl.handshake_timeout`
1937+
: Specifies the timeout for a TLS handshake when opening a transport connection. Defaults to `10s`.
19361938

19371939
### Transport TLS/SSL key and trusted certificate settings [security-transport-tls-ssl-key-trusted-certificate-settings]
19381940

@@ -2131,6 +2133,9 @@ You can configure the following TLS/SSL settings.
21312133

21322134
For more information, see Oracle’s [Java Cryptography Architecture documentation](https://docs.oracle.com/en/java/javase/11/security/oracle-providers.md#GUID-7093246A-31A3-4304-AC5F-5FB6400405E2).
21332135

2136+
`xpack.security.remote_cluster_server.ssl.handshake_timeout`
2137+
: Specifies the timeout for a TLS handshake when handling an inbound remote-cluster connection. Defaults to `10s`.
2138+
21342139

21352140
### Remote cluster server (API key based model) TLS/SSL key and trusted certificate settings [security-remote-cluster-server-tls-ssl-key-trusted-certificate-settings]
21362141

@@ -2260,6 +2265,9 @@ You can configure the following TLS/SSL settings.
22602265

22612266
For more information, see Oracle’s [Java Cryptography Architecture documentation](https://docs.oracle.com/en/java/javase/11/security/oracle-providers.md#GUID-7093246A-31A3-4304-AC5F-5FB6400405E2).
22622267

2268+
`xpack.security.remote_cluster_client.ssl.handshake_timeout`
2269+
: Specifies the timeout for a TLS handshake when opening a remote-cluster connection. Defaults to `10s`.
2270+
22632271

22642272
### Remote cluster client (API key based model) TLS/SSL key and trusted certificate settings [security-remote-cluster-client-tls-ssl-key-trusted-certificate-settings]
22652273

libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/SslConfiguration.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ public record SslConfiguration(
4040
SslVerificationMode verificationMode,
4141
SslClientAuthenticationMode clientAuth,
4242
List<String> ciphers,
43-
List<String> supportedProtocols
43+
List<String> supportedProtocols,
44+
long handshakeTimeoutMillis
4445
) {
4546

4647
/**
@@ -71,7 +72,8 @@ public SslConfiguration(
7172
SslVerificationMode verificationMode,
7273
SslClientAuthenticationMode clientAuth,
7374
List<String> ciphers,
74-
List<String> supportedProtocols
75+
List<String> supportedProtocols,
76+
long handshakeTimeoutMillis
7577
) {
7678
this.settingPrefix = settingPrefix;
7779
this.explicitlyConfigured = explicitlyConfigured;
@@ -85,6 +87,10 @@ public SslConfiguration(
8587
this.keyConfig = Objects.requireNonNull(keyConfig, "key config cannot be null");
8688
this.verificationMode = Objects.requireNonNull(verificationMode, "verification mode cannot be null");
8789
this.clientAuth = Objects.requireNonNull(clientAuth, "client authentication cannot be null");
90+
if (handshakeTimeoutMillis < 1L) {
91+
throw new SslConfigException("handshake timeout must be at least 1ms");
92+
}
93+
this.handshakeTimeoutMillis = handshakeTimeoutMillis;
8894
this.ciphers = Collections.unmodifiableList(ciphers);
8995
this.supportedProtocols = Collections.unmodifiableList(supportedProtocols);
9096
}
@@ -164,11 +170,21 @@ public boolean equals(Object o) {
164170
&& this.verificationMode == that.verificationMode
165171
&& this.clientAuth == that.clientAuth
166172
&& Objects.equals(this.ciphers, that.ciphers)
167-
&& Objects.equals(this.supportedProtocols, that.supportedProtocols);
173+
&& Objects.equals(this.supportedProtocols, that.supportedProtocols)
174+
&& this.handshakeTimeoutMillis == that.handshakeTimeoutMillis;
168175
}
169176

170177
@Override
171178
public int hashCode() {
172-
return Objects.hash(settingPrefix, trustConfig, keyConfig, verificationMode, clientAuth, ciphers, supportedProtocols);
179+
return Objects.hash(
180+
settingPrefix,
181+
trustConfig,
182+
keyConfig,
183+
verificationMode,
184+
clientAuth,
185+
ciphers,
186+
supportedProtocols,
187+
handshakeTimeoutMillis
188+
);
173189
}
174190
}

libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/SslConfigurationKeys.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ public class SslConfigurationKeys {
132132
* The use of this setting {@link #isDeprecated(String) is deprecated}.
133133
*/
134134
public static final String KEY_LEGACY_PASSPHRASE = "key_passphrase";
135+
/**
136+
* The timeout for TLS handshakes in this context.
137+
*/
138+
public static final String HANDSHAKE_TIMEOUT = "handshake_timeout";
135139

136140
private static final Set<String> DEPRECATED_KEYS = new HashSet<>(
137141
Arrays.asList(TRUSTSTORE_LEGACY_PASSWORD, KEYSTORE_LEGACY_PASSWORD, KEYSTORE_LEGACY_KEY_PASSWORD, KEY_LEGACY_PASSPHRASE)

libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/SslConfigurationLoader.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package org.elasticsearch.common.ssl;
1111

1212
import org.elasticsearch.core.Nullable;
13+
import org.elasticsearch.core.TimeValue;
1314

1415
import java.nio.file.Path;
1516
import java.security.KeyStore;
@@ -27,6 +28,7 @@
2728
import static org.elasticsearch.common.ssl.SslConfigurationKeys.CERTIFICATE_AUTHORITIES;
2829
import static org.elasticsearch.common.ssl.SslConfigurationKeys.CIPHERS;
2930
import static org.elasticsearch.common.ssl.SslConfigurationKeys.CLIENT_AUTH;
31+
import static org.elasticsearch.common.ssl.SslConfigurationKeys.HANDSHAKE_TIMEOUT;
3032
import static org.elasticsearch.common.ssl.SslConfigurationKeys.KEY;
3133
import static org.elasticsearch.common.ssl.SslConfigurationKeys.KEYSTORE_ALGORITHM;
3234
import static org.elasticsearch.common.ssl.SslConfigurationKeys.KEYSTORE_LEGACY_KEY_PASSWORD;
@@ -152,6 +154,8 @@ public abstract class SslConfigurationLoader {
152154
private static final char[] EMPTY_PASSWORD = new char[0];
153155
public static final List<X509Field> GLOBAL_DEFAULT_RESTRICTED_TRUST_FIELDS = List.of(X509Field.SAN_OTHERNAME_COMMONNAME);
154156

157+
public static final TimeValue DEFAULT_HANDSHAKE_TIMEOUT = TimeValue.timeValueSeconds(10);
158+
155159
private final String settingPrefix;
156160

157161
private SslTrustConfig defaultTrustConfig;
@@ -302,6 +306,11 @@ public SslConfiguration load(Path basePath) {
302306
X509Field::parseForRestrictedTrust,
303307
defaultRestrictedTrustFields
304308
);
309+
final long handshakeTimeoutMillis = resolveSetting(
310+
HANDSHAKE_TIMEOUT,
311+
s -> TimeValue.parseTimeValue(s, HANDSHAKE_TIMEOUT),
312+
DEFAULT_HANDSHAKE_TIMEOUT
313+
).millis();
305314

306315
final SslKeyConfig keyConfig = buildKeyConfig(basePath);
307316
final SslTrustConfig trustConfig = buildTrustConfig(basePath, verificationMode, keyConfig, Set.copyOf(trustRestrictionsX509Fields));
@@ -321,7 +330,8 @@ public SslConfiguration load(Path basePath) {
321330
verificationMode,
322331
clientAuth,
323332
ciphers,
324-
protocols
333+
protocols,
334+
handshakeTimeoutMillis
325335
);
326336
}
327337

libs/ssl-config/src/test/java/org/elasticsearch/common/ssl/SslConfigurationTests.java

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public void testBasicConstruction() {
3939
final SslClientAuthenticationMode clientAuth = randomFrom(SslClientAuthenticationMode.values());
4040
final List<String> ciphers = randomSubsetOf(randomIntBetween(1, DEFAULT_CIPHERS.size()), DEFAULT_CIPHERS);
4141
final List<String> protocols = randomSubsetOf(randomIntBetween(1, 4), VALID_PROTOCOLS);
42+
final long handshakeTimeoutMillis = randomHandshakeTimeoutMillis();
4243
final SslConfiguration configuration = new SslConfiguration(
4344
"test.ssl",
4445
true,
@@ -47,7 +48,8 @@ public void testBasicConstruction() {
4748
verificationMode,
4849
clientAuth,
4950
ciphers,
50-
protocols
51+
protocols,
52+
handshakeTimeoutMillis
5153
);
5254

5355
assertThat(configuration.trustConfig(), is(trustConfig));
@@ -56,13 +58,15 @@ public void testBasicConstruction() {
5658
assertThat(configuration.clientAuth(), is(clientAuth));
5759
assertThat(configuration.getCipherSuites(), is(ciphers));
5860
assertThat(configuration.supportedProtocols(), is(protocols));
61+
assertThat(configuration.handshakeTimeoutMillis(), is(handshakeTimeoutMillis));
5962

6063
assertThat(configuration.toString(), containsString("TEST-TRUST"));
6164
assertThat(configuration.toString(), containsString("TEST-KEY"));
6265
assertThat(configuration.toString(), containsString(verificationMode.toString()));
6366
assertThat(configuration.toString(), containsString(clientAuth.toString()));
6467
assertThat(configuration.toString(), containsString(randomFrom(ciphers)));
6568
assertThat(configuration.toString(), containsString(randomFrom(protocols)));
69+
assertThat(configuration.toString(), containsString("handshakeTimeoutMillis=" + handshakeTimeoutMillis));
6670
}
6771

6872
public void testEqualsAndHashCode() {
@@ -72,6 +76,7 @@ public void testEqualsAndHashCode() {
7276
final SslClientAuthenticationMode clientAuth = randomFrom(SslClientAuthenticationMode.values());
7377
final List<String> ciphers = randomSubsetOf(randomIntBetween(1, DEFAULT_CIPHERS.size() - 1), DEFAULT_CIPHERS);
7478
final List<String> protocols = randomSubsetOf(randomIntBetween(1, VALID_PROTOCOLS.length - 1), VALID_PROTOCOLS);
79+
final long handshakeTimeoutMillis = randomHandshakeTimeoutMillis();
7580
final SslConfiguration configuration = new SslConfiguration(
7681
"test.ssl",
7782
true,
@@ -80,7 +85,8 @@ public void testEqualsAndHashCode() {
8085
verificationMode,
8186
clientAuth,
8287
ciphers,
83-
protocols
88+
protocols,
89+
handshakeTimeoutMillis
8490
);
8591

8692
EqualsHashCodeTestUtils.checkEqualsAndHashCode(
@@ -93,14 +99,15 @@ public void testEqualsAndHashCode() {
9399
orig.verificationMode(),
94100
orig.clientAuth(),
95101
orig.getCipherSuites(),
96-
orig.supportedProtocols()
102+
orig.supportedProtocols(),
103+
orig.handshakeTimeoutMillis()
97104
),
98105
this::mutateSslConfiguration
99106
);
100107
}
101108

102109
private SslConfiguration mutateSslConfiguration(SslConfiguration orig) {
103-
return switch (randomIntBetween(1, 4)) {
110+
return switch (randomIntBetween(1, 5)) {
104111
case 1 -> new SslConfiguration(
105112
"test.ssl",
106113
true,
@@ -109,7 +116,8 @@ private SslConfiguration mutateSslConfiguration(SslConfiguration orig) {
109116
randomValueOtherThan(orig.verificationMode(), () -> randomFrom(SslVerificationMode.values())),
110117
orig.clientAuth(),
111118
orig.getCipherSuites(),
112-
orig.supportedProtocols()
119+
orig.supportedProtocols(),
120+
orig.handshakeTimeoutMillis()
113121
);
114122
case 2 -> new SslConfiguration(
115123
"test.ssl",
@@ -119,7 +127,8 @@ private SslConfiguration mutateSslConfiguration(SslConfiguration orig) {
119127
orig.verificationMode(),
120128
randomValueOtherThan(orig.clientAuth(), () -> randomFrom(SslClientAuthenticationMode.values())),
121129
orig.getCipherSuites(),
122-
orig.supportedProtocols()
130+
orig.supportedProtocols(),
131+
orig.handshakeTimeoutMillis()
123132
);
124133
case 3 -> new SslConfiguration(
125134
"test.ssl",
@@ -129,7 +138,19 @@ private SslConfiguration mutateSslConfiguration(SslConfiguration orig) {
129138
orig.verificationMode(),
130139
orig.clientAuth(),
131140
DEFAULT_CIPHERS,
132-
orig.supportedProtocols()
141+
orig.supportedProtocols(),
142+
orig.handshakeTimeoutMillis()
143+
);
144+
case 4 -> new SslConfiguration(
145+
"test.ssl",
146+
true,
147+
orig.trustConfig(),
148+
orig.keyConfig(),
149+
orig.verificationMode(),
150+
orig.clientAuth(),
151+
orig.getCipherSuites(),
152+
Arrays.asList(VALID_PROTOCOLS),
153+
orig.handshakeTimeoutMillis()
133154
);
134155
default -> new SslConfiguration(
135156
"test.ssl",
@@ -139,11 +160,16 @@ private SslConfiguration mutateSslConfiguration(SslConfiguration orig) {
139160
orig.verificationMode(),
140161
orig.clientAuth(),
141162
orig.getCipherSuites(),
142-
Arrays.asList(VALID_PROTOCOLS)
163+
orig.supportedProtocols(),
164+
randomValueOtherThan(orig.handshakeTimeoutMillis(), SslConfigurationTests::randomHandshakeTimeoutMillis)
143165
);
144166
};
145167
}
146168

169+
private static long randomHandshakeTimeoutMillis() {
170+
return randomLongBetween(1, 100000);
171+
}
172+
147173
public void testDependentFiles() {
148174
final SslTrustConfig trustConfig = Mockito.mock(SslTrustConfig.class);
149175
final SslKeyConfig keyConfig = Mockito.mock(SslKeyConfig.class);
@@ -155,7 +181,8 @@ public void testDependentFiles() {
155181
randomFrom(SslVerificationMode.values()),
156182
randomFrom(SslClientAuthenticationMode.values()),
157183
DEFAULT_CIPHERS,
158-
SslConfigurationLoader.DEFAULT_PROTOCOLS
184+
SslConfigurationLoader.DEFAULT_PROTOCOLS,
185+
randomHandshakeTimeoutMillis()
159186
);
160187

161188
final Path dir = createTempDir();
@@ -182,7 +209,8 @@ public void testBuildSslContext() {
182209
randomFrom(SslVerificationMode.values()),
183210
randomFrom(SslClientAuthenticationMode.values()),
184211
DEFAULT_CIPHERS,
185-
Collections.singletonList(protocol)
212+
Collections.singletonList(protocol),
213+
randomHandshakeTimeoutMillis()
186214
);
187215

188216
Mockito.when(trustConfig.createTrustManager()).thenReturn(null);

muted-tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,9 @@ tests:
576576
- class: org.elasticsearch.xpack.esql.action.EsqlActionBreakerIT
577577
method: testRowStatsProjectGroupByInt
578578
issue: https://github.com/elastic/elasticsearch/issues/131024
579+
- class: org.elasticsearch.xpack.esql.qa.mixed.EsqlClientYamlIT
580+
method: test {p0=esql/60_enrich/Enrich in fork}
581+
issue: https://github.com/elastic/elasticsearch/issues/131028
579582

580583
# Examples:
581584
#

server/src/main/java/org/elasticsearch/tasks/TaskManager.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,21 +170,33 @@ public Task register(String type, String action, TaskAwareRequest request, boole
170170
Task previousTask = tasks.put(task.getId(), task);
171171
assert previousTask == null;
172172
if (traceRequest) {
173-
startTrace(threadContext, task);
173+
maybeStartTrace(threadContext, task);
174174
}
175175
}
176176
return task;
177177
}
178178

179-
// package private for testing
180-
void startTrace(ThreadContext threadContext, Task task) {
179+
/**
180+
* Start a new trace span if a parent trace context already exists.
181+
* For REST actions this will be the case, otherwise {@link Tracer#startTrace} can be used.
182+
*/
183+
void maybeStartTrace(ThreadContext threadContext, Task task) {
184+
if (threadContext.hasParentTraceContext() == false) {
185+
return;
186+
}
181187
TaskId parentTask = task.getParentTaskId();
182188
Map<String, Object> attributes = parentTask.isSet()
183189
? Map.of(Tracer.AttributeKeys.TASK_ID, task.getId(), Tracer.AttributeKeys.PARENT_TASK_ID, parentTask.toString())
184190
: Map.of(Tracer.AttributeKeys.TASK_ID, task.getId());
185191
tracer.startTrace(threadContext, task, task.getAction(), attributes);
186192
}
187193

194+
void maybeStopTrace(ThreadContext threadContext, Task task) {
195+
if (threadContext.hasTraceContext()) {
196+
tracer.stopTrace(task);
197+
}
198+
}
199+
188200
public <Request extends ActionRequest, Response extends ActionResponse> Task registerAndExecute(
189201
String type,
190202
TransportAction<Request, Response> action,
@@ -247,7 +259,7 @@ private void registerCancellableTask(Task task, long requestId, boolean traceReq
247259
CancellableTaskHolder holder = new CancellableTaskHolder(cancellableTask);
248260
cancellableTasks.put(task, requestId, holder);
249261
if (traceRequest) {
250-
startTrace(threadPool.getThreadContext(), task);
262+
maybeStartTrace(threadPool.getThreadContext(), task);
251263
}
252264
// Check if this task was banned before we start it.
253265
if (task.getParentTaskId().isSet()) {
@@ -346,7 +358,7 @@ public Task unregister(Task task) {
346358
return removedTask;
347359
}
348360
} finally {
349-
tracer.stopTrace(task);
361+
maybeStopTrace(threadPool.getThreadContext(), task);
350362
for (RemovedTaskListener listener : removedTaskListeners) {
351363
listener.onRemoved(task);
352364
}

0 commit comments

Comments
 (0)