Skip to content

Commit

Permalink
Elasticsearch: Add withPassword(String) method for secure access (#2321)
Browse files Browse the repository at this point in the history
  • Loading branch information
dadoonet committed Oct 21, 2020
1 parent 443307c commit ec43c31
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/modules/elasticsearch.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ or set `client.transport.ignore_cluster_name` to `true`.
## Secure your Elasticsearch cluster

The default distribution of Elasticsearch comes with the basic license which contains security feature.
You can turn on security by providing some extra environment settings:
You can turn on security by providing a password:

<!--codeinclude-->
[HttpClient](../../modules/elasticsearch/src/test/java/org/testcontainers/elasticsearch/ElasticsearchContainerTest.java) inside_block:httpClientSecuredContainer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class ElasticsearchContainer extends GenericContainer<ElasticsearchContai
*/
@Deprecated
protected static final String DEFAULT_TAG = "7.9.2";
private boolean isOss = false;

/**
* @deprecated use {@link ElasticsearchContainer(DockerImageName)} instead
Expand All @@ -65,6 +66,10 @@ public ElasticsearchContainer(final DockerImageName dockerImageName) {

dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME, DEFAULT_OSS_IMAGE_NAME);

if (dockerImageName.isCompatibleWith(DEFAULT_OSS_IMAGE_NAME)) {
this.isOss = true;
}

logger().info("Starting an elasticsearch container using [{}]", dockerImageName);
withNetworkAliases("elasticsearch-" + Base58.randomString(6));
withEnv("discovery.type", "single-node");
Expand All @@ -75,6 +80,22 @@ public ElasticsearchContainer(final DockerImageName dockerImageName) {
.withStartupTimeout(Duration.ofMinutes(2)));
}

/**
* Define the Elasticsearch password to set. It enables security behind the scene.
* It's not possible to use security with the oss image.
* @param password Password to set
* @return this
*/
public ElasticsearchContainer withPassword(String password) {
if (isOss) {
throw new IllegalArgumentException("You can not activate security on Elastic OSS Image. " +
"Please switch to the default distribution");
}
withEnv("ELASTIC_PASSWORD", password);
withEnv("xpack.security.enabled", "true");
return this;
}

public String getHttpHostAddress() {
return getHost() + ":" + getMappedPort(ELASTICSEARCH_DEFAULT_PORT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ public void elasticsearchDefaultTest() throws IOException {
@Test
public void elasticsearchSecuredTest() throws IOException {
try (ElasticsearchContainer container = new ElasticsearchContainer(ELASTICSEARCH_IMAGE)
.withEnv("ELASTIC_PASSWORD", ELASTICSEARCH_PASSWORD)
.withEnv("xpack.security.enabled", "true")
) {
.withPassword(ELASTICSEARCH_PASSWORD)) {
container.start();

// The cluster should be secured so it must fail when we try to access / without credentials
Expand Down Expand Up @@ -191,8 +189,7 @@ public void restClientSecuredClusterHealth() throws IOException {
// Create the elasticsearch container.
try (ElasticsearchContainer container = new ElasticsearchContainer(ELASTICSEARCH_IMAGE)
// With a password
.withEnv("ELASTIC_PASSWORD", ELASTICSEARCH_PASSWORD)
.withEnv("xpack.security.enabled", "true")) {
.withPassword(ELASTICSEARCH_PASSWORD)) {
// Start the container. This step might take some time...
container.start();

Expand Down Expand Up @@ -239,6 +236,19 @@ public void transportClientClusterHealth() {
// }
}

@Test
public void incompatibleSettingsTest() {
// The OSS image can not use security feature
assertThrows("We should not be able to activate security with an OSS License",
IllegalArgumentException.class,
() -> new ElasticsearchContainer(
DockerImageName
.parse("docker.elastic.co/elasticsearch/elasticsearch-oss")
.withTag(ELASTICSEARCH_VERSION))
.withPassword("foo")
);
}

private RestClient getClient(ElasticsearchContainer container) {
if (client == null) {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
Expand Down

0 comments on commit ec43c31

Please sign in to comment.