Skip to content

Commit 5048487

Browse files
pioorgkiview
andauthored
Added KibanaContainer (#11493)
Co-authored-by: Kevin Wittek <kiview@users.noreply.github.com>
1 parent 3878311 commit 5048487

5 files changed

Lines changed: 1223 additions & 0 deletions

File tree

docs/modules/elasticsearch.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,33 @@ You can turn on security by providing a password:
3030
[HttpClient](../../modules/elasticsearch/src/test/java/org/testcontainers/elasticsearch/ElasticsearchContainerTest.java) inside_block:httpClientSecuredContainer
3131
<!--/codeinclude-->
3232

33+
## Kibana container
34+
35+
This module also provides a `KibanaContainer` for testing with [Kibana](https://www.elastic.co/kibana).
36+
Kibana requires a connection to Elasticsearch and `KibanaContainer` supports two modes: managed and external.
37+
38+
### Managed mode
39+
40+
In managed mode, `KibanaContainer` automatically connects to an `ElasticsearchContainer`:
41+
42+
<!--codeinclude-->
43+
[Kibana with Elasticsearch](../../modules/elasticsearch/src/test/java/org/testcontainers/elasticsearch/KibanaContainerTest.java) inside_block:managedModeCanStartAndReachElasticsearchInSameExplicitNetwork
44+
<!--/codeinclude-->
45+
46+
When using managed mode with explicit networks, both containers must share the same `Network` instance.
47+
Alternatively, you can omit the network configuration entirely, and `KibanaContainer` will do its best effort to create a shared, ad-hoc network automatically.
48+
49+
### External mode
50+
51+
In external mode, `KibanaContainer` connects to an external Elasticsearch instance via URL and using provided credentials:
52+
53+
<!--codeinclude-->
54+
[Kibana with external Elasticsearch](../../modules/elasticsearch/src/test/java/org/testcontainers/elasticsearch/KibanaContainerTest.java) inside_block:externalModeCanWorkWithUsernamePassword
55+
<!--/codeinclude-->
56+
57+
For external mode with HTTPS, use `withElasticsearchCaCertificate()` to provide the CA certificate.
58+
You can authenticate using either username/password (`withElasticsearchCredentials()`) or service account tokens (`withElasticsearchServiceAccountToken()`).
59+
3360
## Adding this module to your project dependencies
3461

3562
Add the following dependency to your `pom.xml`/`build.gradle` file:

modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/ElasticsearchContainer.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,99 @@ public ElasticsearchContainer withCertPath(String certPath) {
209209
return this;
210210
}
211211

212+
String getCertPath() {
213+
return certPath;
214+
}
215+
212216
public String getHttpHostAddress() {
213217
return getHost() + ":" + getMappedPort(ELASTICSEARCH_DEFAULT_PORT);
214218
}
215219

220+
/**
221+
* Checks env first if this implies HTTP/HTTPS.
222+
* Otherwise, detects the scheme used by Elasticsearch using <code>curl</code>
223+
*
224+
* @return "http" or "https"
225+
*/
226+
String getHttpScheme() {
227+
String securityEnabled = getEnvMap().get("xpack.security.enabled");
228+
String httpSslEnabled = getEnvMap().get("xpack.security.http.ssl.enabled");
229+
230+
// Respect explicit user config
231+
if ("false".equalsIgnoreCase(securityEnabled) || "false".equalsIgnoreCase(httpSslEnabled)) {
232+
return "http";
233+
}
234+
if ("true".equalsIgnoreCase(httpSslEnabled)) {
235+
return "https";
236+
}
237+
238+
if (!isRunning()) {
239+
throw new IllegalStateException(
240+
"Cannot determine HTTP scheme: environment variables are not set and container is not running for curl probe"
241+
);
242+
}
243+
244+
ExecResult httpsResult = null;
245+
ExecResult httpResult = null;
246+
try {
247+
// HTTPS probe: any HTTP response (200/401/403/...) => scheme is HTTPS.
248+
// http_code == 000 means we didn't get an HTTP response (TLS/connect failure/timeout).
249+
httpsResult =
250+
execInContainer(
251+
"curl",
252+
"-sS",
253+
"-k",
254+
"--connect-timeout",
255+
"2",
256+
"--max-time",
257+
"4",
258+
"-o",
259+
"/dev/null",
260+
"-w",
261+
"%{http_code}",
262+
"https://localhost:" + ELASTICSEARCH_DEFAULT_PORT + "/"
263+
);
264+
if (httpsResult.getExitCode() == 0 && !"000".equals(httpsResult.getStdout().trim())) {
265+
return "https";
266+
}
267+
268+
// HTTP probe
269+
httpResult =
270+
execInContainer(
271+
"curl",
272+
"-sS",
273+
"--connect-timeout",
274+
"2",
275+
"--max-time",
276+
"4",
277+
"-o",
278+
"/dev/null",
279+
"-w",
280+
"%{http_code}",
281+
"http://localhost:" + ELASTICSEARCH_DEFAULT_PORT + "/"
282+
);
283+
if (httpResult.getExitCode() == 0 && !"000".equals(httpResult.getStdout().trim())) {
284+
return "http";
285+
}
286+
} catch (Exception e) {
287+
throw new RuntimeException("Failed to detect protocol via curl", e);
288+
}
289+
290+
throw new RuntimeException(
291+
String.format(
292+
"Failed to detect protocol via curl. Both HTTPS and HTTP probes failed. " +
293+
"HTTPS probe - exit code: %d, stdout: %s, stderr: %s; " +
294+
"HTTP probe - exit code: %d, stdout: %s, stderr: %s",
295+
httpsResult.getExitCode(),
296+
httpsResult.getStdout(),
297+
httpsResult.getStderr(),
298+
httpResult.getExitCode(),
299+
httpResult.getStdout(),
300+
httpResult.getStderr()
301+
)
302+
);
303+
}
304+
216305
// The TransportClient will be removed in Elasticsearch 8. No need to expose this port anymore in the future.
217306
@Deprecated
218307
public InetSocketAddress getTcpHost() {

0 commit comments

Comments
 (0)