Skip to content

Commit 0ee1272

Browse files
authored
Run Node deprecation checks locally (#38065)
At times, we need to check for usage of deprecated settings in settings which should not be returned by the NodeInfo API. This commit changes the deprecation info API to run all node checks locally so that these settings can be checked without exposing them via any externally accessible API.
1 parent 13cc7f1 commit 0ee1272

File tree

14 files changed

+600
-227
lines changed

14 files changed

+600
-227
lines changed

client/rest-high-level/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ integTestCluster {
105105
setting 'xpack.security.enabled', 'true'
106106
setting 'xpack.security.authc.token.enabled', 'true'
107107
// Truststore settings are not used since TLS is not enabled. Included for testing the get certificates API
108-
setting 'xpack.ssl.certificate_authorities', 'testnode.crt'
108+
setting 'xpack.security.http.ssl.certificate_authorities', 'testnode.crt'
109109
setting 'xpack.security.transport.ssl.truststore.path', 'testnode.jks'
110110
setting 'indices.lifecycle.poll_interval', '1000ms'
111111
keystoreSetting 'xpack.security.transport.ssl.truststore.secure_password', 'testnode'

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/deprecation/DeprecationInfoAction.java

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import org.elasticsearch.action.ActionResponse;
1212
import org.elasticsearch.action.IndicesRequest;
1313
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
14-
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
1514
import org.elasticsearch.action.support.IndicesOptions;
1615
import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder;
1716
import org.elasticsearch.action.support.master.MasterNodeReadRequest;
@@ -35,7 +34,6 @@
3534
import java.util.Map;
3635
import java.util.Objects;
3736
import java.util.Set;
38-
import java.util.function.BiFunction;
3937
import java.util.function.Function;
4038
import java.util.stream.Collectors;
4139

@@ -63,6 +61,23 @@ public static <T> List<DeprecationIssue> filterChecks(List<T> checks, Function<T
6361
return checks.stream().map(mapper).filter(Objects::nonNull).collect(Collectors.toList());
6462
}
6563

64+
private static List<DeprecationIssue> mergeNodeIssues(NodesDeprecationCheckResponse response) {
65+
Map<DeprecationIssue, List<String>> issueListMap = new HashMap<>();
66+
for (NodesDeprecationCheckAction.NodeResponse resp : response.getNodes()) {
67+
for (DeprecationIssue issue : resp.getDeprecationIssues()) {
68+
issueListMap.computeIfAbsent(issue, (key) -> new ArrayList<>()).add(resp.getNode().getName());
69+
}
70+
}
71+
72+
return issueListMap.entrySet().stream()
73+
.map(entry -> {
74+
DeprecationIssue issue = entry.getKey();
75+
String details = issue.getDetails() != null ? issue.getDetails() + " " : "";
76+
return new DeprecationIssue(issue.getLevel(), issue.getMessage(), issue.getUrl(),
77+
details + "(nodes impacted: " + entry.getValue() + ")");
78+
}).collect(Collectors.toList());
79+
}
80+
6681
@Override
6782
public RequestBuilder newRequestBuilder(ElasticsearchClient client) {
6883
return new RequestBuilder(client, this);
@@ -167,32 +182,29 @@ public int hashCode() {
167182
* this function will run through all the checks and build out the final list of issues that exist in the
168183
* cluster.
169184
*
170-
* @param nodesInfo The list of {@link NodeInfo} metadata objects for retrieving node-level information
171-
* @param nodesStats The list of {@link NodeStats} metadata objects for retrieving node-level information
172185
* @param state The cluster state
173186
* @param indexNameExpressionResolver Used to resolve indices into their concrete names
174187
* @param indices The list of index expressions to evaluate using `indexNameExpressionResolver`
175188
* @param indicesOptions The options to use when resolving and filtering which indices to check
176189
* @param datafeeds The ml datafeed configurations
177-
* @param clusterSettingsChecks The list of cluster-level checks
178-
* @param nodeSettingsChecks The list of node-level checks
190+
* @param nodeDeprecationResponse The response containing the deprecation issues found on each node
179191
* @param indexSettingsChecks The list of index-level checks that will be run across all specified
180192
* concrete indices
193+
* @param clusterSettingsChecks The list of cluster-level checks
181194
* @param mlSettingsCheck The list of ml checks
182195
* @return The list of deprecation issues found in the cluster
183196
*/
184-
public static DeprecationInfoAction.Response from(List<NodeInfo> nodesInfo, List<NodeStats> nodesStats, ClusterState state,
185-
IndexNameExpressionResolver indexNameExpressionResolver,
186-
String[] indices, IndicesOptions indicesOptions,
187-
List<DatafeedConfig> datafeeds,
188-
List<Function<ClusterState,DeprecationIssue>>clusterSettingsChecks,
189-
List<BiFunction<List<NodeInfo>, List<NodeStats>, DeprecationIssue>> nodeSettingsChecks,
190-
List<Function<IndexMetaData, DeprecationIssue>> indexSettingsChecks,
191-
List<Function<DatafeedConfig, DeprecationIssue>> mlSettingsCheck) {
197+
public static DeprecationInfoAction.Response from(ClusterState state,
198+
IndexNameExpressionResolver indexNameExpressionResolver,
199+
String[] indices, IndicesOptions indicesOptions,
200+
List<DatafeedConfig> datafeeds,
201+
NodesDeprecationCheckResponse nodeDeprecationResponse,
202+
List<Function<IndexMetaData, DeprecationIssue>> indexSettingsChecks,
203+
List<Function<ClusterState, DeprecationIssue>> clusterSettingsChecks,
204+
List<Function<DatafeedConfig, DeprecationIssue>> mlSettingsCheck) {
192205
List<DeprecationIssue> clusterSettingsIssues = filterChecks(clusterSettingsChecks,
193206
(c) -> c.apply(state));
194-
List<DeprecationIssue> nodeSettingsIssues = filterChecks(nodeSettingsChecks,
195-
(c) -> c.apply(nodesInfo, nodesStats));
207+
List<DeprecationIssue> nodeSettingsIssues = mergeNodeIssues(nodeDeprecationResponse);
196208
List<DeprecationIssue> mlSettingsIssues = new ArrayList<>();
197209
for (DatafeedConfig config : datafeeds) {
198210
mlSettingsIssues.addAll(filterChecks(mlSettingsCheck, (c) -> c.apply(config)));
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.core.deprecation;
8+
9+
import org.elasticsearch.action.Action;
10+
import org.elasticsearch.action.support.nodes.BaseNodeRequest;
11+
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
12+
import org.elasticsearch.action.support.nodes.NodesOperationRequestBuilder;
13+
import org.elasticsearch.client.ElasticsearchClient;
14+
import org.elasticsearch.cluster.node.DiscoveryNode;
15+
import org.elasticsearch.common.io.stream.StreamInput;
16+
import org.elasticsearch.common.io.stream.StreamOutput;
17+
18+
import java.io.IOException;
19+
import java.util.List;
20+
import java.util.Objects;
21+
22+
/**
23+
* Runs deprecation checks on each node. Deprecation checks are performed locally so that filtered settings
24+
* can be accessed in the deprecation checks.
25+
*/
26+
public class NodesDeprecationCheckAction extends Action<NodesDeprecationCheckRequest, NodesDeprecationCheckResponse,
27+
NodesDeprecationCheckAction.RequestBuilder> {
28+
public static final NodesDeprecationCheckAction INSTANCE = new NodesDeprecationCheckAction();
29+
public static final String NAME = "cluster:admin/xpack/deprecation/nodes/info";
30+
31+
private NodesDeprecationCheckAction() {
32+
super(NAME);
33+
}
34+
35+
@Override
36+
public RequestBuilder newRequestBuilder(ElasticsearchClient client) {
37+
return new RequestBuilder(client, INSTANCE, new NodesDeprecationCheckRequest());
38+
}
39+
40+
@Override
41+
public NodesDeprecationCheckResponse newResponse() {
42+
return new NodesDeprecationCheckResponse();
43+
}
44+
45+
public static class NodeRequest extends BaseNodeRequest {
46+
47+
NodesDeprecationCheckRequest request;
48+
49+
public NodeRequest() {}
50+
public NodeRequest(String nodeId, NodesDeprecationCheckRequest request) {
51+
super(nodeId);
52+
this.request = request;
53+
}
54+
55+
@Override
56+
public void readFrom(StreamInput in) throws IOException {
57+
super.readFrom(in);
58+
request = new NodesDeprecationCheckRequest();
59+
request.readFrom(in);
60+
}
61+
62+
@Override
63+
public void writeTo(StreamOutput out) throws IOException {
64+
super.writeTo(out);
65+
request.writeTo(out);
66+
}
67+
}
68+
69+
public static class NodeResponse extends BaseNodeResponse {
70+
private List<DeprecationIssue> deprecationIssues;
71+
72+
public NodeResponse() {
73+
super();
74+
}
75+
76+
public NodeResponse(DiscoveryNode node, List<DeprecationIssue> deprecationIssues) {
77+
super(node);
78+
this.deprecationIssues = deprecationIssues;
79+
}
80+
81+
@Override
82+
public void readFrom(StreamInput in) throws IOException {
83+
super.readFrom(in);
84+
deprecationIssues = in.readList(DeprecationIssue::new);
85+
}
86+
87+
@Override
88+
public void writeTo(StreamOutput out) throws IOException {
89+
super.writeTo(out);
90+
out.writeList(this.deprecationIssues);
91+
}
92+
93+
public static NodeResponse readNodeResponse(StreamInput in) throws IOException {
94+
NodeResponse nodeResponse = new NodeResponse();
95+
nodeResponse.readFrom(in);
96+
return nodeResponse;
97+
}
98+
99+
public List<DeprecationIssue> getDeprecationIssues() {
100+
return deprecationIssues;
101+
}
102+
103+
@Override
104+
public boolean equals(Object o) {
105+
if (this == o) return true;
106+
if (o == null || getClass() != o.getClass()) return false;
107+
NodeResponse that = (NodeResponse) o;
108+
return Objects.equals(getDeprecationIssues(), that.getDeprecationIssues())
109+
&& Objects.equals(getNode(), that.getNode());
110+
}
111+
112+
@Override
113+
public int hashCode() {
114+
return Objects.hash(getNode(), getDeprecationIssues());
115+
}
116+
}
117+
118+
public static class RequestBuilder extends NodesOperationRequestBuilder<NodesDeprecationCheckRequest,
119+
NodesDeprecationCheckResponse, RequestBuilder> {
120+
121+
protected RequestBuilder(ElasticsearchClient client,
122+
Action<NodesDeprecationCheckRequest, NodesDeprecationCheckResponse, RequestBuilder> action,
123+
NodesDeprecationCheckRequest request) {
124+
super(client, action, request);
125+
}
126+
}
127+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.core.deprecation;
8+
9+
import org.elasticsearch.action.support.nodes.BaseNodesRequest;
10+
import org.elasticsearch.common.io.stream.StreamInput;
11+
import org.elasticsearch.common.io.stream.StreamOutput;
12+
13+
import java.io.IOException;
14+
import java.util.Arrays;
15+
import java.util.Objects;
16+
17+
public class NodesDeprecationCheckRequest extends BaseNodesRequest<NodesDeprecationCheckRequest> {
18+
public NodesDeprecationCheckRequest() {}
19+
20+
public NodesDeprecationCheckRequest(String... nodesIds) {
21+
super(nodesIds);
22+
}
23+
24+
@Override
25+
public void readFrom(StreamInput in) throws IOException {
26+
super.readFrom(in);
27+
}
28+
29+
@Override
30+
public void writeTo(StreamOutput out) throws IOException {
31+
super.writeTo(out);
32+
}
33+
34+
@Override
35+
public int hashCode() {
36+
return Objects.hash((Object[]) this.nodesIds());
37+
}
38+
39+
@Override
40+
public boolean equals(Object obj) {
41+
if (this == obj) {
42+
return true;
43+
}
44+
if (obj == null || getClass() != obj.getClass()) {
45+
return false;
46+
}
47+
NodesDeprecationCheckRequest that = (NodesDeprecationCheckRequest) obj;
48+
return Arrays.equals(this.nodesIds(), that.nodesIds());
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.core.deprecation;
8+
9+
import org.elasticsearch.action.FailedNodeException;
10+
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
11+
import org.elasticsearch.cluster.ClusterName;
12+
import org.elasticsearch.common.io.stream.StreamInput;
13+
import org.elasticsearch.common.io.stream.StreamOutput;
14+
15+
import java.io.IOException;
16+
import java.util.List;
17+
import java.util.Objects;
18+
19+
public class NodesDeprecationCheckResponse extends BaseNodesResponse<NodesDeprecationCheckAction.NodeResponse> {
20+
21+
public NodesDeprecationCheckResponse() {}
22+
23+
public NodesDeprecationCheckResponse(ClusterName clusterName,
24+
List<NodesDeprecationCheckAction.NodeResponse> nodes,
25+
List<FailedNodeException> failures) {
26+
super(clusterName, nodes, failures);
27+
}
28+
29+
@Override
30+
protected List<NodesDeprecationCheckAction.NodeResponse> readNodesFrom(StreamInput in) throws IOException {
31+
return in.readList(NodesDeprecationCheckAction.NodeResponse::readNodeResponse);
32+
}
33+
34+
@Override
35+
protected void writeNodesTo(StreamOutput out, List<NodesDeprecationCheckAction.NodeResponse> nodes) throws IOException {
36+
out.writeStreamableList(nodes);
37+
}
38+
39+
@Override
40+
public boolean equals(Object o) {
41+
if (this == o) return true;
42+
if (o == null || getClass() != o.getClass()) return false;
43+
NodesDeprecationCheckResponse that = (NodesDeprecationCheckResponse) o;
44+
return Objects.equals(getClusterName(), that.getClusterName())
45+
&& Objects.equals(getNodes(), that.getNodes())
46+
&& Objects.equals(failures(), that.failures());
47+
}
48+
49+
@Override
50+
public int hashCode() {
51+
return Objects.hash(getClusterName(), getNodes(), failures());
52+
}
53+
}

0 commit comments

Comments
 (0)