diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java index 7dfc668fac036..e59bc691b92eb 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java @@ -30,6 +30,7 @@ public abstract class AbstractLocalSpecBuilder> im private final Set modules = new HashSet<>(); private final Set plugins = new HashSet<>(); private final Set features = new HashSet<>(); + private final Map keystoreSettings = new HashMap<>(); private DistributionType distributionType; protected AbstractLocalSpecBuilder(AbstractLocalSpecBuilder parent) { @@ -123,6 +124,16 @@ Set getFeatures() { return inherit(() -> parent.getFeatures(), features); } + @Override + public T keystore(String key, String value) { + this.keystoreSettings.put(key, value); + return cast(this); + } + + public Map getKeystoreSettings() { + return inherit(() -> parent.getKeystoreSettings(), keystoreSettings); + } + private List inherit(Supplier> parent, List child) { List combinedList = new ArrayList<>(); if (this.parent != null) { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterSpecBuilder.java index 20e06fcb8e9b4..6e93ad14cb4bc 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterSpecBuilder.java @@ -145,7 +145,8 @@ private LocalNodeSpec build(LocalClusterSpec cluster) { getModules(), getPlugins(), Optional.ofNullable(getDistributionType()).orElse(DistributionType.INTEG_TEST), - getFeatures() + getFeatures(), + getKeystoreSettings() ); } } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterFactory.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterFactory.java index efb1da2da7b8c..3c1f5a81cdd91 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterFactory.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterFactory.java @@ -102,6 +102,7 @@ public synchronized void start() { initializeWorkingDirectory(); writeConfiguration(); createKeystore(); + addKeystoreSettings(); configureSecurity(); installPlugins(); if (spec.getDistributionType() == DistributionType.INTEG_TEST) { @@ -271,6 +272,27 @@ private void createKeystore() { } } + private void addKeystoreSettings() { + spec.getKeystoreSettings().forEach((key, value) -> { + try { + ProcessUtils.exec( + value, + workingDir, + OS.conditional( + c -> c.onWindows(() -> distributionDir.resolve("bin").resolve("elasticsearch-keystore.bat")) + .onUnix(() -> distributionDir.resolve("bin").resolve("elasticsearch-keystore")) + ), + getEnvironmentVariables(), + false, + "add", + key + ).waitFor(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + } + private void configureSecurity() { if (spec.isSecurityEnabled()) { if (spec.getUsers().isEmpty() == false) { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java index 223326f4f0a66..9065db9c2f550 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java @@ -78,6 +78,7 @@ public static class LocalNodeSpec { private final Set plugins; private final DistributionType distributionType; private final Set features; + private final Map keystoreSettings; public LocalNodeSpec( LocalClusterSpec cluster, @@ -90,7 +91,8 @@ public LocalNodeSpec( Set modules, Set plugins, DistributionType distributionType, - Set features + Set features, + Map keystoreSettings ) { this.cluster = cluster; this.name = name; @@ -103,6 +105,7 @@ public LocalNodeSpec( this.plugins = plugins; this.distributionType = distributionType; this.features = features; + this.keystoreSettings = keystoreSettings; } public LocalClusterSpec getCluster() { @@ -141,6 +144,10 @@ public Set getFeatures() { return features; } + public Map getKeystoreSettings() { + return keystoreSettings; + } + public boolean isSecurityEnabled() { return Boolean.parseBoolean( resolveSettings().getOrDefault("xpack.security.enabled", getVersion().onOrAfter("8.0.0") ? "true" : "false") diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java index e78079502d21c..5be895c03d16c 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java @@ -61,4 +61,9 @@ interface LocalSpecBuilder> { * Require feature to be enabled in the cluster. */ T feature(FeatureFlag feature); + + /** + * Adds a secure setting to the node keystore. + */ + T keystore(String key, String value); } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/ProcessUtils.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/ProcessUtils.java index 2e41e89a3ecab..e8f88c513bdd0 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/ProcessUtils.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/ProcessUtils.java @@ -12,6 +12,7 @@ import org.apache.logging.log4j.Logger; import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -47,7 +48,6 @@ public static Process exec( String... args ) { Process process; - Path inputFile = null; if (Files.exists(executable) == false) { throw new IllegalArgumentException("Can't run executable: `" + executable + "` does not exist."); @@ -68,37 +68,28 @@ public static Process exec( processBuilder.environment().clear(); processBuilder.environment().putAll(environment); - if (input != null) { - try { - inputFile = Files.createTempFile("exec-input-", ".tmp"); - Files.writeString(inputFile, input); - processBuilder.redirectInput(inputFile.toFile()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - try { process = processBuilder.start(); - Process finalProcess = process; startLoggingThread( - finalProcess.getInputStream(), + process.getInputStream(), inheritIO ? System.out::println : PROCESS_LOGGER::info, executable.getFileName().toString() ); startLoggingThread( - finalProcess.getErrorStream(), + process.getErrorStream(), inheritIO ? System.err::println : PROCESS_LOGGER::error, executable.getFileName().toString() ); + + if (input != null) { + try (BufferedWriter writer = process.outputWriter()) { + writer.write(input); + } + } } catch (IOException e) { throw new UncheckedIOException("Error executing process: " + executable.getFileName(), e); - } finally { - if (inputFile != null) { - IOUtils.uncheckedDeleteWithRetry(inputFile); - } } return process;