Skip to content

Commit ed8aebe

Browse files
authored
Add support for keystore secure settings to test clusters (#92554) (#92556)
Adds support for adding secure settings to node keystore using the new junit test clusters framework.
1 parent 8524372 commit ed8aebe

File tree

6 files changed

+57
-20
lines changed

6 files changed

+57
-20
lines changed

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public abstract class AbstractLocalSpecBuilder<T extends LocalSpecBuilder<?>> im
3030
private final Set<String> modules = new HashSet<>();
3131
private final Set<String> plugins = new HashSet<>();
3232
private final Set<FeatureFlag> features = new HashSet<>();
33+
private final Map<String, String> keystoreSettings = new HashMap<>();
3334
private DistributionType distributionType;
3435

3536
protected AbstractLocalSpecBuilder(AbstractLocalSpecBuilder<?> parent) {
@@ -123,6 +124,16 @@ Set<FeatureFlag> getFeatures() {
123124
return inherit(() -> parent.getFeatures(), features);
124125
}
125126

127+
@Override
128+
public T keystore(String key, String value) {
129+
this.keystoreSettings.put(key, value);
130+
return cast(this);
131+
}
132+
133+
public Map<String, String> getKeystoreSettings() {
134+
return inherit(() -> parent.getKeystoreSettings(), keystoreSettings);
135+
}
136+
126137
private <T> List<T> inherit(Supplier<List<T>> parent, List<T> child) {
127138
List<T> combinedList = new ArrayList<>();
128139
if (this.parent != null) {

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterSpecBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ private LocalNodeSpec build(LocalClusterSpec cluster) {
145145
getModules(),
146146
getPlugins(),
147147
Optional.ofNullable(getDistributionType()).orElse(DistributionType.INTEG_TEST),
148-
getFeatures()
148+
getFeatures(),
149+
getKeystoreSettings()
149150
);
150151
}
151152
}

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterFactory.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public synchronized void start() {
102102
initializeWorkingDirectory();
103103
writeConfiguration();
104104
createKeystore();
105+
addKeystoreSettings();
105106
configureSecurity();
106107
installPlugins();
107108
if (spec.getDistributionType() == DistributionType.INTEG_TEST) {
@@ -271,6 +272,27 @@ private void createKeystore() {
271272
}
272273
}
273274

275+
private void addKeystoreSettings() {
276+
spec.getKeystoreSettings().forEach((key, value) -> {
277+
try {
278+
ProcessUtils.exec(
279+
value,
280+
workingDir,
281+
OS.conditional(
282+
c -> c.onWindows(() -> distributionDir.resolve("bin").resolve("elasticsearch-keystore.bat"))
283+
.onUnix(() -> distributionDir.resolve("bin").resolve("elasticsearch-keystore"))
284+
),
285+
getEnvironmentVariables(),
286+
false,
287+
"add",
288+
key
289+
).waitFor();
290+
} catch (InterruptedException e) {
291+
throw new RuntimeException(e);
292+
}
293+
});
294+
}
295+
274296
private void configureSecurity() {
275297
if (spec.isSecurityEnabled()) {
276298
if (spec.getUsers().isEmpty() == false) {

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public static class LocalNodeSpec {
7878
private final Set<String> plugins;
7979
private final DistributionType distributionType;
8080
private final Set<FeatureFlag> features;
81+
private final Map<String, String> keystoreSettings;
8182

8283
public LocalNodeSpec(
8384
LocalClusterSpec cluster,
@@ -90,7 +91,8 @@ public LocalNodeSpec(
9091
Set<String> modules,
9192
Set<String> plugins,
9293
DistributionType distributionType,
93-
Set<FeatureFlag> features
94+
Set<FeatureFlag> features,
95+
Map<String, String> keystoreSettings
9496
) {
9597
this.cluster = cluster;
9698
this.name = name;
@@ -103,6 +105,7 @@ public LocalNodeSpec(
103105
this.plugins = plugins;
104106
this.distributionType = distributionType;
105107
this.features = features;
108+
this.keystoreSettings = keystoreSettings;
106109
}
107110

108111
public LocalClusterSpec getCluster() {
@@ -141,6 +144,10 @@ public Set<FeatureFlag> getFeatures() {
141144
return features;
142145
}
143146

147+
public Map<String, String> getKeystoreSettings() {
148+
return keystoreSettings;
149+
}
150+
144151
public boolean isSecurityEnabled() {
145152
return Boolean.parseBoolean(
146153
resolveSettings().getOrDefault("xpack.security.enabled", getVersion().onOrAfter("8.0.0") ? "true" : "false")

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,9 @@ interface LocalSpecBuilder<T extends LocalSpecBuilder<?>> {
6161
* Require feature to be enabled in the cluster.
6262
*/
6363
T feature(FeatureFlag feature);
64+
65+
/**
66+
* Adds a secure setting to the node keystore.
67+
*/
68+
T keystore(String key, String value);
6469
}

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/ProcessUtils.java

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.apache.logging.log4j.Logger;
1313

1414
import java.io.BufferedReader;
15+
import java.io.BufferedWriter;
1516
import java.io.IOException;
1617
import java.io.InputStream;
1718
import java.io.InputStreamReader;
@@ -47,7 +48,6 @@ public static Process exec(
4748
String... args
4849
) {
4950
Process process;
50-
Path inputFile = null;
5151

5252
if (Files.exists(executable) == false) {
5353
throw new IllegalArgumentException("Can't run executable: `" + executable + "` does not exist.");
@@ -68,37 +68,28 @@ public static Process exec(
6868
processBuilder.environment().clear();
6969
processBuilder.environment().putAll(environment);
7070

71-
if (input != null) {
72-
try {
73-
inputFile = Files.createTempFile("exec-input-", ".tmp");
74-
Files.writeString(inputFile, input);
75-
processBuilder.redirectInput(inputFile.toFile());
76-
} catch (IOException e) {
77-
throw new UncheckedIOException(e);
78-
}
79-
}
80-
8171
try {
8272
process = processBuilder.start();
83-
Process finalProcess = process;
8473

8574
startLoggingThread(
86-
finalProcess.getInputStream(),
75+
process.getInputStream(),
8776
inheritIO ? System.out::println : PROCESS_LOGGER::info,
8877
executable.getFileName().toString()
8978
);
9079

9180
startLoggingThread(
92-
finalProcess.getErrorStream(),
81+
process.getErrorStream(),
9382
inheritIO ? System.err::println : PROCESS_LOGGER::error,
9483
executable.getFileName().toString()
9584
);
85+
86+
if (input != null) {
87+
try (BufferedWriter writer = process.outputWriter()) {
88+
writer.write(input);
89+
}
90+
}
9691
} catch (IOException e) {
9792
throw new UncheckedIOException("Error executing process: " + executable.getFileName(), e);
98-
} finally {
99-
if (inputFile != null) {
100-
IOUtils.uncheckedDeleteWithRetry(inputFile);
101-
}
10293
}
10394

10495
return process;

0 commit comments

Comments
 (0)