From 3b85ada2e4e08727eff93f222b88e54bd5071d3f Mon Sep 17 00:00:00 2001 From: Will Droste Date: Tue, 13 Feb 2018 12:22:09 -0600 Subject: [PATCH] Adds configuration properties for TLSConfig in ConsulClient. fixes gh-360 --- ...ConsulPropertySourceLocatorFilesTests.java | 4 +- .../cloud/consul/ConsulAutoConfiguration.java | 16 ++++++- .../cloud/consul/ConsulProperties.java | 22 +++++++++ .../consul/ConsulAutoConfigurationTests.java | 42 ++++++++++++++++++ .../src/test/resources/server.jks | Bin 0 -> 2239 bytes .../src/test/resources/trustStore.jks | Bin 0 -> 1405 bytes 6 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulAutoConfigurationTests.java create mode 100644 spring-cloud-consul-core/src/test/resources/server.jks create mode 100644 spring-cloud-consul-core/src/test/resources/trustStore.jks diff --git a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFilesTests.java b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFilesTests.java index 02de441b..a40ac4bf 100644 --- a/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFilesTests.java +++ b/spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFilesTests.java @@ -95,7 +95,9 @@ public class ConsulPropertySourceLocatorFilesTests { @After public void teardown() { this.client.deleteKVValues(PREFIX); - this.context.close(); + if (this.context != null) { + this.context.close(); + } } @Test diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java index d8d178a2..3e6d2733 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulAutoConfiguration.java @@ -16,7 +16,10 @@ package org.springframework.cloud.consul; +import com.ecwid.consul.transport.TLSConfig; +import com.ecwid.consul.v1.ConsulClient; import org.aspectj.lang.annotation.Aspect; + import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.Endpoint; @@ -32,8 +35,6 @@ import org.springframework.retry.annotation.Retryable; import org.springframework.retry.interceptor.RetryInterceptorBuilder; import org.springframework.retry.interceptor.RetryOperationsInterceptor; -import com.ecwid.consul.v1.ConsulClient; - /** * @author Spencer Gibb */ @@ -51,6 +52,17 @@ public class ConsulAutoConfiguration { @Bean @ConditionalOnMissingBean public ConsulClient consulClient(ConsulProperties consulProperties) { + if (consulProperties.getTls() != null) { + ConsulProperties.TLSConfig tls = consulProperties.getTls(); + TLSConfig tlsConfig = new TLSConfig( + tls.getKeyStoreInstanceType(), + tls.getCertificatePath(), + tls.getCertificatePassword(), + tls.getKeyStorePath(), + tls.getKeyStorePassword() + ); + return new ConsulClient(consulProperties.getHost(), consulProperties.getPort(), tlsConfig); + } return new ConsulClient(consulProperties.getHost(), consulProperties.getPort()); } diff --git a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulProperties.java b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulProperties.java index 6c5f686e..3cfa9de7 100644 --- a/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulProperties.java +++ b/spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulProperties.java @@ -18,6 +18,7 @@ package org.springframework.cloud.consul; import javax.validation.constraints.NotNull; +import com.ecwid.consul.transport.TLSConfig.KeyStoreInstanceType; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -40,4 +41,25 @@ public class ConsulProperties { /** Is spring cloud consul enabled */ private boolean enabled = true; + + /** configuration for TLS */ + private TLSConfig tls; + + @Data + public static class TLSConfig { + /** Type of key framework to use. */ + private KeyStoreInstanceType keyStoreInstanceType; + + /** Path to an external keystore */ + private String keyStorePath; + + /** Password to an external keystore */ + private String keyStorePassword; + + /**File path to the certificate. */ + private String certificatePath; + + /** Password to open the certificate. */ + private String certificatePassword; + } } diff --git a/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulAutoConfigurationTests.java b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulAutoConfigurationTests.java new file mode 100644 index 00000000..fe226ba1 --- /dev/null +++ b/spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulAutoConfigurationTests.java @@ -0,0 +1,42 @@ +package org.springframework.cloud.consul; + +import com.ecwid.consul.transport.DefaultHttpsTransport; +import com.ecwid.consul.transport.HttpTransport; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.ConsulRawClient; +import com.ecwid.consul.v1.catalog.CatalogConsulClient; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(properties = {"spring.cloud.consul.tls.key-store-instance-type=JKS", + "spring.cloud.consul.tls.key-store-path=src/test/resources/server.jks", + "spring.cloud.consul.tls.key-store-password=letmein", + "spring.cloud.consul.tls.certificate-path=src/test/resources/trustStore.jks", + "spring.cloud.consul.tls.certificate-password=change_me", }) +public class ConsulAutoConfigurationTests { + + @Autowired + private ConsulClient consulClient; + + @Test + public void tlsConfigured() { + CatalogConsulClient client = (CatalogConsulClient) ReflectionTestUtils.getField(consulClient, "catalogClient"); + ConsulRawClient rawClient = (ConsulRawClient) ReflectionTestUtils.getField(client, "rawClient"); + HttpTransport httpTransport = (HttpTransport) ReflectionTestUtils.getField(rawClient, "httpTransport"); + assertThat(httpTransport).isInstanceOf(DefaultHttpsTransport.class); + } + + @EnableAutoConfiguration + @SpringBootConfiguration + protected static class TestConfig {} +} diff --git a/spring-cloud-consul-core/src/test/resources/server.jks b/spring-cloud-consul-core/src/test/resources/server.jks new file mode 100644 index 0000000000000000000000000000000000000000..560be5fed77efd4c75d2ca49a33bc6eb616b1af4 GIT binary patch literal 2239 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 X87oqp`%q!o8#z_2ZOluhie~)>Rnq1* literal 0 HcmV?d00001 diff --git a/spring-cloud-consul-core/src/test/resources/trustStore.jks b/spring-cloud-consul-core/src/test/resources/trustStore.jks new file mode 100644 index 0000000000000000000000000000000000000000..9f599362aef2cd5425b50b6a5dc9f20731c0cd94 GIT binary patch literal 1405 zcmezO_TO6u1_mY|W(3om$)&|5`MJ8ui9nG!>r+K<7+53pObsj<7+9?hnpn*ZnwaGm zFf%bSF|pWN89XuIW#iOp^Jx3d%gD&f%3$DX$Zf#M#vIDRCd?G-ZO9Ll2Xfej*?jWz zQu6Z*g$x8h0$jqJA*sbB{zd7|j)sB;{2(!AVU7}@m|lKSx`CWHuc5htrGcS=iK&UP zL6kVJk-33|u>q7zEo+*Xl#o5Z$jZRn#Kg~F(8R>W)WpQd(5Uw2g82`xU4=4@Cbcsa zzrLHI9-sZ(KBHFeT88G{`%=>vl(POz-RjkJIYvY0%HM0p53swwPb^=$bYI)fNp&W3 zKIo^3>=9OzU9_w)t(|ZEeW!V8&2#iMjYRU#ziQo{yL|UI@5-VRby6{xOX3f?>HK)j zvgEu--zL6k@?16HJ^R+b4A|!66K?s~aLcB*U(4S86fT|rWX`uoAH@GOnSOfI5I50B zCArOZi(DPQ&6F6sZTtBRPA)S@-^G8X>R{QIlg<98&)&Uhneh= zdaiTf+{JV2dh2|?tH&*yto}#+t6^1Q7@tVNZ6EJMi?u;4sw&(Qbr~BgSN%S)cJcJI zi1};kiVC83oNPU_IBvD({*rk0yGvSbAK!iC(9X`ORlJh2ncKR857=8Q2o2)bo%Mi~ zW&KKr%5H(gx#GSn@1EZge57w){A{Mli>oqKxxETnr24WZ_3UvB-mEX;^eErMKL4}r zoi*QU0*(A9e9%{1zQ>B!g-=a&uBh79$JasyG#5JG(Aoa{mHUHct+fez?jI}DJ|n}U zvVHjyftjDojVix6U6+W>{x9ofJ(nZuhedJb+^LE(+4C^D>HuDZTqcww>rnwzop(&cloKR2z7-_ zKiH;LVBDn93Ld7Hu1;9PWx9#$xCd{%_T)={dNmeR{!iLG@BZFZwV4G0Tn1anI5tAIuAUZhZK} zd&V`7Ev891bXBM{oZ`S+&`Q@2+%%1=%{jJC!CYxNLisRQ9_)b76`=mE5&c z!JG6SzP(~*GG(*z!gX0}b2%>0&Hh!Uch2;Gnd8N1wnzO7{@8xmetG}-kL&v9TB-dw zzH+ruU~2QGjS};F&U)_rdem^~gXW!W%f(t)gt&fbW zJ9$jXD6;d!wh!k#WOhs6GTe4fG2zY8@RH=8pNywC%ntnRoMaU!UwKqg%&}sV=|d*< zTi2Po?;8~#w7=G=yvnm^UK+2*B>kYA=MPeXezfdJlbH5m_xpx!=gZglC-c|cUy*Ke JJ*{TuD*(XESdah! literal 0 HcmV?d00001