Skip to content

Commit 30bef59

Browse files
prwhelanchrisparrinello
authored andcommitted
[ML] Disable CPS for Dataframes (elastic#136716)
Cross-Project Search and Cross-Cluster Search is indefinitely disabled for Dataframe Analytics. The error message will now display if the syntax would have otherwise resolved to the respective feature.
1 parent f60f60d commit 30bef59

File tree

6 files changed

+138
-4
lines changed

6 files changed

+138
-4
lines changed

x-pack/plugin/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ tasks.named("yamlRestCompatTestTransform").configure({ task ->
143143
task.skipTest("ml/sparse_vector_search/Search on a sparse_vector field with dots in the field names", "Vectors are no longer returned by default")
144144
task.skipTest("ml/sparse_vector_search/Search on a nested sparse_vector field with dots in the field names and conflicting child fields", "Vectors are no longer returned by default")
145145
task.skipTest("esql/190_lookup_join/lookup-no-key-only-key", "Requires the fix")
146+
task.skipTest("ml/data_frame_analytics_crud/Test put config with remote source index", "Error message changed")
146147
})
147148

148149
tasks.named('yamlRestCompatTest').configure {

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/common/validation/SourceDestValidator.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ public final class SourceDestValidator {
6969
+ "alias [{0}], at least a [{1}] license is required, found license [{2}]";
7070
public static final String REMOTE_CLUSTER_LICENSE_INACTIVE = "License check failed for remote cluster "
7171
+ "alias [{0}], license is not active";
72-
public static final String REMOTE_SOURCE_INDICES_NOT_SUPPORTED = "remote source indices are not supported";
72+
public static final String REMOTE_SOURCE_AND_CROSS_PROJECT_INDICES_ARE_NOT_SUPPORTED =
73+
"remote source and cross-project indices are not supported";
7374
public static final String REMOTE_CLUSTERS_TRANSPORT_TOO_OLD =
7475
"remote clusters are expected to run at least version [{0}] (reason: [{1}])," + " but the following clusters were too old: [{2}]";
7576
public static final String PIPELINE_MISSING = "Pipeline with id [{0}] could not be found";
@@ -555,7 +556,7 @@ static class RemoteSourceNotSupportedValidation implements SourceDestValidation
555556
@Override
556557
public void validate(Context context, ActionListener<Context> listener) {
557558
if (context.resolveRemoteSource().isEmpty() == false) {
558-
context.addValidationError(REMOTE_SOURCE_INDICES_NOT_SUPPORTED);
559+
context.addValidationError(REMOTE_SOURCE_AND_CROSS_PROJECT_INDICES_ARE_NOT_SUPPORTED);
559560
}
560561
listener.onResponse(context);
561562
}

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/common/validation/SourceDestValidatorTests.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@
6767
import static org.elasticsearch.xpack.core.common.validation.SourceDestValidator.DESTINATION_IN_SOURCE_VALIDATION;
6868
import static org.elasticsearch.xpack.core.common.validation.SourceDestValidator.DESTINATION_PIPELINE_MISSING_VALIDATION;
6969
import static org.elasticsearch.xpack.core.common.validation.SourceDestValidator.DESTINATION_SINGLE_INDEX_VALIDATION;
70+
import static org.elasticsearch.xpack.core.common.validation.SourceDestValidator.REMOTE_SOURCE_NOT_SUPPORTED_VALIDATION;
7071
import static org.elasticsearch.xpack.core.common.validation.SourceDestValidator.SOURCE_MISSING_VALIDATION;
72+
import static org.hamcrest.Matchers.containsString;
7173
import static org.hamcrest.Matchers.equalTo;
7274
import static org.mockito.Mockito.mock;
7375
import static org.mockito.Mockito.spy;
@@ -667,6 +669,51 @@ public void testRemoteSourceBasic() throws InterruptedException {
667669
);
668670
}
669671

672+
public void testRemoteSourceNotSupportedValidationWithLocalIndex() throws InterruptedException {
673+
Context context = spy(
674+
new SourceDestValidator.Context(
675+
CLUSTER_STATE,
676+
indexNameExpressionResolver,
677+
remoteClusterService,
678+
remoteClusterLicenseCheckerBasic,
679+
ingestService,
680+
new String[] { SOURCE_1 },
681+
"dest",
682+
null,
683+
"node_id",
684+
"license"
685+
)
686+
);
687+
688+
assertValidationWithContext(listener -> REMOTE_SOURCE_NOT_SUPPORTED_VALIDATION.validate(context, listener), c -> {
689+
assertNull(c.getValidationException());
690+
}, null);
691+
}
692+
693+
public void testRemoteSourceNotSupportedValidationWithRemoteIndex() throws InterruptedException {
694+
Context context = spy(
695+
new SourceDestValidator.Context(
696+
CLUSTER_STATE,
697+
indexNameExpressionResolver,
698+
remoteClusterService,
699+
remoteClusterLicenseCheckerBasic,
700+
ingestService,
701+
new String[] { REMOTE_BASIC + ":" + SOURCE_1 },
702+
"dest",
703+
null,
704+
"node_id",
705+
"license"
706+
)
707+
);
708+
709+
assertValidationWithContext(listener -> REMOTE_SOURCE_NOT_SUPPORTED_VALIDATION.validate(context, listener), c -> {
710+
assertThat(
711+
c.getValidationException().getMessage(),
712+
containsString("remote source and cross-project indices are not supported")
713+
);
714+
}, null);
715+
}
716+
670717
public void testRemoteSourcePlatinum() throws InterruptedException {
671718
final Context context = spy(
672719
new SourceDestValidator.Context(
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.ml.integration;
9+
10+
import org.elasticsearch.common.ValidationException;
11+
import org.elasticsearch.common.settings.Setting;
12+
import org.elasticsearch.common.settings.Settings;
13+
import org.elasticsearch.index.query.QueryBuilders;
14+
import org.elasticsearch.plugins.ClusterPlugin;
15+
import org.elasticsearch.plugins.Plugin;
16+
import org.elasticsearch.xpack.core.ml.action.PutDataFrameAnalyticsAction;
17+
import org.elasticsearch.xpack.core.ml.dataframe.DataFrameAnalyticsConfig;
18+
import org.elasticsearch.xpack.core.ml.dataframe.DataFrameAnalyticsDest;
19+
import org.elasticsearch.xpack.core.ml.dataframe.DataFrameAnalyticsSource;
20+
import org.elasticsearch.xpack.core.ml.dataframe.analyses.BoostedTreeParams;
21+
import org.elasticsearch.xpack.core.ml.dataframe.analyses.Classification;
22+
import org.elasticsearch.xpack.core.ml.utils.QueryProvider;
23+
import org.elasticsearch.xpack.ml.MlSingleNodeTestCase;
24+
25+
import java.io.IOException;
26+
import java.util.Collection;
27+
import java.util.Collections;
28+
import java.util.List;
29+
import java.util.stream.Stream;
30+
31+
import static org.hamcrest.Matchers.containsString;
32+
33+
public class DataframeCpsIT extends MlSingleNodeTestCase {
34+
@Override
35+
protected Settings nodeSettings() {
36+
return Settings.builder().put(super.nodeSettings()).put("serverless.cross_project.enabled", "true").build();
37+
}
38+
39+
@Override
40+
protected Collection<Class<? extends Plugin>> getPlugins() {
41+
return Stream.concat(super.getPlugins().stream(), Stream.of(CpsPlugin.class)).toList();
42+
}
43+
44+
public void testCrossProjectFailsForDataFrameAnalytics() throws IOException {
45+
var id = "test-cross-project-fails";
46+
var sourceIndex = "project1:" + id + "_source_index";
47+
var destIndex = id + "_results";
48+
49+
var config = new DataFrameAnalyticsConfig.Builder().setId(id)
50+
.setSource(
51+
new DataFrameAnalyticsSource(
52+
new String[] { sourceIndex },
53+
QueryProvider.fromParsedQuery(QueryBuilders.matchAllQuery()),
54+
null,
55+
Collections.emptyMap()
56+
)
57+
)
58+
.setDest(new DataFrameAnalyticsDest(destIndex, null))
59+
.setAnalysis(
60+
new Classification(
61+
"keyword-field",
62+
BoostedTreeParams.builder().setNumTopFeatureImportanceValues(1).build(),
63+
null,
64+
null,
65+
null,
66+
null,
67+
null,
68+
null,
69+
null
70+
)
71+
)
72+
.build();
73+
74+
var request = new PutDataFrameAnalyticsAction.Request(config);
75+
var response = client().execute(PutDataFrameAnalyticsAction.INSTANCE, request);
76+
var validationException = assertThrows(ValidationException.class, response::actionGet);
77+
assertThat(validationException.getMessage(), containsString("remote source and cross-project indices are not supported"));
78+
}
79+
80+
public static class CpsPlugin extends Plugin implements ClusterPlugin {
81+
public List<Setting<?>> getSettings() {
82+
return List.of(Setting.simpleString("serverless.cross_project.enabled", Setting.Property.NodeScope));
83+
}
84+
}
85+
}

x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityMlIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ public void testDataframeAnalyticsNotSupportForRemoteIndices() {
200200
""");
201201
final ResponseException e = expectThrows(ResponseException.class, () -> performRequestWithRemoteMlUser(putDataframeAnalytics));
202202
assertThat(e.getResponse().getStatusLine().getStatusCode(), equalTo(400));
203-
assertThat(e.getMessage(), containsString("remote source indices are not supported"));
203+
assertThat(e.getMessage(), containsString("remote source and cross-project indices are not supported"));
204204
}
205205

206206
private Response performRequestWithRemoteMlUser(final Request request) throws IOException {

x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/ml/data_frame_analytics_crud.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ setup:
432432
"Test put config with remote source index":
433433

434434
- do:
435-
catch: /.*Validation Failed.* remote source indices are not supported/
435+
catch: /.*Validation Failed.* remote source and cross-project indices are not supported/
436436
ml.put_data_frame_analytics:
437437
id: "config-with-missing-concrete-source-index"
438438
body: >

0 commit comments

Comments
 (0)