Skip to content

Commit 6e15e09

Browse files
Update Vault docs (#3685)
- Update code example in the docs to use `codeinclude` - Remove `VaultClientTest` and moved its contest to `VaultContainerTest` - Add `getHttpHostAddress()` for usage convenience Co-authored-by: Eddú Meléndez <[email protected]>
1 parent 96af052 commit 6e15e09

File tree

5 files changed

+106
-51
lines changed

5 files changed

+106
-51
lines changed

docs/modules/vault.md

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,31 @@ Testcontainers module for [Vault](https://github.com/hashicorp/vault). Vault is
44

55
## Usage example
66

7-
Running Vault in your Junit tests is easily done with an @Rule or @ClassRule such as the following:
8-
9-
```java
10-
public class SomeTest {
11-
12-
@ClassRule
13-
public static VaultContainer vaultContainer = new VaultContainer<>()
14-
.withVaultToken("my-root-token")
15-
.withVaultPort(8200)
16-
.withSecretInVault("secret/testing", "top_secret=password1","db_password=dbpassword1");
17-
18-
@Test
19-
public void someTestMethod() {
20-
//interact with Vault via the container's host, port and Vault token.
21-
22-
//There are many integration clients for Vault so let's just define a general one here:
23-
VaultClient client = new VaultClient(
24-
vaultContainer.getHost(),
25-
vaultContainer.getMappedPort(8200),
26-
"my-root-token");
27-
28-
List<String> secrets = client.readSecret("secret/testing");
29-
30-
}
31-
```
7+
Start Vault container as a `@ClassRule`:
8+
9+
<!--codeinclude-->
10+
[Starting a Vault container](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:vaultContainer
11+
<!--/codeinclude-->
12+
13+
Use CLI to read data from Vault container:
14+
15+
<!--codeinclude-->
16+
[Use CLI to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readFirstSecretPathWithCli
17+
<!--/codeinclude-->
18+
19+
Use Http API to read data from Vault container:
20+
21+
<!--codeinclude-->
22+
[Use Http API to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readFirstSecretPathOverHttpApi
23+
<!--/codeinclude-->
24+
25+
Use client library to read data from Vault container:
26+
27+
<!--codeinclude-->
28+
[Use library to read data](../../modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java) inside_block:readWithLibrary
29+
<!--/codeinclude-->
30+
31+
[See full example.](https://github.com/testcontainers/testcontainers-java/blob/master/modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java)
3232

3333
## Why Vault in Junit tests?
3434

modules/vault/src/main/java/org/testcontainers/vault/VaultContainer.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ public VaultContainer(final DockerImageName dockerImageName) {
6060
withExposedPorts(port);
6161
}
6262

63+
public String getHttpHostAddress() {
64+
return String.format("http://%s:%s", getHost(), getMappedPort(port));
65+
}
66+
6367
@Override
6468
protected void containerIsStarted(InspectContainerResponse containerInfo) {
6569
addSecrets();
@@ -182,8 +186,8 @@ public SELF withSecretInVault(String path, String firstSecret, String... remaini
182186

183187
/**
184188
* Run initialization commands using the vault cli.
185-
*
186-
* Useful for enableing more secret engines like:
189+
* <p>
190+
* Useful for enabling more secret engines like:
187191
* <pre>
188192
* .withInitCommand("secrets enable pki")
189193
* .withInitCommand("secrets enable transit")

modules/vault/src/test/java/org/testcontainers/vault/VaultClientTest.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ public class VaultClientTest {
1717

1818
@Test
1919
public void writeAndReadMultipleValues() throws VaultException {
20-
try (
21-
VaultContainer<?> vaultContainer = new VaultContainer<>(VaultTestImages.VAULT_IMAGE)
22-
.withVaultToken(VAULT_TOKEN)
23-
) {
20+
try (VaultContainer<?> vaultContainer = new VaultContainer<>("vault:1.1.3").withVaultToken(VAULT_TOKEN)) {
2421
vaultContainer.start();
2522

2623
final VaultConfig config = new VaultConfig()

modules/vault/src/test/java/org/testcontainers/vault/VaultContainerTest.java

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
package org.testcontainers.vault;
22

3+
import com.bettercloud.vault.Vault;
4+
import com.bettercloud.vault.VaultConfig;
5+
import com.bettercloud.vault.response.LogicalResponse;
36
import io.restassured.response.Response;
47
import org.junit.ClassRule;
58
import org.junit.Test;
69
import org.testcontainers.containers.GenericContainer;
710

8-
import java.io.IOException;
11+
import java.util.HashMap;
12+
import java.util.Map;
913

1014
import static io.restassured.RestAssured.given;
1115
import static org.assertj.core.api.Assertions.assertThat;
1216

1317
/**
1418
* This test shows the pattern to use the VaultContainer @ClassRule for a junit test. It also has tests that ensure
15-
* the secrets were added correctly by reading from Vault with the CLI and over HTTP.
19+
* the secrets were added correctly by reading from Vault with the CLI, over HTTP and over Client Library.
1620
*/
1721
public class VaultContainerTest {
1822

1923
private static final String VAULT_TOKEN = "my-root-token";
2024

2125
@ClassRule
22-
public static VaultContainer<?> vaultContainer = new VaultContainer<>(VaultTestImages.VAULT_IMAGE)
26+
// vaultContainer {
27+
public static VaultContainer<?> vaultContainer = new VaultContainer<>("vault:1.6.1")
2328
.withVaultToken(VAULT_TOKEN)
2429
.withSecretInVault("secret/testing1", "top_secret=password123")
2530
.withSecretInVault(
@@ -32,28 +37,30 @@ public class VaultContainerTest {
3237
)
3338
.withInitCommand("secrets enable transit", "write -f transit/keys/my-key");
3439

40+
// }
41+
3542
@Test
36-
public void readFirstSecretPathWithCli() throws IOException, InterruptedException {
43+
public void readFirstSecretPathWithCli() throws Exception {
3744
GenericContainer.ExecResult result = vaultContainer.execInContainer(
3845
"vault",
3946
"kv",
4047
"get",
4148
"-format=json",
4249
"secret/testing1"
4350
);
44-
final String output = result.getStdout().replaceAll("\\r?\\n", "");
45-
assertThat(output).contains("password123");
51+
assertThat(result.getStdout()).contains("password123");
4652
}
4753

4854
@Test
49-
public void readSecondSecretPathWithCli() throws IOException, InterruptedException {
55+
public void readSecondSecretPathWithCli() throws Exception {
5056
GenericContainer.ExecResult result = vaultContainer.execInContainer(
5157
"vault",
5258
"kv",
5359
"get",
5460
"-format=json",
5561
"secret/testing2"
5662
);
63+
5764
final String output = result.getStdout().replaceAll("\\r?\\n", "");
5865
System.out.println("output = " + output);
5966
assertThat(output).contains("password1");
@@ -63,11 +70,11 @@ public void readSecondSecretPathWithCli() throws IOException, InterruptedExcepti
6370
}
6471

6572
@Test
66-
public void readFirstSecretPathOverHttpApi() throws InterruptedException {
73+
public void readFirstSecretPathOverHttpApi() {
6774
Response response = given()
6875
.header("X-Vault-Token", VAULT_TOKEN)
6976
.when()
70-
.get("http://" + getHostAndPort() + "/v1/secret/data/testing1")
77+
.get(vaultContainer.getHttpHostAddress() + "/v1/secret/data/testing1")
7178
.thenReturn();
7279
assertThat(response.body().jsonPath().getString("data.data.top_secret")).isEqualTo("password123");
7380
}
@@ -77,7 +84,7 @@ public void readSecondSecretPathOverHttpApi() throws InterruptedException {
7784
Response response = given()
7885
.header("X-Vault-Token", VAULT_TOKEN)
7986
.when()
80-
.get("http://" + getHostAndPort() + "/v1/secret/data/testing2")
87+
.get(vaultContainer.getHttpHostAddress() + "/v1/secret/data/testing2")
8188
.andReturn();
8289

8390
assertThat(response.body().jsonPath().getString("data.data.secret_one")).contains("password1");
@@ -91,13 +98,67 @@ public void readTransitKeyOverHttpApi() throws InterruptedException {
9198
Response response = given()
9299
.header("X-Vault-Token", VAULT_TOKEN)
93100
.when()
94-
.get("http://" + getHostAndPort() + "/v1/transit/keys/my-key")
101+
.get(vaultContainer.getHttpHostAddress() + "/v1/transit/keys/my-key")
95102
.thenReturn();
96103

97104
assertThat(response.body().jsonPath().getString("data.name")).isEqualTo("my-key");
98105
}
99106

100-
private String getHostAndPort() {
101-
return vaultContainer.getHost() + ":" + vaultContainer.getMappedPort(8200);
107+
@Test
108+
// readWithLibrary {
109+
public void readFirstSecretPathOverClientLibrary() throws Exception {
110+
final VaultConfig config = new VaultConfig()
111+
.address(vaultContainer.getHttpHostAddress())
112+
.token(VAULT_TOKEN)
113+
.build();
114+
115+
final Vault vault = new Vault(config);
116+
117+
final Map<String, String> value = vault.logical().read("secret/testing1").getData();
118+
119+
assertThat(value).containsEntry("top_secret", "password123");
120+
}
121+
122+
// }
123+
124+
@Test
125+
public void readSecondSecretPathOverClientLibrary() throws Exception {
126+
final VaultConfig config = new VaultConfig()
127+
.address(vaultContainer.getHttpHostAddress())
128+
.token(VAULT_TOKEN)
129+
.build();
130+
131+
final Vault vault = new Vault(config);
132+
final Map<String, String> value = vault.logical().read("secret/testing2").getData();
133+
134+
assertThat(value)
135+
.containsEntry("secret_one", "password1")
136+
.containsEntry("secret_two", "password2")
137+
.containsEntry("secret_three", "[\"password3\",\"password3\"]")
138+
.containsEntry("secret_four", "password4");
139+
}
140+
141+
@Test
142+
public void writeSecretOverClientLibrary() throws Exception {
143+
final VaultConfig config = new VaultConfig()
144+
.address(vaultContainer.getHttpHostAddress())
145+
.token(VAULT_TOKEN)
146+
.build();
147+
148+
final Vault vault = new Vault(config);
149+
150+
final Map<String, Object> secrets = new HashMap<>();
151+
secrets.put("value", "world");
152+
secrets.put("other_value", "another world");
153+
154+
// Write operation
155+
final LogicalResponse writeResponse = vault.logical().write("secret/hello", secrets);
156+
157+
assertThat(writeResponse.getRestResponse().getStatus()).isEqualTo(200);
158+
159+
// Read operation
160+
final Map<String, String> value = vault.logical().read("secret/hello").getData();
161+
162+
assertThat(value).containsEntry("value", "world").containsEntry("other_value", "another world");
102163
}
103164
}

modules/vault/src/test/java/org/testcontainers/vault/VaultTestImages.java

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)