diff options
author | Jacek <jacek.poreda@sonarsource.com> | 2021-04-19 11:30:44 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2021-04-23 20:03:29 +0000 |
commit | df28c5d95838beec4bb98059baab9b2cd70022fe (patch) | |
tree | 16b6c133ca63a1ffe3c30fdcfa23b00dfceeceea /server/sonar-main/src | |
parent | d8109105b156ece5352c95c0b1f2095fffcb69c2 (diff) | |
download | sonarqube-df28c5d95838beec4bb98059baab9b2cd70022fe.tar.gz sonarqube-df28c5d95838beec4bb98059baab9b2cd70022fe.zip |
SONAR-14583 Use Elasticsearch password in HTTP clients
Diffstat (limited to 'server/sonar-main/src')
4 files changed, 42 insertions, 6 deletions
diff --git a/server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java b/server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java index 28c2e0001a4..936dcb64996 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java +++ b/server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java @@ -41,6 +41,7 @@ import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HOST; import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_HZ_PORT; import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME; import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_HOSTS; +import static org.sonar.process.ProcessProperties.Property.CLUSTER_SEARCH_PASSWORD; public class AppStateFactory { private final AppSettings settings; @@ -74,6 +75,7 @@ public class AppStateFactory { Set<HostAndPort> hostAndPorts = Arrays.stream(searchHosts.split(",")) .map(HostAndPort::fromString) .collect(Collectors.toSet()); - return new EsConnectorImpl(hostAndPorts); + String searchPassword = props.value(CLUSTER_SEARCH_PASSWORD.getKey()); + return new EsConnectorImpl(hostAndPorts, searchPassword); } } diff --git a/server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java b/server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java index 657d3a693e8..de47af4f884 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java @@ -32,7 +32,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Properties; import java.util.function.Supplier; import org.slf4j.Logger; @@ -107,7 +106,7 @@ public class ProcessLauncherImpl implements ProcessLauncher { if (processId == ProcessId.ELASTICSEARCH) { checkArgument(esInstallation != null, "Incorrect configuration EsInstallation is null"); EsConnectorImpl esConnector = new EsConnectorImpl(singleton(HostAndPort.fromParts(esInstallation.getHost(), - esInstallation.getHttpPort()))); + esInstallation.getHttpPort())), esInstallation.getBootstrapPassword()); return new EsManagedProcess(process, processId, esConnector); } else { ProcessCommands commands = allProcessesCommands.createAfterClean(processId.getIpcIndex()); diff --git a/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java b/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java index f5dbca10dcc..1c5a3263df1 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java @@ -26,11 +26,16 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import javax.annotation.Nullable; import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.impl.client.BasicCredentialsProvider; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.slf4j.Logger; @@ -39,14 +44,17 @@ import org.slf4j.LoggerFactory; import static org.elasticsearch.common.unit.TimeValue.timeValueSeconds; public class EsConnectorImpl implements EsConnector { + private static final String ES_USERNAME = "elastic"; private static final Logger LOG = LoggerFactory.getLogger(EsConnectorImpl.class); private final AtomicReference<RestHighLevelClient> restClient = new AtomicReference<>(null); private final Set<HostAndPort> hostAndPorts; + private final String searchPassword; - public EsConnectorImpl(Set<HostAndPort> hostAndPorts) { + public EsConnectorImpl(Set<HostAndPort> hostAndPorts, @Nullable String searchPassword) { this.hostAndPorts = hostAndPorts; + this.searchPassword = searchPassword; } @Override @@ -95,7 +103,22 @@ public class EsConnectorImpl implements EsConnector { .collect(Collectors.joining(", ")); LOG.debug("Connected to Elasticsearch node: [{}]", addresses); } - return new RestHighLevelClient(RestClient.builder(httpHosts)); + + RestClientBuilder builder = RestClient.builder(httpHosts) + .setHttpClientConfigCallback(httpClientBuilder -> { + if (searchPassword != null) { + BasicCredentialsProvider provider = getBasicCredentialsProvider(searchPassword); + httpClientBuilder.setDefaultCredentialsProvider(provider); + } + return httpClientBuilder; + }); + return new RestHighLevelClient(builder); + } + + private static BasicCredentialsProvider getBasicCredentialsProvider(String searchPassword) { + BasicCredentialsProvider provider = new BasicCredentialsProvider(); + provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(ES_USERNAME, searchPassword)); + return provider; } } diff --git a/server/sonar-main/src/test/java/org/sonar/application/es/EsConnectorImplTest.java b/server/sonar-main/src/test/java/org/sonar/application/es/EsConnectorImplTest.java index d92dfb3f0b2..9c5e3d0d914 100644 --- a/server/sonar-main/src/test/java/org/sonar/application/es/EsConnectorImplTest.java +++ b/server/sonar-main/src/test/java/org/sonar/application/es/EsConnectorImplTest.java @@ -59,7 +59,7 @@ public class EsConnectorImplTest { @Rule public MockWebServer mockWebServer = new MockWebServer(); - EsConnectorImpl underTest = new EsConnectorImpl(Sets.newHashSet(HostAndPort.fromParts(mockWebServer.getHostName(), mockWebServer.getPort()))); + EsConnectorImpl underTest = new EsConnectorImpl(Sets.newHashSet(HostAndPort.fromParts(mockWebServer.getHostName(), mockWebServer.getPort())), null); @After public void after() { @@ -82,6 +82,18 @@ public class EsConnectorImplTest { .hasValue(ClusterHealthStatus.YELLOW); } + @Test + public void should_add_authentication_header() throws InterruptedException { + mockServerResponse(200, JSON_SUCCESS_RESPONSE); + String password = "test-password"; + + EsConnectorImpl underTest = new EsConnectorImpl(Sets.newHashSet(HostAndPort.fromParts(mockWebServer.getHostName(), mockWebServer.getPort())), password); + + assertThat(underTest.getClusterHealthStatus()) + .hasValue(ClusterHealthStatus.YELLOW); + assertThat(mockWebServer.takeRequest().getHeader("Authorization")).isEqualTo("Basic ZWxhc3RpYzp0ZXN0LXBhc3N3b3Jk"); + } + private void mockServerResponse(int httpCode, String jsonResponse) { mockWebServer.enqueue(new MockResponse() .setResponseCode(httpCode) |