aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-main/src
diff options
context:
space:
mode:
authorJacek <jacek.poreda@sonarsource.com>2021-04-19 11:30:44 +0200
committersonartech <sonartech@sonarsource.com>2021-04-23 20:03:29 +0000
commitdf28c5d95838beec4bb98059baab9b2cd70022fe (patch)
tree16b6c133ca63a1ffe3c30fdcfa23b00dfceeceea /server/sonar-main/src
parentd8109105b156ece5352c95c0b1f2095fffcb69c2 (diff)
downloadsonarqube-df28c5d95838beec4bb98059baab9b2cd70022fe.tar.gz
sonarqube-df28c5d95838beec4bb98059baab9b2cd70022fe.zip
SONAR-14583 Use Elasticsearch password in HTTP clients
Diffstat (limited to 'server/sonar-main/src')
-rw-r--r--server/sonar-main/src/main/java/org/sonar/application/AppStateFactory.java4
-rw-r--r--server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java3
-rw-r--r--server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java27
-rw-r--r--server/sonar-main/src/test/java/org/sonar/application/es/EsConnectorImplTest.java14
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)