Sidecar: add accept-all-ssl-certificates property in order to be able to use https health checks with self-signed certificates (#3224)

* Add acceptAllSslCertificates in SidecarProperties
This commit is contained in:
Fabri Di Napoli
2018-10-15 17:02:09 +02:00
committed by Ryan Baxter
parent 9eb5e64cd0
commit 53e7464a6e
6 changed files with 70 additions and 10 deletions

View File

@@ -2021,6 +2021,8 @@ info:
url: https://github.com/spring-cloud-samples
----
To enable the health check request to accept all certificates when using HTTPs set `sidecar.accept-all-ssl-certificates` to `true.
[[retrying-failed-requests]]
== Retrying Failed Requests

View File

@@ -16,22 +16,26 @@
package org.springframework.cloud.netflix.sidecar;
import java.net.URI;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.util.Map;
/**
* @author Spencer Gibb
* @author Fabrizio Di Napoli
*/
public class LocalApplicationHealthIndicator extends AbstractHealthIndicator {
@Autowired
private SidecarProperties properties;
@Autowired
private RestTemplate restTemplate;
@SuppressWarnings("unchecked")
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
@@ -40,12 +44,13 @@ public class LocalApplicationHealthIndicator extends AbstractHealthIndicator {
builder.up();
return;
}
Map<String, Object> map = new RestTemplate().getForObject(uri, Map.class);
Map<String, Object> map = restTemplate.getForObject(uri, Map.class);
Object status = map.get("status");
if (status != null && status instanceof String) {
if (status instanceof String) {
builder.status(status.toString());
}
else if (status != null && status instanceof Map) {
else if (status instanceof Map) {
Map<String, Object> statusMap = (Map<String, Object>) status;
Object code = statusMap.get("code");
if (code != null) {
@@ -63,5 +68,4 @@ public class LocalApplicationHealthIndicator extends AbstractHealthIndicator {
private Health.Builder getWarning(Health.Builder builder) {
return builder.unknown().withDetail("warning", "no status field in response");
}
}

View File

@@ -16,6 +16,11 @@
package org.springframework.cloud.netflix.sidecar;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceId;
import org.springframework.beans.factory.annotation.Autowired;
@@ -33,10 +38,12 @@ import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvi
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.StringUtils;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.discovery.EurekaClientConfig;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
@@ -54,6 +61,7 @@ import java.util.Map;
*
* @author Spencer Gibb
* @author Ryan Baxter
* @author Fabrizio Di Napoli
*
* @see EurekaInstanceConfigBeanConfiguration
*/
@@ -153,7 +161,25 @@ public class SidecarConfiguration {
final LocalApplicationHealthIndicator healthIndicator) {
return new LocalApplicationHealthCheckHandler(healthIndicator);
}
}
@Bean
@ConditionalOnMissingClass("org.apache.http.client.HttpClient")
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
@ConditionalOnClass(HttpClient.class)
@ConditionalOnProperty(value = "sidecar.accept-all-ssl-certificates")
public RestTemplate sslRestTemplate() {
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return new RestTemplate(requestFactory);
}
@Bean

View File

@@ -27,6 +27,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Spencer Gibb
* @author Gregor Zurowski
* @author Fabrizio Di Napoli
*/
@ConfigurationProperties("sidecar")
public class SidecarProperties {
@@ -43,6 +44,8 @@ public class SidecarProperties {
private String ipAddress;
private boolean acceptAllSslCertificates;
public URI getHealthUri() {
return healthUri;
}
@@ -83,6 +86,14 @@ public class SidecarProperties {
this.ipAddress = ipAddress;
}
public boolean acceptAllSslCertificates() {
return acceptAllSslCertificates;
}
public void setAcceptAllSslCertificates(boolean acceptAllSslCertificates) {
this.acceptAllSslCertificates = acceptAllSslCertificates;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -92,12 +103,13 @@ public class SidecarProperties {
Objects.equals(homePageUri, that.homePageUri) &&
port == that.port &&
Objects.equals(hostname, that.hostname) &&
Objects.equals(ipAddress, that.ipAddress);
Objects.equals(ipAddress, that.ipAddress) &&
Objects.equals(acceptAllSslCertificates, that.acceptAllSslCertificates);
}
@Override
public int hashCode() {
return Objects.hash(healthUri, homePageUri, port, hostname, ipAddress);
return Objects.hash(healthUri, homePageUri, port, hostname, ipAddress, acceptAllSslCertificates);
}
@Override
@@ -107,7 +119,8 @@ public class SidecarProperties {
.append("homePageUri=").append(homePageUri).append(", ")
.append("port=").append(port).append(", ")
.append("hostname='").append(hostname).append("', ")
.append("ipAddress='").append(ipAddress).append("'}")
.append("ipAddress='").append(ipAddress).append("', ")
.append("acceptAllSslCertificates='").append(acceptAllSslCertificates).append("'}")
.toString();
}

View File

@@ -16,6 +16,7 @@
package org.springframework.cloud.netflix.sidecar;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -26,6 +27,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import org.springframework.web.client.RestTemplate;
public class SidecarApplicationTests {
@@ -128,4 +130,16 @@ public class SidecarApplicationTests {
assertThat(this.config.getHealthCheckUrl(), equalTo("http://mhhost2:0/foo/health"));
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, value = {"sidecar.accept-all-ssl-certificates=false"})
public static class AcceptAllSslCertificatesContext {
@Autowired
RestTemplate restTemplate;
@Test
public void testUseRestTemplateWhenHttpClientIsNotAvailable() {
assertNull(restTemplate.getRequestFactory());
}
}
}

View File

@@ -7,6 +7,7 @@ spring:
sidecar:
port: 8000
health-uri: http://localhost:8000/src/test/resources/health.json
accept-all-ssl-certificates: true
eureka:
instance: