From 44bb1ec5dbe75f107f682a99cdb74c252135dcf2 Mon Sep 17 00:00:00 2001 From: Ramazan Yapparov Date: Wed, 13 Jan 2021 17:59:18 +0300 Subject: [PATCH 1/4] - changed code example in the docs to codeinclude - removed VaultClientTest and moved its contest to VaultContainerTest - uplifted Vault image version - added getVaultAddress method for usage convenience --- docs/modules/vault.md | 50 ++++---- .../testcontainers/vault/VaultContainer.java | 8 +- .../testcontainers/vault/VaultClientTest.java | 58 --------- .../vault/VaultContainerTest.java | 114 +++++++++++++++--- .../testcontainers/vault/VaultTestImages.java | 7 -- 5 files changed, 125 insertions(+), 112 deletions(-) delete mode 100644 modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java delete mode 100644 modules/vault/src/test/java/org/testcontainers/vault/VaultTestImages.java diff --git a/docs/modules/vault.md b/docs/modules/vault.md index 1f58c0ab836..ddd325e30f3 100644 --- a/docs/modules/vault.md +++ b/docs/modules/vault.md @@ -4,31 +4,31 @@ Testcontainers module for [Vault](https://github.com/hashicorp/vault). Vault is ## Usage example -Running Vault in your Junit tests is easily done with an @Rule or @ClassRule such as the following: - -```java -public class SomeTest { - - @ClassRule - public static VaultContainer vaultContainer = new VaultContainer<>() - .withVaultToken("my-root-token") - .withVaultPort(8200) - .withSecretInVault("secret/testing", "top_secret=password1","db_password=dbpassword1"); - - @Test - public void someTestMethod() { - //interact with Vault via the container's host, port and Vault token. - - //There are many integration clients for Vault so let's just define a general one here: - VaultClient client = new VaultClient( - vaultContainer.getHost(), - vaultContainer.getMappedPort(8200), - "my-root-token"); - - List secrets = client.readSecret("secret/testing"); - - } -``` +Start Vault container as a `@ClassRule`: + + +[Starting a Vault container as a @ClassRule](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:vaultContainer + + +Use CLI to read data from Vault container: + + +[Use CLI to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readWithCli + + +Use Http API to read data from Vault container: + + +[Use Http API to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readWithHttpApi + + +Use client library to read data from Vault container: + + +[Use library to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readWithLibrary + + +[See full example.](https://github.com/testcontainers/testcontainers-java/blob/master/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) ## Why Vault in Junit tests? diff --git a/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java b/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java index 37e78a14f95..67b90c774f3 100644 --- a/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java +++ b/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java @@ -27,7 +27,7 @@ public class VaultContainer> extends GenericContainer { private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("vault"); - private static final String DEFAULT_TAG = "1.1.3"; + private static final String DEFAULT_TAG = "1.6.1"; private static final int VAULT_PORT = 8200; @@ -61,6 +61,10 @@ public VaultContainer(final DockerImageName dockerImageName) { withExposedPorts(port); } + public String getVaultAddress() { + return String.format("http://%s:%s", getHost(), getMappedPort(port)); + } + @Override protected void containerIsStarted(InspectContainerResponse containerInfo) { addSecrets(); @@ -166,7 +170,7 @@ public SELF withSecretInVault(String path, String firstSecret, String... remaini /** * Run initialization commands using the vault cli. - * + * * Useful for enableing more secret engines like: *
      *     .withInitCommand("secrets enable pki")
diff --git a/modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java b/modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java
deleted file mode 100644
index 4a1a800da17..00000000000
--- a/modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.testcontainers.vault;
-
-import com.bettercloud.vault.Vault;
-import com.bettercloud.vault.VaultConfig;
-import com.bettercloud.vault.VaultException;
-import com.bettercloud.vault.response.LogicalResponse;
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.testcontainers.vault.VaultTestImages.VAULT_IMAGE;
-
-public class VaultClientTest {
-
-    private static final String VAULT_TOKEN = "my-root-token";
-
-    @Test
-    public void writeAndReadMultipleValues() throws VaultException {
-        try (
-            VaultContainer vaultContainer = new VaultContainer<>(VAULT_IMAGE)
-                    .withVaultToken(VAULT_TOKEN)
-        ) {
-
-            vaultContainer.start();
-
-            final VaultConfig config = new VaultConfig()
-                .address("http://" + vaultContainer.getHost() + ":" + vaultContainer.getFirstMappedPort())
-                .token(VAULT_TOKEN)
-                .build();
-
-            final Vault vault = new Vault(config);
-
-            final Map secrets = new HashMap<>();
-            secrets.put("value", "world");
-            secrets.put("other_value", "another world");
-
-            // Write operation
-            final LogicalResponse writeResponse = vault.logical()
-                .write("secret/hello", secrets);
-
-            assertThat(writeResponse.getRestResponse().getStatus()).isEqualTo(200);
-
-            // Read operation
-            final Map value = vault.logical()
-                .read("secret/hello")
-                .getData();
-
-
-            assertThat(value)
-                .containsEntry("value", "world")
-                .containsEntry("other_value", "another world");
-
-        }
-
-    }
-}
diff --git a/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java b/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
index 9dee4c21416..1f8baac6536 100644
--- a/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
+++ b/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
@@ -1,25 +1,31 @@
 package org.testcontainers.vault;
 
+import com.bettercloud.vault.Vault;
+import com.bettercloud.vault.VaultConfig;
+import com.bettercloud.vault.response.LogicalResponse;
+import java.util.HashMap;
+import java.util.Map;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.testcontainers.containers.GenericContainer;
 
-import java.io.IOException;
+import org.testcontainers.utility.DockerImageName;
 
 import static io.restassured.RestAssured.given;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.assertThat;
 
 /**
  * This test shows the pattern to use the VaultContainer @ClassRule for a junit test. It also has tests that ensure
- * the secrets were added correctly by reading from Vault with the CLI and over HTTP.
+ * the secrets were added correctly by reading from Vault with the CLI, over HTTP and over Client Library.
  */
 public class VaultContainerTest {
 
     private static final String VAULT_TOKEN = "my-root-token";
 
+    // vaultContainer {
     @ClassRule
-    public static VaultContainer vaultContainer = new VaultContainer<>(VaultTestImages.VAULT_IMAGE)
+    public static VaultContainer vaultContainer = new VaultContainer<>(DockerImageName.parse("vault:1.6.1"))
         .withVaultToken(VAULT_TOKEN)
         .withSecretInVault("secret/testing1", "top_secret=password123")
         .withSecretInVault("secret/testing2",
@@ -29,41 +35,47 @@ public class VaultContainerTest {
             "secret_three=password3",
             "secret_four=password4")
         .withInitCommand("secrets enable transit", "write -f transit/keys/my-key");
+    // }
 
     @Test
-    public void readFirstSecretPathWithCli() throws IOException, InterruptedException {
-        GenericContainer.ExecResult result = vaultContainer.execInContainer("vault", "kv", "get", "-format=json", "secret/testing1");
+    // readWithCli {
+    public void readFirstSecretPathWithCli() throws Exception {
+        GenericContainer.ExecResult result =
+            vaultContainer.execInContainer("vault", "kv", "get", "-format=json", "secret/testing1");
         final String output = result.getStdout().replaceAll("\\r?\\n", "");
-        assertThat(output, containsString("password123"));
+        assertThat(output).contains("password123");
     }
+    // }
 
     @Test
-    public void readSecondSecretPathWithCli() throws IOException, InterruptedException {
+    public void readSecondSecretPathWithCli() throws Exception {
         GenericContainer.ExecResult result = vaultContainer.execInContainer("vault", "kv", "get", "-format=json", "secret/testing2");
         final String output = result.getStdout().replaceAll("\\r?\\n", "");
         System.out.println("output = " + output);
-        assertThat(output, containsString("password1"));
-        assertThat(output, containsString("password2"));
-        assertThat(output, containsString("password3"));
-        assertThat(output, containsString("password4"));
+        assertThat(output).contains("password1");
+        assertThat(output).contains("password2");
+        assertThat(output).contains("password3");
+        assertThat(output).contains("password4");
     }
 
     @Test
-    public void readFirstSecretPathOverHttpApi() throws InterruptedException {
+    // readWithHttpApi {
+    public void readFirstSecretPathOverHttpApi() {
         given().
             header("X-Vault-Token", VAULT_TOKEN).
             when().
-            get("http://" + getHostAndPort() + "/v1/secret/data/testing1").
+            get(vaultContainer.getVaultAddress() + "/v1/secret/data/testing1").
             then().
             assertThat().body("data.data.top_secret", equalTo("password123"));
     }
+    // }
 
     @Test
-    public void readSecondSecretPathOverHttpApi() throws InterruptedException {
+    public void readSecondSecretPathOverHttpApi() {
         given().
             header("X-Vault-Token", VAULT_TOKEN).
             when().
-            get("http://" + getHostAndPort() + "/v1/secret/data/testing2").
+            get(vaultContainer.getVaultAddress() + "/v1/secret/data/testing2").
             then().
             assertThat().body("data.data.secret_one", containsString("password1")).
             assertThat().body("data.data.secret_two", containsString("password2")).
@@ -72,18 +84,80 @@ public void readSecondSecretPathOverHttpApi() throws InterruptedException {
     }
 
     @Test
-    public void readTransitKeyOverHttpApi() throws InterruptedException {
+    public void readTransitKeyOverHttpApi() {
         given().
             header("X-Vault-Token", VAULT_TOKEN).
             when().
-            get("http://" + getHostAndPort() + "/v1/transit/keys/my-key").
+            get(vaultContainer.getVaultAddress() + "/v1/transit/keys/my-key").
             then().
             assertThat().body("data.name", equalTo("my-key"));
     }
 
-    private String getHostAndPort() {
-        return vaultContainer.getHost() + ":" + vaultContainer.getMappedPort(8200);
+    @Test
+    // readWithLibrary {
+    public void readFirstSecretPathOverClientLibrary() throws Exception {
+        final VaultConfig config = new VaultConfig()
+            .address(vaultContainer.getVaultAddress())
+            .token(VAULT_TOKEN)
+            .build();
+
+        final Vault vault = new Vault(config);
+
+        final Map value = vault.logical()
+            .read("secret/testing1")
+            .getData();
+
+        assertThat(value)
+            .containsEntry("top_secret", "password123");
+    }
+    // }
+
+    @Test
+    public void readSecondSecretPathOverClientLibrary() throws Exception {
+        final VaultConfig config = new VaultConfig()
+            .address(vaultContainer.getVaultAddress())
+            .token(VAULT_TOKEN)
+            .build();
+
+        final Vault vault = new Vault(config);
+        final Map value = vault.logical()
+            .read("secret/testing1")
+            .getData();
+
+        assertThat(value)
+            .containsEntry("secret_one", "password1")
+            .containsEntry("secret_two", "password2")
+            .containsEntry("secret_three", "password3")
+            .containsEntry("secret_four", "password4");
     }
 
+    @Test
+    public void writeSecretOverClientLibrary() throws Exception {
+        final VaultConfig config = new VaultConfig()
+            .address(vaultContainer.getVaultAddress())
+            .token(VAULT_TOKEN)
+            .build();
+
+        final Vault vault = new Vault(config);
+
+        final Map secrets = new HashMap<>();
+        secrets.put("value", "world");
+        secrets.put("other_value", "another world");
+
+        // Write operation
+        final LogicalResponse writeResponse = vault.logical()
+            .write("secret/hello", secrets);
+
+        assertThat(writeResponse.getRestResponse().getStatus()).isEqualTo(200);
+
+        // Read operation
+        final Map value = vault.logical()
+            .read("secret/hello")
+            .getData();
+
+        assertThat(value)
+            .containsEntry("value", "world")
+            .containsEntry("other_value", "another world");
+    }
 
 }
diff --git a/modules/vault/src/test/java/org/testcontainers/vault/VaultTestImages.java b/modules/vault/src/test/java/org/testcontainers/vault/VaultTestImages.java
deleted file mode 100644
index 9afecdcffb9..00000000000
--- a/modules/vault/src/test/java/org/testcontainers/vault/VaultTestImages.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.testcontainers.vault;
-
-import org.testcontainers.utility.DockerImageName;
-
-public interface VaultTestImages {
-    DockerImageName VAULT_IMAGE = DockerImageName.parse("vault:1.1.3");
-}

From 31269ede046d97e4903b42ebb520bd1fba0c0f14 Mon Sep 17 00:00:00 2001
From: Ramazan Yapparov 
Date: Wed, 13 Jan 2021 21:25:51 +0300
Subject: [PATCH 2/4] - fixed test

---
 .../java/org/testcontainers/vault/VaultContainerTest.java     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java b/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
index 1f8baac6536..fcb36a42950 100644
--- a/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
+++ b/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
@@ -121,13 +121,13 @@ public void readSecondSecretPathOverClientLibrary() throws Exception {
 
         final Vault vault = new Vault(config);
         final Map value = vault.logical()
-            .read("secret/testing1")
+            .read("secret/testing2")
             .getData();
 
         assertThat(value)
             .containsEntry("secret_one", "password1")
             .containsEntry("secret_two", "password2")
-            .containsEntry("secret_three", "password3")
+            .containsEntry("secret_three", "[\"password3\",\"password3\"]")
             .containsEntry("secret_four", "password4");
     }
 

From d49fdaf3830eeabf947cd1d10f2845253303322c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= 
Date: Tue, 1 Nov 2022 16:03:09 -0600
Subject: [PATCH 3/4] Update code blocks

---
 docs/modules/vault.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/docs/modules/vault.md b/docs/modules/vault.md
index 380411cb25c..e32abfd1c60 100644
--- a/docs/modules/vault.md
+++ b/docs/modules/vault.md
@@ -7,19 +7,19 @@ Testcontainers module for [Vault](https://github.com/hashicorp/vault). Vault is
 Start Vault container as a `@ClassRule`:
 
 
-[Starting a Vault container as a @ClassRule](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:vaultContainer
+[Starting a Vault container](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:vaultContainer
 
 
 Use CLI to read data from Vault container:
 
 
-[Use CLI to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readWithCli
+[Use CLI to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readFirstSecretPathWithCli
 
 
 Use Http API to read data from Vault container:
 
 
-[Use Http API to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readWithHttpApi
+[Use Http API to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readFirstSecretPathOverHttpApi
 
 
 Use client library to read data from Vault container:

From b1ed52369e03eb0460952130c0a6d8778f27fc56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= 
Date: Mon, 7 Nov 2022 10:29:16 -0600
Subject: [PATCH 4/4] Rename getVaultAddress to getHttpHostAddress

---
 .../org/testcontainers/vault/VaultContainer.java     |  2 +-
 .../org/testcontainers/vault/VaultContainerTest.java | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java b/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java
index 5cb32cbf699..4c44668d565 100644
--- a/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java
+++ b/modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java
@@ -60,7 +60,7 @@ public VaultContainer(final DockerImageName dockerImageName) {
         withExposedPorts(port);
     }
 
-    public String getVaultAddress() {
+    public String getHttpHostAddress() {
         return String.format("http://%s:%s", getHost(), getMappedPort(port));
     }
 
diff --git a/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java b/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
index c3524feeab5..608d8bbb8a7 100644
--- a/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
+++ b/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java
@@ -74,7 +74,7 @@ public void readFirstSecretPathOverHttpApi() {
         Response response = given()
             .header("X-Vault-Token", VAULT_TOKEN)
             .when()
-            .get(vaultContainer.getVaultAddress() + "/v1/secret/data/testing1")
+            .get(vaultContainer.getHttpHostAddress() + "/v1/secret/data/testing1")
             .thenReturn();
         assertThat(response.body().jsonPath().getString("data.data.top_secret")).isEqualTo("password123");
     }
@@ -84,7 +84,7 @@ public void readSecondSecretPathOverHttpApi() throws InterruptedException {
         Response response = given()
             .header("X-Vault-Token", VAULT_TOKEN)
             .when()
-            .get(vaultContainer.getVaultAddress() + "/v1/secret/data/testing2")
+            .get(vaultContainer.getHttpHostAddress() + "/v1/secret/data/testing2")
             .andReturn();
 
         assertThat(response.body().jsonPath().getString("data.data.secret_one")).contains("password1");
@@ -98,7 +98,7 @@ public void readTransitKeyOverHttpApi() throws InterruptedException {
         Response response = given()
             .header("X-Vault-Token", VAULT_TOKEN)
             .when()
-            .get(vaultContainer.getVaultAddress() + "/v1/transit/keys/my-key")
+            .get(vaultContainer.getHttpHostAddress() + "/v1/transit/keys/my-key")
             .thenReturn();
 
         assertThat(response.body().jsonPath().getString("data.name")).isEqualTo("my-key");
@@ -108,7 +108,7 @@ public void readTransitKeyOverHttpApi() throws InterruptedException {
     // readWithLibrary {
     public void readFirstSecretPathOverClientLibrary() throws Exception {
         final VaultConfig config = new VaultConfig()
-            .address(vaultContainer.getVaultAddress())
+            .address(vaultContainer.getHttpHostAddress())
             .token(VAULT_TOKEN)
             .build();
 
@@ -124,7 +124,7 @@ public void readFirstSecretPathOverClientLibrary() throws Exception {
     @Test
     public void readSecondSecretPathOverClientLibrary() throws Exception {
         final VaultConfig config = new VaultConfig()
-            .address(vaultContainer.getVaultAddress())
+            .address(vaultContainer.getHttpHostAddress())
             .token(VAULT_TOKEN)
             .build();
 
@@ -141,7 +141,7 @@ public void readSecondSecretPathOverClientLibrary() throws Exception {
     @Test
     public void writeSecretOverClientLibrary() throws Exception {
         final VaultConfig config = new VaultConfig()
-            .address(vaultContainer.getVaultAddress())
+            .address(vaultContainer.getHttpHostAddress())
             .token(VAULT_TOKEN)
             .build();