diff --git a/.github/workflows/ubuntu-master.yml b/.github/workflows/ubuntu-master.yml index f09cfc3..f6a42c5 100644 --- a/.github/workflows/ubuntu-master.yml +++ b/.github/workflows/ubuntu-master.yml @@ -37,4 +37,5 @@ jobs: TARANTOOL_SERVER_USER: root TARANTOOL_SERVER_GROUP: root DOWNLOAD_SDK_URI: ${{ secrets.DOWNLOAD_SDK_URI }} + SDK_VERSION: tarantool-enterprise-sdk-nogc64-2.10.7-0-r563.linux.x86_64 run: mvn -B test -P enterprise --file pom.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 987f60f..b4f8e20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ - Bump testcontainers to 1.18.0 - Move rocks building in build phase - Use "addExposedPorts" instead of "withExposedPorts" +- **[breaking change]** Remove io.tarantool.cartridge-driver dependency +- **[breaking change]** Update executeScript and executeCommand methods to execute code via execInContainer + (now it returns **yaml** string in Container.ExecResult instead of CompletableFuture) +- Add executeScriptDecoded and executeCommandDecoded methods to return parsed yaml not string. +- Add SslContext class +- Add withSslContext method to TarantoolContainer and TarantoolCartridgeContainer. +- Update org.yaml.snakeyaml to 2.0 version. ## [0.5.4] - 2023-03-31 - Use tarantool image as base instead of centos in cartridge container diff --git a/README.md b/README.md index e46151e..79b17f8 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,9 @@ public class SomeTest { @BeforeAll public void setUp() { // Run some setup commands - container.executeCommand("return 1, 2").get(); + container.executeCommand("return 1, 2"); // Or execute a script - container.executeScript("org/testcontainers/containers/test.lua").get(); + container.executeScript("org/testcontainers/containers/test.lua"); } @Test @@ -72,7 +72,7 @@ public class SomeTest { ... // Execute some commands in Tarantool instance for verification - List result = container.executeCommand("return 1, 2").get(); + List result = container.executeCommand("return 1, 2"); ... } ... @@ -181,7 +181,7 @@ public class SomeOtherTest { // Use the created container in tests public void testFoo() { // Execute Lua commands in the router instance - List result = container.executeCommand("return profile_get(...)", 1).get(); + List result = container.executeCommand("return profile_get(1)"); // Instantiate a client connected to the router node TarantoolCredentials credentials = new SimpleTarantoolCredentials(getRouterUsername(), getRouterPassword()); diff --git a/pom.xml b/pom.xml index d18f5ca..635cd7a 100644 --- a/pom.xml +++ b/pom.xml @@ -81,15 +81,10 @@ testcontainers ${testcontainers.version} - - io.tarantool - cartridge-driver - 0.9.1 - org.yaml snakeyaml - 1.33 + 2.0 org.slf4j diff --git a/src/main/java/org/testcontainers/containers/SslContext.java b/src/main/java/org/testcontainers/containers/SslContext.java new file mode 100644 index 0000000..e81b924 --- /dev/null +++ b/src/main/java/org/testcontainers/containers/SslContext.java @@ -0,0 +1,30 @@ +package org.testcontainers.containers; + +public class SslContext { + private String keyFile; + private String certFile; + + private SslContext() { + } + + private SslContext(String keyFile, String certFile) { + this.keyFile = keyFile; + this.certFile = certFile; + } + + public static SslContext getSslContext(){ + return new SslContext(); + } + + public static SslContext getSslContext(String keyFile, String certFile){ + return new SslContext(keyFile, certFile); + } + + String getKeyFile() { + return this.keyFile; + } + + String getCertFile() { + return this.certFile; + } +} diff --git a/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java b/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java index 4a01f74..88cccbb 100644 --- a/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java +++ b/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java @@ -1,7 +1,6 @@ package org.testcontainers.containers; import com.github.dockerjava.api.command.InspectContainerResponse; -import io.tarantool.driver.exceptions.TarantoolConnectionException; import org.testcontainers.containers.exceptions.CartridgeTopologyException; import org.testcontainers.images.builder.ImageFromDockerfile; @@ -13,7 +12,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.function.Supplier; @@ -83,6 +81,9 @@ * specified in the http_port options, will be exposed. * * @author Alexey Kuzin + * @author Artyom Dubinin + * @author Ivan Dneprov + * */ public class TarantoolCartridgeContainer extends GenericContainer implements TarantoolContainerOperations { @@ -120,6 +121,7 @@ public class TarantoolCartridgeContainer extends GenericContainer res = executeScript(topologyConfigurationFile).get(); + List res = executeScriptDecoded(topologyConfigurationFile); if (res.size() >= 2 && res.get(1) != null && res.get(1) instanceof Map) { HashMap error = ((HashMap) res.get(1)); // that means topology already exists @@ -517,10 +524,6 @@ private boolean setupTopology() { if (e.getCause() instanceof TimeoutException) { return true; // Do nothing, the cluster is reloading - } else if (e.getCause() instanceof TarantoolConnectionException) { - // Probably cluster is not ready - logger().error("Failed to setup topology: {}", e.getMessage()); - return false; } } else { throw new CartridgeTopologyException(e); @@ -546,7 +549,7 @@ private void retryingSetupTopology() { private void bootstrapVshard() { try { - executeCommand(VSHARD_BOOTSTRAP_COMMAND).get(); + executeCommand(VSHARD_BOOTSTRAP_COMMAND); } catch (Exception e) { logger().error("Failed to bootstrap vshard cluster", e); throw new RuntimeException(e); @@ -594,10 +597,10 @@ private void waitUntilTrue(int secondsToWait, Supplier waitFunc) { private boolean routerIsUp() { String healthyCmd = " local cartridge = package.loaded['cartridge']" + - " return assert(cartridge ~= nil)"; + " return cartridge ~= nil"; try { - List result = executeCommand(healthyCmd).get(); - return (Boolean) result.get(0); + List result = executeCommandDecoded(healthyCmd); + return result.get(0).getClass() == Boolean.class && (Boolean) result.get(0); } catch (Exception e) { logger().warn("Error while waiting for router instance to be up: " + e.getMessage()); return false; @@ -606,10 +609,10 @@ private boolean routerIsUp() { private boolean isCartridgeHealthy() { String healthyCmd = " local cartridge = package.loaded['cartridge']" + - " return assert(cartridge) and assert(cartridge.is_healthy())"; + " return cartridge ~= nil and cartridge.is_healthy()"; try { - List result = executeCommand(healthyCmd).get(); - return (Boolean) result.get(0); + List result = executeCommandDecoded(healthyCmd); + return result.get(0).getClass() == Boolean.class && (Boolean) result.get(0); } catch (Exception e) { logger().warn("Error while waiting for cartridge healthy state: " + e.getMessage()); return false; @@ -617,12 +620,22 @@ private boolean isCartridgeHealthy() { } @Override - public CompletableFuture> executeScript(String scriptResourcePath) throws Exception { - return clientHelper.executeScript(scriptResourcePath); + public ExecResult executeScript(String scriptResourcePath) throws Exception { + return clientHelper.executeScript(scriptResourcePath, this.sslContext); + } + + @Override + public T executeScriptDecoded(String scriptResourcePath) throws Exception { + return clientHelper.executeScriptDecoded(scriptResourcePath, this.sslContext); + } + + @Override + public ExecResult executeCommand(String command) throws Exception { + return clientHelper.executeCommand(command, this.sslContext); } @Override - public CompletableFuture> executeCommand(String command, Object... arguments) throws Exception { - return clientHelper.executeCommand(command, arguments); + public T executeCommandDecoded(String command) throws Exception { + return clientHelper.executeCommandDecoded(command, this.sslContext); } } diff --git a/src/main/java/org/testcontainers/containers/TarantoolContainer.java b/src/main/java/org/testcontainers/containers/TarantoolContainer.java index 2065ab2..3bdfef5 100644 --- a/src/main/java/org/testcontainers/containers/TarantoolContainer.java +++ b/src/main/java/org/testcontainers/containers/TarantoolContainer.java @@ -1,13 +1,10 @@ package org.testcontainers.containers; import com.github.dockerjava.api.command.InspectContainerResponse; -import io.tarantool.driver.api.TarantoolClientBuilder; import org.testcontainers.containers.wait.strategy.Wait; import java.net.URL; import java.nio.file.Paths; -import java.util.List; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import static org.testcontainers.containers.PathUtils.normalizePath; @@ -16,6 +13,7 @@ * Sets up a Tarantool instance and provides API for configuring it. * * @author Alexey Kuzin + * @author Ivan Dneprov */ public class TarantoolContainer extends GenericContainer implements TarantoolContainerOperations { @@ -45,6 +43,7 @@ public class TarantoolContainer extends GenericContainer private String scriptFileName = SCRIPT_FILENAME; private String instanceDir = INSTANCE_DIR; private boolean useFixedPorts = false; + private SslContext sslContext; private final TarantoolContainerClientHelper clientHelper; @@ -55,15 +54,6 @@ public TarantoolContainer() { this(String.format("%s:%s", TARANTOOL_IMAGE, DEFAULT_IMAGE_VERSION)); } - /** - * Constructor for {@link TarantoolContainer} - * - * @param clientBuilder client builder with custom client settings for setting up container - */ - public TarantoolContainer(TarantoolClientBuilder clientBuilder) { - this(String.format("%s:%s", TARANTOOL_IMAGE, DEFAULT_IMAGE_VERSION), clientBuilder); - } - /** * Constructor for {@link TarantoolContainer} * @@ -74,18 +64,6 @@ public TarantoolContainer(String dockerImageName) { clientHelper = new TarantoolContainerClientHelper(this); } - /** - * Constructor for {@link TarantoolContainer} - * - * @param dockerImageName docker image name for container creating - * @param clientBuilder client builder with custom client settings for setting up container - */ - public TarantoolContainer(String dockerImageName, - TarantoolClientBuilder clientBuilder) { - super(dockerImageName); - clientHelper = new TarantoolContainerClientHelper(this, clientBuilder); - } - /** * Constructor for {@link TarantoolContainer} * @@ -96,18 +74,6 @@ public TarantoolContainer(TarantoolImageParams tarantoolImageParams) { clientHelper = new TarantoolContainerClientHelper(this); } - /** - * Constructor for {@link TarantoolContainer} - * - * @param tarantoolImageParams params for cached image creating - * @param clientBuilder client builder with custom client settings for setting up container - */ - public TarantoolContainer(TarantoolImageParams tarantoolImageParams, - TarantoolClientBuilder clientBuilder) { - super(TarantoolContainerImageHelper.getImage(tarantoolImageParams)); - clientHelper = new TarantoolContainerClientHelper(this, clientBuilder); - } - /** * Constructor for {@link TarantoolContainer} * @@ -118,18 +84,6 @@ public TarantoolContainer(Future image) { clientHelper = new TarantoolContainerClientHelper(this); } - /** - * Constructor for {@link TarantoolContainer} - * - * @param image future with image name - * @param clientBuilder client builder with custom client settings for setting up container - */ - public TarantoolContainer(Future image, - TarantoolClientBuilder clientBuilder) { - super(image); - clientHelper = new TarantoolContainerClientHelper(this, clientBuilder); - } - /** * Use fixed ports binding. * Defaults to false. @@ -223,6 +177,20 @@ public TarantoolContainer withPassword(String password) { return this; } + + /** + * Specify SSL as connection transport and path to key and cert files inside your container for mTLS connection. + * Warning! SSL must be set as the default transport in your Tarantool cluster. + * Supported only in Tarantool Enterprise. + * + * @return this container instance + */ + public TarantoolContainer withSslContext(SslContext sslContext) { + checkNotRunning(); + this.sslContext = sslContext; + return this; + } + /** * Change the log_level setting on the Tarantool instance * @@ -233,7 +201,7 @@ public TarantoolContainer withLogLevel(TarantoolLogLevel logLevel) { this.logLevel = logLevel; if (isRunning()) { try { - executeCommand(logLevel.toCommand()).get(); + executeCommand(logLevel.toCommand()); } catch (Exception e) { logger().error(String.format("Failed to set log_level to %s", logLevel.toString()), e); throw new RuntimeException(e); @@ -256,7 +224,7 @@ public TarantoolContainer withMemtxMemory(Integer memtxMemory) { this.memtxMemory = memtxMemory; if (isRunning()) { try { - executeCommand(String.format("box.cfg{memtx_memory=%d}", memtxMemory)).get(); + executeCommand(String.format("box.cfg{memtx_memory=%d}", memtxMemory)); } catch (Exception e) { logger().error(String.format("Failed to set memtx_memory to %d", memtxMemory), e); throw new RuntimeException(e); @@ -300,6 +268,11 @@ public String getInstanceDir() { return instanceDir; } + @Override + public int getInternalPort() { + return port; + } + /** * Specify the server init script file name * @@ -390,12 +363,22 @@ protected void containerIsStopping(InspectContainerResponse containerInfo) { } @Override - public CompletableFuture> executeScript(String scriptResourcePath) throws Exception { - return clientHelper.executeScript(scriptResourcePath); + public Container.ExecResult executeScript(String scriptResourcePath) throws Exception { + return clientHelper.executeScript(scriptResourcePath, this.sslContext); + } + + @Override + public T executeScriptDecoded(String scriptResourcePath) throws Exception { + return clientHelper.executeScriptDecoded(scriptResourcePath, this.sslContext); + } + + @Override + public Container.ExecResult executeCommand(String command) throws Exception { + return clientHelper.executeCommand(command, this.sslContext); } @Override - public CompletableFuture> executeCommand(String command, Object... arguments) throws Exception { - return clientHelper.executeCommand(command, arguments); + public T executeCommandDecoded(String command) throws Exception { + return clientHelper.executeCommandDecoded(command, this.sslContext); } } diff --git a/src/main/java/org/testcontainers/containers/TarantoolContainerClientHelper.java b/src/main/java/org/testcontainers/containers/TarantoolContainerClientHelper.java index cfaa559..3a40e70 100644 --- a/src/main/java/org/testcontainers/containers/TarantoolContainerClientHelper.java +++ b/src/main/java/org/testcontainers/containers/TarantoolContainerClientHelper.java @@ -1,18 +1,11 @@ package org.testcontainers.containers; -import io.tarantool.driver.api.TarantoolClient; -import io.tarantool.driver.api.TarantoolClientBuilder; -import io.tarantool.driver.api.TarantoolClientFactory; -import io.tarantool.driver.api.TarantoolResult; -import io.tarantool.driver.api.retry.TarantoolRequestRetryPolicies; -import io.tarantool.driver.api.tuple.TarantoolTuple; import org.testcontainers.utility.MountableFile; +import org.yaml.snakeyaml.Yaml; +import java.io.IOException; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.ExecutionException; import static org.testcontainers.containers.PathUtils.normalizePath; @@ -20,69 +13,126 @@ * Provides a wrapper around a Tarantool client with helper methods * * @author Alexey Kuzin + * @author Artyom Dubinin + * @author Ivan Dneprov */ public final class TarantoolContainerClientHelper { private static final String TMP_DIR = "/tmp"; + private static final Yaml yaml = new Yaml(); private final TarantoolContainerOperations> container; - private final AtomicReference>> clientHolder = - new AtomicReference<>(); - private final TarantoolClientBuilder clientBuilder; + private final String EXECUTE_SCRIPT_ERROR_TEMPLATE = + "Executed script %s with exit code %d, stderr: \"%s\", stdout: \"%s\""; + private static final String EXECUTE_COMMAND_ERROR_TEMPLATE = + "Executed command \"%s\" with exit code %d, stderr: \"%s\", stdout: \"%s\""; + private static final String MTLS_COMMAND_TEMPLATE = + "echo \" " + + " print(require('yaml').encode( " + + " {require('net.box').connect( " + + " { uri='%s:%d', params = { transport='ssl', ssl_key_file = '%s', ssl_cert_file = '%s' }}, " + + " { user = '%s', password = '%s' } " + + " ):eval('%s')}) " + + " ); " + + " os.exit(); " + + "\" | tarantool"; + private static final String SSL_COMMAND_TEMPLATE = + "echo \" " + + " print(require('yaml').encode( " + + " {require('net.box').connect( " + + " { uri='%s:%d', params = { transport='ssl' }}, " + + " { user = '%s', password = '%s' } " + + " ):eval('%s')}) " + + " ); " + + " os.exit(); " + + "\" | tarantool"; + private static final String COMMAND_TEMPLATE = "echo \" " + + " print(require('yaml').encode( " + + " {require('net.box').connect( " + + " { uri='%s:%d' }, " + + " { user = '%s', password = '%s' } " + + " ):eval('%s')}) " + + " ); " + + " os.exit(); " + + "\" | tarantool"; TarantoolContainerClientHelper(TarantoolContainerOperations> container) { this.container = container; - this.clientBuilder = TarantoolClientFactory.createClient() - .withRequestTimeout(5000) - .withRetryingByNumberOfAttempts(15, - TarantoolRequestRetryPolicies.retryNetworkErrors(), - b -> b.withDelay(100)); } + + public Container.ExecResult executeScript(String scriptResourcePath, SslContext sslContext) throws IOException, InterruptedException { + if (!container.isRunning()) { + throw new IllegalStateException("Cannot execute scripts in stopped container"); + } - TarantoolContainerClientHelper(TarantoolContainerOperations> container, - TarantoolClientBuilder clientBuilder) { - this.container = container; - this.clientBuilder = clientBuilder; + String scriptName = Paths.get(scriptResourcePath).getFileName().toString(); + String containerPath = normalizePath(Paths.get(TMP_DIR, scriptName)); + container.copyFileToContainer(MountableFile.forClasspathResource(scriptResourcePath), containerPath); + return executeCommand(String.format("return dofile('%s')", containerPath), sslContext); } - private TarantoolClient> createClient() { - return clientBuilder - .withCredentials(container.getUsername(), container.getPassword()) - .withAddress(container.getHost(), container.getPort()) - .build(); - } + public T executeScriptDecoded(String scriptResourcePath, SslContext sslContext) throws IOException, InterruptedException, ExecutionException { + Container.ExecResult result = executeScript(scriptResourcePath, sslContext); - /** - * Configure or return an already configured client connected to a Cartridge router - * - * @return a configured client - */ - public TarantoolClient> getClient() { - if (!container.isRunning()) { - throw new IllegalStateException("Cannot connect to Tarantool instance in a stopped container"); - } - if (clientHolder.get() == null) { - clientHolder.compareAndSet(null, createClient()); + if (result.getExitCode() != 0) { + + if (result.getExitCode() == 3 || result.getExitCode() == 1) { + throw new ExecutionException(String.format(EXECUTE_SCRIPT_ERROR_TEMPLATE, + scriptResourcePath, result.getExitCode(), + result.getStderr(), result.getStdout()), + new Throwable()); + } + + throw new IllegalStateException(String.format(EXECUTE_SCRIPT_ERROR_TEMPLATE, + scriptResourcePath, result.getExitCode(), + result.getStderr(), result.getStdout())); } - return clientHolder.get(); + + return yaml.load(result.getStdout()); } - public CompletableFuture> executeScript(String scriptResourcePath) { + public Container.ExecResult executeCommand(String command, SslContext sslContext) throws IOException, InterruptedException { if (!container.isRunning()) { - throw new IllegalStateException("Cannot execute scripts in stopped container"); + throw new IllegalStateException("Cannot execute commands in stopped container"); } - String scriptName = Paths.get(scriptResourcePath).getFileName().toString(); - String containerPath = normalizePath(Paths.get(TMP_DIR, scriptName)); - container.copyFileToContainer(MountableFile.forClasspathResource(scriptResourcePath), containerPath); - return executeCommand(String.format("return dofile('%s')", containerPath)); + command = command.replace("\"", "\\\""); + command = command.replace("\'", "\\\'"); + + String bashCommand; + if (sslContext == null) { // No SSL + bashCommand = String.format(COMMAND_TEMPLATE, + container.getHost(), container.getInternalPort(), + container.getUsername(), container.getPassword(), + command + ); + } else if (sslContext.getKeyFile() != null && sslContext.getCertFile() != null) { // mTLS + bashCommand = String.format(MTLS_COMMAND_TEMPLATE, + container.getHost(), container.getInternalPort(), + sslContext.getKeyFile(), sslContext.getCertFile(), + container.getUsername(), container.getPassword(), + command + ); + } else { // SSL + bashCommand = String.format(SSL_COMMAND_TEMPLATE, + container.getHost(), container.getInternalPort(), + container.getUsername(), container.getPassword(), + command + ); + } + + return container.execInContainer("sh", "-c", bashCommand); } - public CompletableFuture> executeCommand(String command, Object... arguments) { - if (!container.isRunning()) { - throw new IllegalStateException("Cannot execute commands in stopped container"); + public T executeCommandDecoded(String command, SslContext sslContext) throws IOException, InterruptedException { + Container.ExecResult result = executeCommand(command, sslContext); + + if (result.getExitCode() != 0) { + throw new IllegalStateException(String.format(EXECUTE_COMMAND_ERROR_TEMPLATE, + command, result.getExitCode(), result.getStderr(), result.getStdout())); } - return getClient().eval(command, Arrays.asList(arguments)); + return yaml.load(result.getStdout()); } + } diff --git a/src/main/java/org/testcontainers/containers/TarantoolContainerOperations.java b/src/main/java/org/testcontainers/containers/TarantoolContainerOperations.java index 68c847a..65c1910 100644 --- a/src/main/java/org/testcontainers/containers/TarantoolContainerOperations.java +++ b/src/main/java/org/testcontainers/containers/TarantoolContainerOperations.java @@ -7,6 +7,7 @@ * Represents operations available on a Tarantool Container * * @author Alexey Kuzin + * @author Ivan Dneprov */ public interface TarantoolContainerOperations> extends Container { /** @@ -44,6 +45,13 @@ public interface TarantoolContainerOperations> extends Co */ String getInstanceDir(); + /** + * Get the Tarantool server internal port for client connections + * + * @return a port + */ + int getInternalPort(); + /** * Execute a local script in the Tarantool instance. The path must be classpath-relative. * `dofile()` function is executed internally, so possible exceptions will be caught as the client exceptions. @@ -52,15 +60,33 @@ public interface TarantoolContainerOperations> extends Co * @return script execution result * @throws Exception if failed to connect to the instance or execution fails */ - CompletableFuture> executeScript(String scriptResourcePath) throws Exception; + Container.ExecResult executeScript(String scriptResourcePath) throws Exception; + + /** + * Execute a local script in the Tarantool instance. The path must be classpath-relative. + * `dofile()` function is executed internally, so possible exceptions will be caught as the client exceptions. + * + * @param scriptResourcePath the classpath resource path to a script + * @return script execution result in {@link Container.ExecResult} + * @throws Exception if failed to connect to the instance or execution fails + */ + T executeScriptDecoded(String scriptResourcePath) throws Exception; /** * Execute a command in the Tarantool instance. Example of a command: `return 1 + 2, 'foo'` * * @param command a valid Lua command or a sequence of Lua commands - * @param arguments command arguments * @return command execution result * @throws Exception if failed to connect to the instance or execution fails */ - CompletableFuture> executeCommand(String command, Object... arguments) throws Exception; + Container.ExecResult executeCommand(String command) throws Exception; + + /** + * Execute a command in the Tarantool instance. Example of a command: `return 1 + 2, 'foo'` + * + * @param command a valid Lua command or a sequence of Lua commands + * @return command execution result in {@link Container.ExecResult} + * @throws Exception if failed to connect to the instance or execution fails + */ + T executeCommandDecoded(String command) throws Exception; } diff --git a/src/test/java/org/testcontainers/containers/CartridgeContainerTestUtils.java b/src/test/java/org/testcontainers/containers/CartridgeContainerTestUtils.java index ad8078a..fc36c76 100644 --- a/src/test/java/org/testcontainers/containers/CartridgeContainerTestUtils.java +++ b/src/test/java/org/testcontainers/containers/CartridgeContainerTestUtils.java @@ -1,12 +1,12 @@ package org.testcontainers.containers; -import java.util.Arrays; import java.util.List; import static org.junit.Assert.assertEquals; /** * @author Vladimir Rogach + * @author Ivan Dneprov */ public class CartridgeContainerTestUtils { @@ -15,9 +15,9 @@ private CartridgeContainerTestUtils() { static public void executeProfileReplaceSmokeTest(TarantoolCartridgeContainer container) throws Exception { container.executeCommand( - "return profile_replace(...)", Arrays.asList(1, "Ivanov Ivan Ivanovich", 33, 100500)).get(); + "return profile_replace({1, \"Ivanov Ivan Ivanovich\", 33, 100500})"); - List result = container.executeCommand("return profile_get(...)", 1).get(); + List result = container.executeCommandDecoded("return profile_get(1)"); assertEquals(1, result.size()); assertEquals(33, ((List) result.get(0)).get(3)); } diff --git a/src/test/java/org/testcontainers/containers/TarantoolCartridgeBootstrapFromYamlTest.java b/src/test/java/org/testcontainers/containers/TarantoolCartridgeBootstrapFromYamlTest.java index a12611c..94682e7 100644 --- a/src/test/java/org/testcontainers/containers/TarantoolCartridgeBootstrapFromYamlTest.java +++ b/src/test/java/org/testcontainers/containers/TarantoolCartridgeBootstrapFromYamlTest.java @@ -5,15 +5,16 @@ import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.testcontainers.utility.MountableFile; +import org.testcontainers.containers.Container.ExecResult; import java.time.Duration; -import java.util.List; import static org.junit.Assert.assertEquals; /** * @author Alexey Kuzin + * @author Valdimir Rogach + * @author Ivan Dneprov */ @Testcontainers public class TarantoolCartridgeBootstrapFromYamlTest { @@ -37,7 +38,10 @@ public void test_StaticClusterContainer_StartsSuccessfully_ifFilesAreCopied() th @Test public void test_migrator_executesOk() throws Exception { - List result = container.executeCommand("return require('migrator').up()").get(); - assertEquals("001_ddl.lua", ((List)result.get(0)).get(0)); + ExecResult result = container.executeCommand("return require('migrator').up()"); + assertEquals("---\n" + + "- ['001_ddl.lua']\n" + + "...\n" + + "\n", result.getStdout()); } } diff --git a/src/test/java/org/testcontainers/containers/TarantoolContainerTest.java b/src/test/java/org/testcontainers/containers/TarantoolContainerTest.java index 45736ff..b2d68f3 100644 --- a/src/test/java/org/testcontainers/containers/TarantoolContainerTest.java +++ b/src/test/java/org/testcontainers/containers/TarantoolContainerTest.java @@ -7,6 +7,7 @@ /** * @author Alexey Kuzin + * @author Ivan Dneprov */ class TarantoolContainerTest { @@ -14,9 +15,8 @@ class TarantoolContainerTest { public void testExecuteScript() throws Exception { try (TarantoolContainer container = new TarantoolContainer()) { container.start(); - - container.executeScript("org/testcontainers/containers/test.lua").get(); - List result = container.executeCommand("return user_function_no_param()").get(); + container.executeScript("org/testcontainers/containers/test.lua"); + List result = container.executeCommandDecoded("return user_function_no_param()"); assertEquals(1, result.size()); assertEquals(5, result.get(0)); } @@ -34,15 +34,15 @@ public void testContainerWithParameters() throws Exception { .withLogLevel(TarantoolLogLevel.INFO)) { container.start(); - List result = container.executeCommand("return box.cfg.memtx_memory").get(); + List result = container.executeCommandDecoded("return box.cfg.memtx_memory"); assertEquals(1, result.size()); assertEquals(memory, result.get(0)); - result = container.executeCommand("return box.cfg.log_level").get(); + result = container.executeCommandDecoded("return box.cfg.log_level"); assertEquals(1, result.size()); assertEquals(5, result.get(0)); - result = container.executeCommand("return user_function_no_param()").get(); + result = container.executeCommandDecoded("return user_function_no_param()"); assertEquals(result.size(), 1); assertEquals(result.get(0), 5); } diff --git a/src/test/java/org/testcontainers/containers/TarantoolSdkContainerTestEnterprise.java b/src/test/java/org/testcontainers/containers/TarantoolSdkContainerTestEnterprise.java deleted file mode 100644 index 645dca9..0000000 --- a/src/test/java/org/testcontainers/containers/TarantoolSdkContainerTestEnterprise.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.testcontainers.containers; - - -import io.tarantool.driver.TarantoolVersion; -import io.tarantool.driver.api.TarantoolClient; -import io.tarantool.driver.api.TarantoolClientFactory; -import io.tarantool.driver.api.TarantoolResult; -import io.tarantool.driver.api.tuple.TarantoolTuple; - -import java.io.File; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Oleg Kuznetsov - */ -public class TarantoolSdkContainerTestEnterprise { - - @Test - void test_should_createTarantoolContainerFromSdk() throws URISyntaxException { - final File dockerfile = new File( - TarantoolSdkContainerTestEnterprise.class.getClassLoader().getResource("testsdk/Dockerfile").toURI() - ); - final Map buildArgs = new HashMap<>(); - buildArgs.put("DOWNLOAD_SDK_URI", System.getenv("DOWNLOAD_SDK_URI")); - buildArgs.put("SDK_VERSION", "tarantool-enterprise-sdk-nogc64-2.10.6-0-r557.linux.x86_64"); - - try (final TarantoolContainer tarantoolContainer = new TarantoolContainer( - new TarantoolImageParams("tarantool-enterprise-bundle:latest", dockerfile, buildArgs)) - .withDirectoryBinding("testsdk")) { - - tarantoolContainer.start(); - - final TarantoolClient> client = - TarantoolClientFactory.createClient() - .withCredentials("api_user", "secret") - .withAddress(tarantoolContainer.getHost(), tarantoolContainer.getMappedPort(3301)) - .build(); - - final List result = client.eval("return 'test'").join(); - final TarantoolVersion version = client.getVersion(); - - assertEquals("test", result.get(0)); - assertTrue(version.toString().startsWith("Tarantool 2.10.6 (Binary)")); - } - } -} diff --git a/src/test/java/org/testcontainers/containers/TarantoolStaticContainerTest.java b/src/test/java/org/testcontainers/containers/TarantoolStaticContainerTest.java index 38fc947..7526c1a 100644 --- a/src/test/java/org/testcontainers/containers/TarantoolStaticContainerTest.java +++ b/src/test/java/org/testcontainers/containers/TarantoolStaticContainerTest.java @@ -10,6 +10,8 @@ /** * @author Alexey Kuzin + * @author Oleg Kuznetsov + * @author Ivan Dneprov */ @Testcontainers public class TarantoolStaticContainerTest { @@ -19,17 +21,15 @@ public class TarantoolStaticContainerTest { @Test public void testExecuteCommand() throws Exception { - List result = container.executeCommand("return 1, 2").get(); + List result = container.executeCommandDecoded("return 1, 2"); assertEquals(2, result.size()); assertEquals(1, result.get(0)); } @Test public void testExecuteCommandWithArguments() throws Exception { - List result = container.executeCommand( - "return require('fun').iter({...}):reduce(function(x, acc) return acc+x end, 0)", - 1, 2, 3) - .get(); + List result = container.executeCommandDecoded( + "return require('fun').iter({1, 2, 3}):reduce(function(x, acc) return acc+x end, 0)"); assertEquals(1, result.size()); assertEquals(6, result.get(0)); } @@ -37,7 +37,7 @@ public void testExecuteCommandWithArguments() throws Exception { @Test public void testSetLogLevel() throws Exception { container.withLogLevel(TarantoolLogLevel.INFO); - List result = container.executeCommand("return box.cfg.log_level").get(); + List result = container.executeCommandDecoded("return box.cfg.log_level"); assertEquals(1, result.size()); assertEquals(5, result.get(0)); } @@ -46,7 +46,7 @@ public void testSetLogLevel() throws Exception { public void testSetMemtxMemory() throws Exception { int memory = 256 * 1024 * 1024; container.withMemtxMemory(memory); - List result = container.executeCommand("return box.cfg.memtx_memory").get(); + List result = container.executeCommandDecoded("return box.cfg.memtx_memory"); assertEquals(1, result.size()); assertEquals(memory, result.get(0)); } diff --git a/src/test/java/org/testcontainers/containers/enterprise/TarantoolMTlsContainerTestEnterprise.java b/src/test/java/org/testcontainers/containers/enterprise/TarantoolMTlsContainerTestEnterprise.java new file mode 100644 index 0000000..012f231 --- /dev/null +++ b/src/test/java/org/testcontainers/containers/enterprise/TarantoolMTlsContainerTestEnterprise.java @@ -0,0 +1,63 @@ +package org.testcontainers.containers.enterprise; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.SslContext; +import org.testcontainers.containers.TarantoolContainer; +import org.testcontainers.containers.TarantoolImageParams; +import org.testcontainers.containers.output.Slf4jLogConsumer; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Ivan Dneprov + */ +public class TarantoolMTlsContainerTestEnterprise { + + private static final Logger log = LoggerFactory.getLogger(TarantoolMTlsContainerTestEnterprise.class); + + private static TarantoolContainer containerWithSsl; + + @BeforeAll + public static void setUp() throws Exception { + final File dockerfile = new File( + TarantoolMTlsContainerTestEnterprise.class.getClassLoader() + .getResource("enterprise/Dockerfile").toURI() + ); + final Map buildArgs = new HashMap<>(); + buildArgs.put("DOWNLOAD_SDK_URI", System.getenv("DOWNLOAD_SDK_URI")); + buildArgs.put("SDK_VERSION", System.getenv("SDK_VERSION")); + + containerWithSsl = new TarantoolContainer( + new TarantoolImageParams("tarantool-enterprise", dockerfile, buildArgs)) + .withScriptFileName("mtls_server.lua") + .withUsername("api_user") + .withPassword("secret") + .withMemtxMemory(256 * 1024 * 1024) + .withDirectoryBinding("enterprise/ssl/mtls") + .withSslContext(SslContext.getSslContext("/app/ca.key", "/app/ca.crt")) + .withLogConsumer(new Slf4jLogConsumer(log)); + + if (!containerWithSsl.isRunning()) { + containerWithSsl.start(); + } + } + + @Test + public void test_clientWithSsl_shouldWork() throws Exception { + List resultList = containerWithSsl.executeCommandDecoded("return box.cfg.listen"); + HashMap result = resultList.get(0); + HashMap params = result.get("params"); + assertEquals("ssl", params.get("transport")); + assertEquals("server.key", params.get("ssl_key_file")); + assertEquals("server.crt", params.get("ssl_cert_file")); + assertEquals("ca.crt", params.get("ssl_ca_file")); + } +} diff --git a/src/test/java/org/testcontainers/containers/enterprise/TarantoolSdkContainerTestEnterprise.java b/src/test/java/org/testcontainers/containers/enterprise/TarantoolSdkContainerTestEnterprise.java new file mode 100644 index 0000000..8c78396 --- /dev/null +++ b/src/test/java/org/testcontainers/containers/enterprise/TarantoolSdkContainerTestEnterprise.java @@ -0,0 +1,42 @@ +package org.testcontainers.containers.enterprise; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.TarantoolContainer; +import org.testcontainers.containers.TarantoolImageParams; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Oleg Kuznetsov + * @author Ivan Dneprov + */ +public class TarantoolSdkContainerTestEnterprise { + + + @Test + void test_should_createTarantoolContainerFromSdk() throws Exception { + final File dockerfile = new File( + TarantoolSdkContainerTestEnterprise.class.getClassLoader().getResource("enterprise/Dockerfile").toURI() + ); + final Map buildArgs = new HashMap<>(); + buildArgs.put("DOWNLOAD_SDK_URI", System.getenv("DOWNLOAD_SDK_URI")); + buildArgs.put("SDK_VERSION", System.getenv("SDK_VERSION")); + + try (final TarantoolContainer tarantoolContainer = new TarantoolContainer( + new TarantoolImageParams("tarantool-enterprise-bundle:latest", dockerfile, buildArgs)) + .withDirectoryBinding("enterprise")) { + + tarantoolContainer.start(); + + List result = tarantoolContainer.executeCommandDecoded("return 'test'"); + List versionAnswer = tarantoolContainer.executeCommandDecoded("return _TARANTOOL"); + + Assertions.assertEquals("test", result.get(0)); + Assertions.assertEquals("2.10.7-0-g2e9b20365-r563-nogc64", versionAnswer.get(0)); + } + } +} diff --git a/src/test/java/org/testcontainers/containers/enterprise/TarantoolSslContainerTestEnterprise.java b/src/test/java/org/testcontainers/containers/enterprise/TarantoolSslContainerTestEnterprise.java new file mode 100644 index 0000000..b69d860 --- /dev/null +++ b/src/test/java/org/testcontainers/containers/enterprise/TarantoolSslContainerTestEnterprise.java @@ -0,0 +1,62 @@ +package org.testcontainers.containers.enterprise; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.SslContext; +import org.testcontainers.containers.TarantoolContainer; +import org.testcontainers.containers.TarantoolImageParams; +import org.testcontainers.containers.output.Slf4jLogConsumer; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Ivan Dneprov + */ +public class TarantoolSslContainerTestEnterprise { + + private static final Logger log = LoggerFactory.getLogger(TarantoolSslContainerTestEnterprise.class); + + private static TarantoolContainer containerWithSsl; + + @BeforeAll + public static void setUp() throws Exception { + final File dockerfile = new File( + TarantoolSslContainerTestEnterprise.class.getClassLoader() + .getResource("enterprise/Dockerfile").toURI() + ); + final Map buildArgs = new HashMap<>(); + buildArgs.put("DOWNLOAD_SDK_URI", System.getenv("DOWNLOAD_SDK_URI")); + buildArgs.put("SDK_VERSION", System.getenv("SDK_VERSION")); + + containerWithSsl = new TarantoolContainer( + new TarantoolImageParams("tarantool-enterprise", dockerfile, buildArgs)) + .withScriptFileName("ssl_server.lua") + .withUsername("api_user") + .withPassword("secret") + .withMemtxMemory(256 * 1024 * 1024) + .withDirectoryBinding("enterprise/ssl") + .withSslContext(SslContext.getSslContext()) + .withLogConsumer(new Slf4jLogConsumer(log)); + + if (!containerWithSsl.isRunning()) { + containerWithSsl.start(); + } + } + + @Test + public void test_clientWithSsl_shouldWork() throws Exception { + List resultList = containerWithSsl.executeCommandDecoded("return box.cfg.listen"); + HashMap result = resultList.get(0); + HashMap params = result.get("params"); + assertEquals("ssl", params.get("transport")); + assertEquals("key.pem", params.get("ssl_key_file")); + assertEquals("certificate.crt", params.get("ssl_cert_file")); + } +} diff --git a/src/test/resources/testsdk/Dockerfile b/src/test/resources/enterprise/Dockerfile similarity index 100% rename from src/test/resources/testsdk/Dockerfile rename to src/test/resources/enterprise/Dockerfile diff --git a/src/test/resources/testsdk/server.lua b/src/test/resources/enterprise/server.lua similarity index 100% rename from src/test/resources/testsdk/server.lua rename to src/test/resources/enterprise/server.lua diff --git a/src/test/resources/enterprise/ssl/certificate.crt b/src/test/resources/enterprise/ssl/certificate.crt new file mode 100644 index 0000000..62ebf3a --- /dev/null +++ b/src/test/resources/enterprise/ssl/certificate.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhDCCAmwCCQCbVZGkNwxnRzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMC +UlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MQswCQYDVQQKDAJW +SzESMBAGA1UECwwJVGFyYW50b29sMRIwEAYDVQQDDAlUYXJhbnRvb2wxHTAbBgkq +hkiG9w0BCQEWDnRlc3RAdGVzdC50ZXN0MB4XDTIyMDQwNzE2MDU1NFoXDTIzMDQw +NzE2MDU1NFowgYMxCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNV +BAcMBk1vc2NvdzELMAkGA1UECgwCVksxEjAQBgNVBAsMCVRhcmFudG9vbDESMBAG +A1UEAwwJVGFyYW50b29sMR0wGwYJKoZIhvcNAQkBFg50ZXN0QHRlc3QudGVzdDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM/3KMHSybroxV5nR8tm19kg +uVlWoFzd7IXGcVbeVCdu30wBLeDQ2XvsnjYYMkHUDPWLkVosZO4de0D+vyS2CmgE +zeurAjCrUEs4Sc/Aa+CTSRuI17EkJjPpDQNSCmp3KJfPGGAypYNT7kH2Va+HvNBR +HHsSk3xuyXujX02DwsuUnf5XqYuuZ39S5jRZ3qvmQytmVXrOtSeNyhWz50XISTER +ErczPVfKOIFYEZWj+9cKaTZssYZp95MCbkagKh9ZQ6E/T3TGTMEHrqYuXQC4mHI8 +PEISqnY3Vo4lpe+SBWxpJBOK5YWSTUWdPygyt71xEPkyss+C87bMsdQaY8r4TrkC +AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAj2xf7QdcSbG0nF783TGnqFK7/pBrrdDb +zlT3NReHP70FjxPIK5alMkQBM+kn/+j1RDnjJhQQa5NKadhEHqpaRd7R2Iv9a2h8 +xQ78jB1GGygFnc5rGx3h5kOFSLjQlFcm9HYafTlasKYAjvhM4SiBQU/jgG2bHrIb +KrElFswBsfV2VvmvyYyhwDqrtZzKayS3BMD6fls95W+hUlMtcQXFZCVlIkJj6BVc +okM2tvkM/6ShokidAIkrq34dg4IJf3ZBXrXdiqtznMdaHAqb++Z4w3DY+hB+82qy +rUzOXligeS/xxzhiZRuIiGgMg4WbGAv7yexRgqv2wyJiGZfIfBrEdw== +-----END CERTIFICATE----- diff --git a/src/test/resources/enterprise/ssl/gen.sh b/src/test/resources/enterprise/ssl/gen.sh new file mode 100644 index 0000000..f767927 --- /dev/null +++ b/src/test/resources/enterprise/ssl/gen.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +HOST=tarantool.io +NEW_KEY_ARG=rsa:4096 +DAYS_ARG=36500 +CYPHER="PBE-SHA1-RC2-40" + +gen_ca() { + local ca="${1}" + openssl req \ + -new \ + -nodes \ + -newkey "${NEW_KEY_ARG}" \ + -keyout "${ca}.key" \ + -days "${DAYS_ARG}" \ + -x509 \ + -subj "/OU=Unknown/O=Unknown/L=Unknown/ST=unknown/C=AU" \ + -out "${ca}.crt" + +} + +gen_cert() { + local cert="${1}" + local ca="${2}" + + openssl req \ + -new \ + -nodes \ + -newkey "${NEW_KEY_ARG}" \ + -subj "/CN=${HOST}/OU=Unknown/O=Unknown/L=Unknown/ST=unknown/C=AU" \ + -keyout "${cert}.key" \ + -out "${cert}.csr" + + openssl x509 \ + -req \ + -days "${DAYS_ARG}" \ + -CAcreateserial \ + -CA "${ca}.crt" \ + -CAkey "${ca}.key" \ + -in "${cert}.csr" \ + -out "${cert}.crt" + + rm -f "${cert}.csr" + rm -f "${ca}.srl" +} + +secure_key() { + local file="${1}" + local pass="${2}" + openssl pkcs8 \ + -topk8 \ + -v1 ${CYPHER} \ + -in ${file}.key \ + -out ${file}.pkcs8.key \ + -passout "pass:${pass}" +} + +gen_ca ca +gen_cert server ca +gen_cert client ca +secure_key client 1q2w3e diff --git a/src/test/resources/enterprise/ssl/key.pem b/src/test/resources/enterprise/ssl/key.pem new file mode 100644 index 0000000..81493b0 --- /dev/null +++ b/src/test/resources/enterprise/ssl/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDP9yjB0sm66MVe +Z0fLZtfZILlZVqBc3eyFxnFW3lQnbt9MAS3g0Nl77J42GDJB1Az1i5FaLGTuHXtA +/r8ktgpoBM3rqwIwq1BLOEnPwGvgk0kbiNexJCYz6Q0DUgpqdyiXzxhgMqWDU+5B +9lWvh7zQURx7EpN8bsl7o19Ng8LLlJ3+V6mLrmd/UuY0Wd6r5kMrZlV6zrUnjcoV +s+dFyEkxERK3Mz1XyjiBWBGVo/vXCmk2bLGGafeTAm5GoCofWUOhP090xkzBB66m +Ll0AuJhyPDxCEqp2N1aOJaXvkgVsaSQTiuWFkk1FnT8oMre9cRD5MrLPgvO2zLHU +GmPK+E65AgMBAAECggEAVpNrOT1aU+Bhggp2/ftjcnXIE6QXgHG27H4PYv2NhRkI +BqkbA1OOpqN7vcNW8MapWnNu4F5I6kQFsqoawtqx/Fm7rBd2AvLeq2HUgJN3lXdb +YQYX3RvSd5vWmgJGacoPcRt651lORBzlvDojs75LYWHS/H1gPtYUNM9vdmKa7orA +wWL1SITeR3gla0euaPItBUUNEyH4wepqG22ERqk/A7u54KRSvXp0mXRYcoDah6Y/ +nmuWwWfPbqCHgopiT3IBOsqklWIkCzLNx24OhOEXXAfgH5pw85NiPP/ZJN3moNYg +2Tj3VUt9Po3TnmKX+Az8gG4tNQ9R2F4YbnKm2wxFAQKBgQD1B2guaee/wUR16foX +pgOW+9TnDwTpBwHFaymzLHG2Gs3Zb0fR5HAGfV9Oxnde8Jw4bprRa5IZYzwgKgKY +jD9Qa8u+WsYKKOObmyBPTzpJevp0cQ9pxIgR/PSj98LL5Wvitcc82fGQAbA4KK02 +6VnaSfCrW2YDrl4Wk2NBFQACGQKBgQDZRuuD2Cn1dbCPuroQmYE4Pl++ke4mDl7F +xcOL7syu3uBbep/JwMB/ujruhtY9qBdKdLYjIO11xFtdQWhi7sMhhp3hlv8OGhR4 +b2Po3XnNZJ16/gSu4UqgSJ8ZQA8luNNMA0jUFW8Ki15O6vhvFDS/HIcLot+l3Lna +B71+l+CFoQKBgQCCtUDOAZCuqdprTDUtCFJB6HTaDRkBdctsFI5aFgtSqVnF86bM +QJ/B1n9Q9m4XJyMut1G/BTMad+VLAx3/YlEkBVzaXnHmWYmRKF9D72+YYxHXq7gd +I8myTs3x6ejv+6Jhfbaar2g8+amXS5ua/z//QhIwVsFElW97e4Qm45ztgQKBgEBB +JeL+qSHq5QUMTnwcOUedwojD9S6R71sDahnWy/cm+Ch1cg2jEAp103m4rGDddc3S +CA8JbM/3+qDwd+NSAqjGe6g8FD9iXQ1ku6Ig5SVljODTgCULgRs3fr1j4VbherMv +AXmewRDYOFKUUFXhHtwpnpJFX2hYhynAQjzOw1ohAoGBAIGypNhAgnhc2hyeqYC9 +Sg5JA06PFjuvrpymdcO3pfx9K7fHpU+wH17uYmzscMkFd5KrXVtqkziqMNV78hB4 ++x5qgabXlrZj4lVaTJLB5nPWt1VBZXcAwSDw5QAVhZtiXmsqKHgvVzR4hNnOWILq +1sQlocjdaPKH0EEbP84Ae2a7 +-----END PRIVATE KEY----- diff --git a/src/test/resources/enterprise/ssl/mtls/ca.crt b/src/test/resources/enterprise/ssl/mtls/ca.crt new file mode 100644 index 0000000..7000d37 --- /dev/null +++ b/src/test/resources/enterprise/ssl/mtls/ca.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIUD0mJoUjJsB4mrsSsBlAorJwmgcUwDQYJKoZIhvcNAQEL +BQAwVTEQMA4GA1UECwwHVW5rbm93bjEQMA4GA1UECgwHVW5rbm93bjEQMA4GA1UE +BwwHVW5rbm93bjEQMA4GA1UECAwHdW5rbm93bjELMAkGA1UEBhMCQVUwIBcNMjIw +NTMxMjEwNTA2WhgPMjEyMjA1MDcyMTA1MDZaMFUxEDAOBgNVBAsMB1Vua25vd24x +EDAOBgNVBAoMB1Vua25vd24xEDAOBgNVBAcMB1Vua25vd24xEDAOBgNVBAgMB3Vu +a25vd24xCzAJBgNVBAYTAkFVMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEAtpV9sxa6KPfTP4r5IJAHML0SlIUX9rSzEwKnbsMuyEKUwmcZVQ1aUWrmTQ0J +UGboOuVMBaNqmWaeqgJBTXns60/MrKSBQmOUwm1/FIBt6KQF2WZZUM13yq+UN5i/ +MHtAzHxSrecHNmzpvL9y48QJFs4ruoCzVsnLz9EmYChQCrFj1JsfLVvSpcDTFgdV +bTHJIBF9rHFKB92qMbhDJjrSmvPKNqyaLnWP0WttNIMtE5djrqwGbHolX5JrFIKr +9LDV2jJiMA7tFVl2cgg+uEcrxqOz421S9VYD0hl5hFF81rpdg/q7MEBHPYD2cCyl +92mxUYqz7r9OdK7KeMlLD/sjL34IXsT4TbcbMLYcfBdBmDRAbaAlON3spU9EPUxd +Yvhd3qKDlOP3oCXDE5MKQujz7gR3XQpX3Zdd5zxdcp/GiE9RivoKstm5/JznN+ns +BaBzw6d4gBTzIPMmiAmUTrnWD5UEhsG/kHzk+K2WXJS8/05CIZThLgILl/vfgrMX +3OBUsw1ePXj2Jmp1HLExtpX8U1NKA8UtU97QRX40eWvMuLGz7sKMS/VZiA9eNkMI +hQhkjMt0JPo9gfMggVMBOjQbLV4Ni4XZeMzurtGOmlD61s7GECySKHy5pYZtXisO +VpKABYTEyTIPPjuwN5W90h+/NI2h8xW2Z9xsE7K0flGtA1cCAwEAAaNTMFEwHQYD +VR0OBBYEFKA+WAfH0GT8G4aM4RTplY4ECcQDMB8GA1UdIwQYMBaAFKA+WAfH0GT8 +G4aM4RTplY4ECcQDMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB +AG++VdNo894uxESkzjVEC6hSLdcER6EbQOM34H13MzseMIjlv/4ely/Vsh79QEXA +fnAadrdVk/0r3BpBaO/iOLdMquePLBi/IYxfLaY8z2nwaocbMKUVmVjFuOgm+oXq +atyc/yzVG5yyaxoC1jHIgjn81fesI0f17opqda13u+4hXTcdAbpOY7yZY8YmP2o+ +SCCfGco1BBSyKIteHLzQzpG8pZnKM0seAitZ9jD5CF9jw0tzJCWkDIhJ2dgjpigz +Go5WBxY3FMyKQPOIP5a+5AWRV+fVWENdZu9EwEWpLqc/GxQrvhbXhJ/L2ZiYRNd8 +SNTBL7H0Sw65jHRWWSfz7osVntL+LYRPh30sF9LYTpUnp3gr4VTXLo6jaxwhvsIy +CacNhLpgco0sM6RLcHaSxYMUtO3EttDbkcBmIyP1KHEq1mzcVcXSetS7g9efxToh +G7NH1zVP1a8qJF5qKjXgRBASIXke9AHeAOYDI7om7qQtGuqI7nI3eg5E0qUM1gqH +kTKXJcXn/pwCkJL8TvRZWlYNJMG2YEwdA4KFgywHGn3GaM2quNqbZosMF84vlvnp +lrzJbrg2nD/wwQWdljJPVp5WReoPI9t08UqopR2P+zFcDh75X+3SXL8mMRIXMvFU +eTU7QSXhc9Q6l+skY2cRgvYl++fIooebBXpCYY9uDht9 +-----END CERTIFICATE----- diff --git a/src/test/resources/enterprise/ssl/mtls/ca.key b/src/test/resources/enterprise/ssl/mtls/ca.key new file mode 100644 index 0000000..48c1040 --- /dev/null +++ b/src/test/resources/enterprise/ssl/mtls/ca.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +YfB9GdaUnR0F648bsknruMJrFjfZFbo= +-----END PRIVATE KEY----- diff --git a/src/test/resources/enterprise/ssl/mtls/mtls_server.lua b/src/test/resources/enterprise/ssl/mtls/mtls_server.lua new file mode 100644 index 0000000..9079bff --- /dev/null +++ b/src/test/resources/enterprise/ssl/mtls/mtls_server.lua @@ -0,0 +1,12 @@ +box.cfg { listen = { + uri = 3301, + params = { + transport = 'ssl', + ssl_key_file = 'server.key', + ssl_cert_file = 'server.crt', + ssl_ca_file = 'ca.crt' + } +} } + +box.schema.user.create('api_user', { password = 'secret', if_not_exists = true }) +box.schema.user.grant('api_user', 'read, write, execute', 'universe', nil, { if_not_exists = true }) diff --git a/src/test/resources/enterprise/ssl/mtls/server.crt b/src/test/resources/enterprise/ssl/mtls/server.crt new file mode 100644 index 0000000..fe661cc --- /dev/null +++ b/src/test/resources/enterprise/ssl/mtls/server.crt @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFSjCCAzICFAGDWf+4nbv3f7+QrRbP8Q3YhzOaMA0GCSqGSIb3DQEBCwUAMFUx +EDAOBgNVBAsMB1Vua25vd24xEDAOBgNVBAoMB1Vua25vd24xEDAOBgNVBAcMB1Vu +a25vd24xEDAOBgNVBAgMB3Vua25vd24xCzAJBgNVBAYTAkFVMCAXDTIyMDUzMTIx +MDUwOVoYDzIxMjIwNTA3MjEwNTA5WjBsMRUwEwYDVQQDDAx0YXJhbnRvb2wuaW8x +EDAOBgNVBAsMB1Vua25vd24xEDAOBgNVBAoMB1Vua25vd24xEDAOBgNVBAcMB1Vu +a25vd24xEDAOBgNVBAgMB3Vua25vd24xCzAJBgNVBAYTAkFVMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAy8ClyS3WZlJwycdRM1Nteke6adcgScUz0hVn +yhZJpZo4crReCTtCzOWNstlA5nnzlDT56YbnmzAwDNG6pPP00t2jVUU5wxMJSDGy +SkDk0nxq4Rd20EDV3+GIxJ+aEEPYwMcY4RcGErG+5yrSVbWniDLcvKeMjLjODzUr +vzSuBsRgtMt8Z6vQUaBxIdT3XupLFSZb4k883TkQE8wXjqbLmmOPoQAu1WZVAKEV +uvxXKonYlgC00Rl7HsaEMw8zUL7P1e+qtn6GaXkdI55Lk2y/yk0UKhBWR43mDoTx +VWyWrVnL7rFLt7Doz6F8Q5tiekjz3WpVhm2z7aGMZ/n3FE3etNVbnZg1/wqXjini +VXCgaUKryEYKR1kgPxUJB7EHjSLIGIn1Ix6toMK6ntr+WySMUfSt0A5jsQ3WM1TY +8YOdFuFbeiPpTD9Qq7hDPW1AyGOkh31eecqVwBJQlajRrkZBBZ8EacbR6aDgBfm4 +n3gtoUuZZYf1aW1HzlWjaVp6M5gJCbbvuGjcfpVAbq71PTM6PYHvfe2wlbfJR02V +H7kGUUbE3A1JIGSys44FLaitY3Gy+X/Tj+bEH1uid/Q6ykcCcU/ICDoaXBQ9jbSv +56CfIjoSUY2JXpDG/Ahli/b6pwvP9CkLGTDc0VWpuG4sB3sbzjhYyijDac48/JuJ +HVk1mMcCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEARGdetChBKbDNaxGA+NHAtDGe +2lVISV21j5L1EkWQhrp39bx1YsFmvV+wibYuTDTlk/XSh+MpuRvTmc8xWXIIe30Y +PQXQPCrRd8vNjHt6i0MpW4kCe0QU/PTGOOBpD1VnJuAuebqmLuvdwCHb5uCacbVJ +Gt9voyM3yQQNZ0A3jYcm7Y6PAEL/gxq0+F30+LwvZqaAGO6hqC7WJuiyoE9No9ri ++0vZG0F0l1ZiVWaIi5m38KfYGuhd8tAEKkTUZ2cL0Td/KOavCgJ1D8s4co3wyDZG +qrIVKHYvl8G2YivQdXpMuh32QAog/34zI909pM0E2IzxRl6YBjP9UaAUW6LWWuWZ +1pso3pL/+WynAUC9gsWFcnsv3Ji4ZH24nA7BemBwo5JT/5WTtMTAA4phQDH340x4 +VnHPigcvyu3eh/PDS7ZdiUSGuNcibSTrhn4bluCv5vzzmw+Atp9eccF81LxfERJY +4H94Kw70/8LBLR/7McL/aobJ5mSpAK1nnsRdr1xE46uGpkmK4pgHfD5xkcn9AFxE +vsCnwynYp4RNPfiLUHNzez0T4JWnJqPtSNtR2jTO3iVz04SUbUj/cltXOLzyPfyM +VouEL2VnAmC1WCN5KC6NnzyKVLbQ7EAi4x+61lJWWkRugxrXeaVdNbgQlA1yvAlF +cA8F69eVyPJnFsdWSq0= +-----END CERTIFICATE----- diff --git a/src/test/resources/enterprise/ssl/mtls/server.key b/src/test/resources/enterprise/ssl/mtls/server.key new file mode 100644 index 0000000..f6f5117 --- /dev/null +++ b/src/test/resources/enterprise/ssl/mtls/server.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +jE5s8iIxjb4IkPziVOzgev4epyIs +-----END PRIVATE KEY----- diff --git a/src/test/resources/enterprise/ssl/mtls/trustStoreFile b/src/test/resources/enterprise/ssl/mtls/trustStoreFile new file mode 100644 index 0000000..af02d8b Binary files /dev/null and b/src/test/resources/enterprise/ssl/mtls/trustStoreFile differ diff --git a/src/test/resources/enterprise/ssl/ssl_server.lua b/src/test/resources/enterprise/ssl/ssl_server.lua new file mode 100644 index 0000000..72ca5bf --- /dev/null +++ b/src/test/resources/enterprise/ssl/ssl_server.lua @@ -0,0 +1,11 @@ +box.cfg { listen = { + uri = 3301, + params = { + transport = 'ssl', + ssl_key_file = 'key.pem', + ssl_cert_file = 'certificate.crt' + } +} } + +box.schema.user.create('api_user', { password = 'secret', if_not_exists = true }) +box.schema.user.grant('api_user', 'read, write, execute', 'universe', nil, { if_not_exists = true })