diff --git a/docs/src/main/asciidoc/spring-cloud-config.adoc b/docs/src/main/asciidoc/spring-cloud-config.adoc
index de9701f5..aecd11aa 100644
--- a/docs/src/main/asciidoc/spring-cloud-config.adoc
+++ b/docs/src/main/asciidoc/spring-cloud-config.adoc
@@ -105,6 +105,7 @@ If there are profile-specific YAML (or properties) files, these are also applied
Higher precedence translates to a `PropertySource` listed earlier in the `Environment`.
(These same rules apply in a standalone Spring Boot application.)
+You can set spring.cloud.config.server.accept-empty to false so that Server would return a HTTP 404 status, if the application is not found.By default, this flag is set to true.
==== Git Backend
The default implementation of `EnvironmentRepository` uses a Git backend, which is very convenient for managing upgrades and physical
diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java
index 4bf3d3f4..b3c8e592 100644
--- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java
+++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java
@@ -233,14 +233,16 @@ public class ConfigClientProperties {
String bare = UriComponentsBuilder.fromHttpUrl(uri).userInfo(null).build()
.toUriString();
result.uri = bare;
- // handle the password only case
+
+ // if userInfo does not contain a :, then append a : to it
if (!userInfo.contains(":")) {
userInfo = userInfo + ":";
}
- String[] split = userInfo.split(":");
+
+ int sepIndex=userInfo.indexOf(":");
// set username and password from uri
- result.username = split[0];
- result.password = split[1];
+ result.username = userInfo.substring(0, sepIndex);
+ result.password = userInfo.substring(sepIndex +1);
// override password if explicitly set
if (explicitCredentials.password != null) {
diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/ConfigClientPropertiesTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/ConfigClientPropertiesTests.java
index 8d55e2ef..eda6afae 100644
--- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/ConfigClientPropertiesTests.java
+++ b/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/ConfigClientPropertiesTests.java
@@ -59,7 +59,51 @@ public class ConfigClientPropertiesTests {
assertEquals("foo", locator.getUsername());
assertEquals("secret", locator.getPassword());
}
+
+ @Test
+ public void testIfNoColonPresentInUriCreds() {
+ locator.setUri("http://foobar@localhost:9999");
+ locator.setPassword("secret");
+ assertEquals("http://localhost:9999", locator.getRawUri());
+ assertEquals("foobar", locator.getUsername());
+ assertEquals("secret", locator.getPassword());
+ }
+ @Test
+ public void testIfColonPresentAtTheEndInUriCreds() {
+ locator.setUri("http://foobar:@localhost:9999");
+ locator.setPassword("secret");
+ assertEquals("http://localhost:9999", locator.getRawUri());
+ assertEquals("foobar", locator.getUsername());
+ assertEquals("secret", locator.getPassword());
+ }
+
+ @Test
+ public void testIfColonPresentAtTheStartInUriCreds() {
+ locator.setUri("http://:foobar@localhost:9999");
+ assertEquals("http://localhost:9999", locator.getRawUri());
+ assertEquals("", locator.getUsername());
+ assertEquals("foobar", locator.getPassword());
+ }
+
+ @Test
+ public void testIfColonPresentAtTheStartAndEndInUriCreds() {
+ locator.setUri("http://:foobar:@localhost:9999");
+ assertEquals("http://localhost:9999", locator.getRawUri());
+ assertEquals("", locator.getUsername());
+ assertEquals("foobar:", locator.getPassword());
+ }
+
+
+ @Test
+ public void testIfsolonPresentAtTheStartAndEndInUriCreds() {
+ locator.setUri("http:// @localhost:9999");
+ locator.setPassword("secret");
+ assertEquals("http://localhost:9999", locator.getRawUri());
+ assertEquals(" ", locator.getUsername());
+ assertEquals("secret", locator.getPassword());
+ }
+
@Test
public void changeNameInOverride() {
locator.setName("one");
diff --git a/spring-cloud-config-dependencies/pom.xml b/spring-cloud-config-dependencies/pom.xml
index c1a24c50..5e8ba76a 100644
--- a/spring-cloud-config-dependencies/pom.xml
+++ b/spring-cloud-config-dependencies/pom.xml
@@ -13,6 +13,9 @@
pom
spring-cloud-config-dependencies
Spring Cloud Config Dependencies
+
+ 4.11.0.201803080745-r
+
@@ -38,7 +41,12 @@
org.eclipse.jgit
org.eclipse.jgit
- 4.8.0.201706111038-r
+ ${jgit.version}
+
+
+ org.eclipse.jgit
+ org.eclipse.jgit.junit.http
+ ${jgit.version}
com.jcraft
diff --git a/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfiguration.java b/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfiguration.java
index 6ecbe029..4f53e812 100644
--- a/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfiguration.java
+++ b/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfiguration.java
@@ -21,6 +21,7 @@ import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -39,8 +40,8 @@ public class EnvironmentMonitorAutoConfiguration {
private List extractors;
@Bean
- public PropertyPathEndpoint propertyPathEndpoint() {
- return new PropertyPathEndpoint(new CompositePropertyPathNotificationExtractor(this.extractors));
+ public PropertyPathEndpoint propertyPathEndpoint(BusProperties busProperties) {
+ return new PropertyPathEndpoint(new CompositePropertyPathNotificationExtractor(this.extractors), busProperties.getId());
}
@Configuration
diff --git a/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/PropertyPathEndpoint.java b/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/PropertyPathEndpoint.java
index edadbc77..661b37bc 100644
--- a/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/PropertyPathEndpoint.java
+++ b/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/PropertyPathEndpoint.java
@@ -22,12 +22,10 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.UUID;
-import org.springframework.beans.BeansException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.bus.event.RefreshRemoteApplicationEvent;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.HttpHeaders;
@@ -40,31 +38,30 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.apachecommons.CommonsLog;
-
/**
* HTTP endpoint for webhooks coming from repository providers.
*
* @author Dave Syer
*
*/
-@RequiredArgsConstructor
@RestController
@RequestMapping(path = "${spring.cloud.config.monitor.endpoint.path:}/monitor")
-@CommonsLog
public class PropertyPathEndpoint
- implements ApplicationEventPublisherAware, ApplicationContextAware {
+ implements ApplicationEventPublisherAware {
+
+ private static Log log = LogFactory.getLog(PropertyPathEndpoint.class);
private final PropertyPathNotificationExtractor extractor;
private ApplicationEventPublisher applicationEventPublisher;
+ private String busId;
- private String contextId = UUID.randomUUID().toString();
+ public PropertyPathEndpoint(PropertyPathNotificationExtractor extractor, String busId) {
+ this.extractor = extractor;
+ this.busId = busId;
+ }
- @Override
- public void setApplicationContext(ApplicationContext applicationContext)
- throws BeansException {
- this.contextId = applicationContext.getId();
+ /* for testing */ String getBusId() {
+ return busId;
}
@Override
@@ -89,7 +86,7 @@ public class PropertyPathEndpoint
log.info("Refresh for: " + service);
this.applicationEventPublisher
.publishEvent(new RefreshRemoteApplicationEvent(this,
- this.contextId, service));
+ this.busId, service));
}
return services;
}
diff --git a/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfigurationTests.java b/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfigurationTests.java
index 4a2feab6..43f17ee4 100644
--- a/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfigurationTests.java
+++ b/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfigurationTests.java
@@ -17,7 +17,6 @@
package org.springframework.cloud.config.monitor;
import java.util.Collection;
-import java.util.Map;
import org.junit.Test;
@@ -25,11 +24,11 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.util.ReflectionTestUtils;
-import org.springframework.util.MultiValueMap;
import static org.junit.Assert.assertEquals;
@@ -40,8 +39,9 @@ import static org.junit.Assert.assertEquals;
public class EnvironmentMonitorAutoConfigurationTests {
@Test
- public void test() {
+ public void testExtractorsCount() {
ConfigurableApplicationContext context = new SpringApplicationBuilder(
+ BusConfig.class,
EnvironmentMonitorAutoConfiguration.class,
ServletWebServerFactoryAutoConfiguration.class, ServerProperties.class,
PropertyPlaceholderAutoConfiguration.class).properties("server.port=-1")
@@ -57,6 +57,7 @@ public class EnvironmentMonitorAutoConfigurationTests {
@Test
public void testCanAddCustomPropertyPathNotificationExtractor() {
ConfigurableApplicationContext context = new SpringApplicationBuilder(
+ BusConfig.class,
CustomPropertyPathNotificationExtractorConfig.class,
EnvironmentMonitorAutoConfiguration.class,
ServletWebServerFactoryAutoConfiguration.class, ServerProperties.class,
@@ -70,18 +71,22 @@ public class EnvironmentMonitorAutoConfigurationTests {
context.close();
}
+ @Configuration
+ static class BusConfig {
+
+ @Bean
+ public BusProperties busProperties() {
+ return new BusProperties();
+ }
+ }
+
@Configuration
static class CustomPropertyPathNotificationExtractorConfig {
@Bean
public PropertyPathNotificationExtractor customNotificationExtractor() {
- return new PropertyPathNotificationExtractor() {
- @Override
- public PropertyPathNotification extract(
- MultiValueMap headers,
- Map payload) {
- throw new UnsupportedOperationException("doesn't do anything");
- }
- };
+ return (headers, payload) -> {
+ throw new UnsupportedOperationException("doesn't do anything");
+ };
}
}
diff --git a/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/PropertyPathEndpointTests.java b/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/PropertyPathEndpointTests.java
index 53a967bf..7807ba12 100644
--- a/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/PropertyPathEndpointTests.java
+++ b/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/PropertyPathEndpointTests.java
@@ -35,7 +35,7 @@ public class PropertyPathEndpointTests {
private PropertyPathEndpoint endpoint = new PropertyPathEndpoint(
new CompositePropertyPathNotificationExtractor(
- Collections. emptyList()));
+ Collections.emptyList()), "abc1");
@Before
public void init() {
@@ -44,15 +44,20 @@ public class PropertyPathEndpointTests {
publisher.refresh();
}
+ @Test
+ public void testBusId() {
+ assertEquals("abc1", this.endpoint.getBusId());
+ }
+
@Test
- public void testNotifyByForm() throws Exception {
+ public void testNotifyByForm() {
assertEquals(0, this.endpoint
- .notifyByForm(new HttpHeaders(), new ArrayList()).size());
+ .notifyByForm(new HttpHeaders(), new ArrayList<>()).size());
}
@Test
- public void testNotifySeveral() throws Exception {
- List request = new ArrayList();
+ public void testNotifySeveral() {
+ List request = new ArrayList<>();
request.add("/foo/bar.properties");
request.add("/application.properties");
assertEquals("[bar, *]",
@@ -60,56 +65,56 @@ public class PropertyPathEndpointTests {
}
@Test
- public void testNotifyAll() throws Exception {
+ public void testNotifyAll() {
assertEquals("[*]",
this.endpoint
.notifyByPath(new HttpHeaders(), Collections
- . singletonMap("path", "application.yml"))
+ .singletonMap("path", "application.yml"))
.toString());
}
@Test
- public void testNotifyAllWithProfile() throws Exception {
+ public void testNotifyAllWithProfile() {
assertEquals("[*:local]",
this.endpoint
.notifyByPath(new HttpHeaders(), Collections
- . singletonMap("path", "application-local.yml"))
+ .singletonMap("path", "application-local.yml"))
.toString());
}
@Test
- public void testNotifyOne() throws Exception {
+ public void testNotifyOne() {
assertEquals("[foo]",
this.endpoint
.notifyByPath(new HttpHeaders(), Collections
- . singletonMap("path", "foo.yml"))
+ .singletonMap("path", "foo.yml"))
.toString());
}
@Test
- public void testNotifyOneWithWindowsPath() throws Exception {
+ public void testNotifyOneWithWindowsPath() {
assertEquals("[foo]",
this.endpoint
.notifyByPath(new HttpHeaders(), Collections
- . singletonMap("path", "C:\\config\\foo.yml"))
+ .singletonMap("path", "C:\\config\\foo.yml"))
.toString());
}
@Test
- public void testNotifyOneWithProfile() throws Exception {
+ public void testNotifyOneWithProfile() {
assertEquals("[foo:local, foo-local]",
this.endpoint
.notifyByPath(new HttpHeaders(), Collections
- . singletonMap("path", "foo-local.yml"))
+ .singletonMap("path", "foo-local.yml"))
.toString());
}
@Test
- public void testNotifyMultiDash() throws Exception {
+ public void testNotifyMultiDash() {
assertEquals("[foo:local-dev, foo-local:dev, foo-local-dev]",
this.endpoint
.notifyByPath(new HttpHeaders(), Collections
- . singletonMap("path", "foo-local-dev.yml"))
+ .singletonMap("path", "foo-local-dev.yml"))
.toString());
}
diff --git a/spring-cloud-config-sample/src/main/resources/bootstrapservercomposite.yml b/spring-cloud-config-sample/src/main/resources/bootstrapservercomposite.yml
new file mode 100644
index 00000000..29f14d2d
--- /dev/null
+++ b/spring-cloud-config-sample/src/main/resources/bootstrapservercomposite.yml
@@ -0,0 +1,12 @@
+spring:
+ cloud:
+ config:
+ server:
+ composite:
+ - type: git
+ uri: ${repo1}
+ - type: git
+ uri: ${repo1}
+ bootstrap: true
+ profiles:
+ active: composite
\ No newline at end of file
diff --git a/spring-cloud-config-sample/src/test/java/sample/ApplicationBootstrapTests.java b/spring-cloud-config-sample/src/test/java/sample/ApplicationBootstrapTests.java
new file mode 100644
index 00000000..7dccace2
--- /dev/null
+++ b/spring-cloud-config-sample/src/test/java/sample/ApplicationBootstrapTests.java
@@ -0,0 +1,88 @@
+package sample;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.SocketUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+
+/**
+ * Test for gh-975.
+ * org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name
+ * 'vaultEnvironmentRepositoryFactory' defined in
+ * org.springframework.cloud.config.server.config.CompositeRepositoryConfiguration: Unsatisfied dependency
+ * No qualifying bean of type 'javax.servlet.http.HttpServletRequest' available:
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Application.class,
+// Normally spring.cloud.config.enabled:true is the default but since we have the config
+// server on the classpath we need to set it explicitly
+ properties = { "spring.cloud.config.enabled:true", "",
+ "management.security.enabled=false", "management.endpoints.web.exposure.include=*" }, webEnvironment = RANDOM_PORT)
+public class ApplicationBootstrapTests {
+ private static final String BASE_PATH = new WebEndpointProperties().getBasePath();
+
+ private static int configPort = SocketUtils.findAvailableTcpPort();
+
+ @LocalServerPort
+ private int port;
+
+ private static ConfigurableApplicationContext server;
+
+ @BeforeClass
+ public static void startConfigServer() throws IOException {
+ System.setProperty("spring.cloud.bootstrap.name", "bootstrapservercomposite");
+ String baseDir = ConfigServerTestUtils
+ .getBaseDirectory("spring-cloud-config-sample");
+ String repo = ConfigServerTestUtils.prepareLocalRepo(baseDir, "target/repos",
+ "config-repo", "target/config");
+ System.setProperty("repo1", repo);
+ server = SpringApplication.run(
+ org.springframework.cloud.config.server.ConfigServerApplication.class,
+ "--server.port=" + configPort, "--spring.config.name=compositeserver",
+ "--repo1=" + repo);
+ System.setProperty("config.port", "" + configPort);
+ }
+
+ @AfterClass
+ public static void close() {
+ System.clearProperty("config.port");
+ System.clearProperty("spring.cloud.bootstrap.name");
+ System.clearProperty("repo1");
+ if (server != null) {
+ server.close();
+ }
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void contextLoads() {
+ Map res = new TestRestTemplate()
+ .getForObject("http://localhost:" + port + BASE_PATH + "/env/info.foo", Map.class);
+ assertThat(res).containsKey("propertySources");
+ Map property = (Map) res.get("property");
+ assertThat(property).containsEntry("value", "bar");
+ }
+
+ public static void main(String[] args) throws IOException {
+ configPort = 8888;
+ startConfigServer();
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/spring-cloud-config-server/pom.xml b/spring-cloud-config-server/pom.xml
index 65ebef34..86ab7029 100644
--- a/spring-cloud-config-server/pom.xml
+++ b/spring-cloud-config-server/pom.xml
@@ -80,6 +80,11 @@
spring-cloud-test-support
test
+
+ org.eclipse.jgit
+ org.eclipse.jgit.junit.http
+ test
+
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java
index 388144c0..f80631af 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/bootstrap/ConfigServerBootstrapConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2015 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.cloud.config.server.config.ConfigServerProperties;
import org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration;
-import org.springframework.cloud.config.server.config.TransportConfiguration;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.cloud.config.server.environment.EnvironmentRepositoryPropertySourceLocator;
import org.springframework.context.annotation.Bean;
@@ -45,7 +44,7 @@ import org.springframework.util.StringUtils;
public class ConfigServerBootstrapConfiguration {
@EnableConfigurationProperties(ConfigServerProperties.class)
- @Import({ EnvironmentRepositoryConfiguration.class, TransportConfiguration.class })
+ @Import({ EnvironmentRepositoryConfiguration.class })
protected static class LocalPropertySourceLocatorConfiguration {
@Autowired
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerAutoConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerAutoConfiguration.java
index 8a7a4140..0d36c9e6 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerAutoConfiguration.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2016 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import org.springframework.context.annotation.Import;
@ConditionalOnBean(ConfigServerConfiguration.Marker.class)
@EnableConfigurationProperties(ConfigServerProperties.class)
@Import({ EnvironmentRepositoryConfiguration.class, CompositeConfiguration.class, ResourceRepositoryConfiguration.class,
- ConfigServerEncryptionConfiguration.class, ConfigServerMvcConfiguration.class, TransportConfiguration.class })
+ ConfigServerEncryptionConfiguration.class, ConfigServerMvcConfiguration.class })
public class ConfigServerAutoConfiguration {
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerMvcConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerMvcConfiguration.java
index 61f762e3..4990f17b 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerMvcConfiguration.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerMvcConfiguration.java
@@ -57,6 +57,7 @@ public class ConfigServerMvcConfiguration extends WebMvcConfigurerAdapter {
public EnvironmentController environmentController(EnvironmentRepository envRepository, ConfigServerProperties server) {
EnvironmentController controller = new EnvironmentController(encrypted(envRepository, server), this.objectMapper);
controller.setStripDocumentFromYaml(server.isStripDocumentFromYaml());
+ controller.setAcceptEmpty(server.isAcceptEmpty());
return controller;
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerProperties.java
index 1ee6cd57..261c4574 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerProperties.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerProperties.java
@@ -56,6 +56,10 @@ public class ConfigServerProperties {
* should be returned in "native" form.
*/
private boolean stripDocumentFromYaml = true;
+ /**
+ * Flag to indicate that If HTTP 404 needs to be sent if Application is not Found
+ */
+ private boolean acceptEmpty = true;
/**
* Default application name when incoming requests do not have a specific one.
@@ -115,7 +119,14 @@ public class ConfigServerProperties {
public void setStripDocumentFromYaml(boolean stripDocumentFromYaml) {
this.stripDocumentFromYaml = stripDocumentFromYaml;
}
+
+ public boolean isAcceptEmpty() {
+ return this.acceptEmpty;
+ }
+ public void setAcceptEmpty(boolean acceptEmpty) {
+ this.acceptEmpty = acceptEmpty;
+ }
public String getDefaultApplicationName() {
return this.defaultApplicationName;
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java
index 62b1d608..9acd3b39 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfiguration.java
@@ -17,12 +17,12 @@ package org.springframework.cloud.config.server.config;
import java.util.List;
import java.util.Optional;
-
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.tmatesoft.svn.core.SVNException;
+import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -113,14 +113,14 @@ class DefaultRepositoryConfiguration {
private ConfigServerProperties server;
@Autowired(required = false)
- private TransportConfigCallback transportConfigCallback;
+ private TransportConfigCallback customTransportConfigCallback;
@Bean
public MultipleJGitEnvironmentRepository defaultEnvironmentRepository(
MultipleJGitEnvironmentProperties environmentProperties) {
MultipleJGitEnvironmentRepositoryFactory gitEnvironmentRepositoryFactory =
new MultipleJGitEnvironmentRepositoryFactory(environment, server,
- Optional.ofNullable(transportConfigCallback));
+ Optional.ofNullable(customTransportConfigCallback));
return gitEnvironmentRepositoryFactory.build(environmentProperties);
}
}
@@ -169,7 +169,7 @@ class SvnRepositoryConfiguration {
@Profile("vault")
class VaultRepositoryConfiguration {
@Bean
- public VaultEnvironmentRepository vaultEnvironmentRepository(HttpServletRequest request, EnvironmentWatch watch,
+ public VaultEnvironmentRepository vaultEnvironmentRepository(ObjectProvider request, EnvironmentWatch watch,
VaultEnvironmentProperties environmentProperties) {
return new VaultEnvironmentRepositoryFactory(request, watch).build(environmentProperties);
}
@@ -198,8 +198,8 @@ class CompositeRepositoryConfiguration {
@Bean
public MultipleJGitEnvironmentRepositoryFactory gitEnvironmentRepositoryFactory(
ConfigurableEnvironment environment, ConfigServerProperties server,
- Optional transportConfigCallback) {
- return new MultipleJGitEnvironmentRepositoryFactory(environment, server, transportConfigCallback);
+ Optional customTransportConfigCallback) {
+ return new MultipleJGitEnvironmentRepositoryFactory(environment, server, customTransportConfigCallback);
}
}
@@ -214,7 +214,7 @@ class CompositeRepositoryConfiguration {
}
@Bean
- public VaultEnvironmentRepositoryFactory vaultEnvironmentRepositoryFactory(HttpServletRequest request,
+ public VaultEnvironmentRepositoryFactory vaultEnvironmentRepositoryFactory(ObjectProvider request,
EnvironmentWatch watch) {
return new VaultEnvironmentRepositoryFactory(request, watch);
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/TransportConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/TransportConfiguration.java
deleted file mode 100644
index aa6aaccb..00000000
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/TransportConfiguration.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2015-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.config.server.config;
-
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.Session;
-import org.eclipse.jgit.api.TransportConfigCallback;
-import org.eclipse.jgit.transport.*;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.config.server.ssh.PropertyBasedSshSessionFactory;
-import org.springframework.cloud.config.server.ssh.SshUriProperties;
-import org.springframework.cloud.config.server.ssh.SshUriPropertyProcessor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Configure a callback to set up a property based SSH settings before running a transport command (such as clone or fetch)
- *
- * @author Ollie Hughes
- */
-@Configuration
-@ConditionalOnClass(TransportConfigCallback.class)
-@EnableConfigurationProperties(SshUriProperties.class)
-public class TransportConfiguration {
-
- @ConditionalOnMissingBean(TransportConfigCallback.class)
- @Bean
- public TransportConfigCallback propertiesBasedSshTransportCallback(final SshUriProperties sshUriProperties) {
- if(sshUriProperties.isIgnoreLocalSshSettings()) {
- return new PropertiesBasedSshTransportConfigCallback(sshUriProperties);
- }
- else return new FileBasedSshTransportConfigCallback(sshUriProperties);
- }
-
- /**
- * Configure JGit transport command to use a SSH session factory that is configured using properties defined
- * in {@link SshUriProperties}
- */
- public static class PropertiesBasedSshTransportConfigCallback implements TransportConfigCallback {
-
- private SshUriProperties sshUriProperties;
-
- public PropertiesBasedSshTransportConfigCallback(SshUriProperties sshUriProperties) {
- this.sshUriProperties = sshUriProperties;
- }
-
- public SshUriProperties getSshUriProperties() {
- return sshUriProperties;
- }
-
- @Override
- public void configure(Transport transport) {
- if (transport instanceof SshTransport) {
- SshTransport sshTransport = (SshTransport) transport;
- sshTransport.setSshSessionFactory(
- new PropertyBasedSshSessionFactory(
- new SshUriPropertyProcessor(sshUriProperties).getSshKeysByHostname(), new JSch()));
- }
- }
- }
-
- /**
- * Configure JGit transport command to use a default SSH session factory based on local machines SSH config.
- * Allow strict host key checking to be set.
- */
- public static class FileBasedSshTransportConfigCallback implements TransportConfigCallback {
-
- private SshUriProperties sshUriProperties;
-
- public FileBasedSshTransportConfigCallback(SshUriProperties sshUriProperties) {
- this.sshUriProperties = sshUriProperties;
- }
-
- public SshUriProperties getSshUriProperties() {
- return sshUriProperties;
- }
-
- @Override
- public void configure(Transport transport) {
- SshSessionFactory.setInstance(new JschConfigSessionFactory() {
- @Override
- protected void configure(OpenSshConfig.Host hc, Session session) {
- session.setConfig("StrictHostKeyChecking",
- sshUriProperties.isStrictHostKeyChecking() ? "yes" : "no");
- }
- });
- }
- }
-}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java
index 3d6c0e3a..29a6f049 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentController.java
@@ -69,6 +69,7 @@ public class EnvironmentController {
private ObjectMapper objectMapper;
private boolean stripDocument = true;
+ private boolean acceptEmpty = true;
public EnvironmentController(EnvironmentRepository repository) {
this(repository, new ObjectMapper());
@@ -90,6 +91,15 @@ public class EnvironmentController {
this.stripDocument = stripDocument;
}
+ /**
+ * Flag to indicate that If HTTP 404 needs to be sent if Application is not Found
+ *
+ * @param acceptEmpty the flag to set
+ */
+ public void setAcceptEmpty(boolean acceptEmpty) {
+ this.acceptEmpty = acceptEmpty;
+ }
+
@RequestMapping("/{name}/{profiles:.*[^-].*}")
public Environment defaultLabel(@PathVariable String name,
@PathVariable String profiles) {
@@ -110,6 +120,9 @@ public class EnvironmentController {
label = label.replace("(_)", "/");
}
Environment environment = this.repository.findOne(name, profiles, label);
+ if(!acceptEmpty && (environment == null || environment.getPropertySources().isEmpty())){
+ throw new EnvironmentNotFoundException("Profile Not found");
+ }
return environment;
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentNotFoundException.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentNotFoundException.java
new file mode 100644
index 00000000..31908c89
--- /dev/null
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/EnvironmentNotFoundException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.cloud.config.server.environment;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+/**
+ * @author Chids
+ *
+ */
+@SuppressWarnings("serial")
+@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Application Not Found")
+public class EnvironmentNotFoundException extends RuntimeException {
+
+ public EnvironmentNotFoundException(String string) {
+ super(string);
+ }
+
+}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentProperties.java
index 07411da4..5dcacd7c 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentProperties.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentProperties.java
@@ -15,19 +15,76 @@
*/
package org.springframework.cloud.config.server.environment;
+import javax.validation.constraints.Pattern;
+
import org.springframework.cloud.config.server.support.AbstractScmAccessorProperties;
/**
* @author Dylan Roberts
+ * @author Gareth Clay
*/
public class JGitEnvironmentProperties extends AbstractScmAccessorProperties {
private static final String DEFAULT_LABEL = "master";
+ /** Flag to indicate that the repository should be cloned on startup (not on demand). Generally leads to slower startup but faster first query. */
private boolean cloneOnStart = false;
+
+ /** Flag to indicate that the repository should force pull. If true discard any local changes and take from remote repository. */
private boolean forcePull;
+
+ /** Timeout (in seconds) for obtaining HTTP or SSH connection (if applicable), defaults to 5 seconds. */
private int timeout = 5;
+
+ /** Flag to indicate that the branch should be deleted locally if it's origin tracked branch was removed. */
private boolean deleteUntrackedBranches = false;
+ /**
+ * Flag to indicate that SSL certificate validation should be bypassed when
+ * communicating with a repository served over an HTTPS connection.
+ */
+ private boolean skipSslValidation = false;
+
+ /**
+ * Time (in seconds) between refresh of the git repository
+ */
+ private int refreshRate = 0;
+
+ /**
+ * Valid SSH private key. Must be set if ignoreLocalSshSettings is true and Git URI is SSH format.
+ */
+ private String privateKey;
+
+ /**
+ * One of ssh-dss, ssh-rsa, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, or ecdsa-sha2-nistp521. Must be set if hostKey is also set.
+ */
+ private String hostKeyAlgorithm;
+
+ /**
+ * Valid SSH host key. Must be set if hostKeyAlgorithm is also set.
+ */
+ private String hostKey;
+
+ /**
+ * Location of custom .known_hosts file.
+ */
+ private String knownHostsFile;
+
+ /**
+ * Override server authentication method order. This should allow for evading login prompts if server has keyboard-interactive authentication before the publickey method.
+ */
+ @Pattern(regexp = "([\\w -]+,)*([\\w -]+)")
+ private String preferredAuthentications;
+
+ /**
+ * If true, use property-based instead of file-based SSH config.
+ */
+ private boolean ignoreLocalSshSettings;
+
+ /**
+ * If false, ignore errors with host key
+ */
+ private boolean strictHostKeyChecking = true;
+
public JGitEnvironmentProperties() {
super();
setDefaultLabel(DEFAULT_LABEL);
@@ -64,4 +121,78 @@ public class JGitEnvironmentProperties extends AbstractScmAccessorProperties {
public void setDeleteUntrackedBranches(boolean deleteUntrackedBranches) {
this.deleteUntrackedBranches = deleteUntrackedBranches;
}
+
+ public int getRefreshRate() {
+ return refreshRate;
+ }
+
+ public void setRefreshRate(int refreshRate) {
+ this.refreshRate = refreshRate;
+ }
+
+ public String getPrivateKey() {
+ return privateKey;
+ }
+
+ public void setPrivateKey(String privateKey) {
+ this.privateKey = privateKey;
+ }
+
+ public String getHostKeyAlgorithm() {
+ return hostKeyAlgorithm;
+ }
+
+ public void setHostKeyAlgorithm(String hostKeyAlgorithm) {
+ this.hostKeyAlgorithm = hostKeyAlgorithm;
+ }
+
+ public String getHostKey() {
+ return hostKey;
+ }
+
+ public void setHostKey(String hostKey) {
+ this.hostKey = hostKey;
+ }
+
+ public String getKnownHostsFile() {
+ return knownHostsFile;
+ }
+
+ public void setKnownHostsFile(String knownHostsFile) {
+ this.knownHostsFile = knownHostsFile;
+ }
+
+ public String getPreferredAuthentications() {
+ return preferredAuthentications;
+ }
+
+ public void setPreferredAuthentications(String preferredAuthentications) {
+ this.preferredAuthentications = preferredAuthentications;
+ }
+
+ public boolean isIgnoreLocalSshSettings() {
+ return ignoreLocalSshSettings;
+ }
+
+ public void setIgnoreLocalSshSettings(boolean ignoreLocalSshSettings) {
+ this.ignoreLocalSshSettings = ignoreLocalSshSettings;
+ }
+
+ @Override
+ public boolean isStrictHostKeyChecking() {
+ return strictHostKeyChecking;
+ }
+
+ @Override
+ public void setStrictHostKeyChecking(boolean strictHostKeyChecking) {
+ this.strictHostKeyChecking = strictHostKeyChecking;
+ }
+
+ public boolean isSkipSslValidation() {
+ return skipSslValidation;
+ }
+
+ public void setSkipSslValidation(boolean skipSslValidation) {
+ this.skipSslValidation = skipSslValidation;
+ }
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java
index 7a40a718..9e430330 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java
@@ -54,19 +54,18 @@ import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.TagOpt;
import org.eclipse.jgit.transport.TrackingRefUpdate;
-import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.util.FileUtils;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.cloud.config.server.support.PassphraseCredentialsProvider;
+import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.UrlResource;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
+
import static java.lang.String.format;
import static org.eclipse.jgit.transport.ReceiveCommand.Type.DELETE;
-import static org.springframework.util.StringUtils.hasText;
/**
* An {@link EnvironmentRepository} backed by a single git repository.
@@ -76,6 +75,7 @@ import static org.springframework.util.StringUtils.hasText;
* @author Marcos Barbero
* @author Daniel Lavoie
* @author Ryan Lynch
+ * @author Gareth Clay
*/
public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
implements EnvironmentRepository, SearchPathLocator, InitializingBean {
@@ -90,6 +90,16 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
*/
private int timeout;
+ /**
+ * Time (in seconds) between refresh of the git repository
+ */
+ private int refreshRate = 0;
+
+ /**
+ * Time of the last refresh of the git repository
+ */
+ private long lastRefresh;
+
/**
* Flag to indicate that the repository should be cloned on startup (not on demand).
* Generally leads to slower startup but faster first query.
@@ -101,9 +111,10 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
private String defaultLabel;
/**
- * The credentials provider to use to connect to the Git repository.
+ * Factory used to create the credentials provider to use to connect to the Git
+ * repository.
*/
- private CredentialsProvider gitCredentialsProvider;
+ private GitCredentialsProviderFactory gitCredentialsProviderFactory = new GitCredentialsProviderFactory();
/**
* Transport configuration callback for JGit commands.
@@ -122,6 +133,12 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
*/
private boolean deleteUntrackedBranches;
+ /**
+ * Flag to indicate that SSL certificate validation should be bypassed when
+ * communicating with a repository served over an HTTPS connection.
+ */
+ private boolean skipSslValidation;
+
public JGitEnvironmentRepository(ConfigurableEnvironment environment, JGitEnvironmentProperties properties) {
super(environment, properties);
this.cloneOnStart = properties.isCloneOnStart();
@@ -129,6 +146,8 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
this.forcePull = properties.isForcePull();
this.timeout = properties.getTimeout();
this.deleteUntrackedBranches = properties.isDeleteUntrackedBranches();
+ this.refreshRate = properties.getRefreshRate();
+ this.skipSslValidation = properties.isSkipSslValidation();
}
public boolean isCloneOnStart() {
@@ -147,6 +166,15 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
this.timeout = timeout;
}
+ public int getRefreshRate() {
+ return refreshRate;
+ }
+
+ public void setRefreshRate(int refreshRate) {
+ this.refreshRate = refreshRate;
+ }
+
+
public TransportConfigCallback getTransportConfigCallback() {
return transportConfigCallback;
}
@@ -164,6 +192,11 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
this.gitFactory = gitFactory;
}
+ public void setGitCredentialsProviderFactory(
+ GitCredentialsProviderFactory gitCredentialsProviderFactory) {
+ this.gitCredentialsProviderFactory = gitCredentialsProviderFactory;
+ }
+
public String getDefaultLabel() {
return this.defaultLabel;
}
@@ -188,6 +221,14 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
this.deleteUntrackedBranches = deleteUntrackedBranches;
}
+ public boolean isSkipSslValidation() {
+ return skipSslValidation;
+ }
+
+ public void setSkipSslValidation(boolean skipSslValidation) {
+ this.skipSslValidation = skipSslValidation;
+ }
+
@Override
public synchronized Locations getLocations(String application, String profile,
String label) {
@@ -349,6 +390,11 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
protected boolean shouldPull(Git git) throws GitAPIException {
boolean shouldPull;
+
+ if (this.refreshRate > 0 && System.currentTimeMillis() - this.lastRefresh < (this.refreshRate * 1000)) {
+ return false;
+ }
+
Status gitStatus = git.status().call();
boolean isWorkingTreeClean = gitStatus.isClean();
String originUrl = git.getRepository().getConfig().getString("remote", "origin",
@@ -394,6 +440,9 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
fetch.setRemote("origin");
fetch.setTagOpt(TagOpt.FETCH_TAGS);
fetch.setRemoveDeletedRefs(deleteUntrackedBranches);
+ if (this.refreshRate > 0) {
+ this.setLastRefresh(System.currentTimeMillis());
+ }
configureCommand(fetch);
try {
@@ -555,19 +604,8 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
}
private CredentialsProvider getCredentialsProvider() {
- if (this.gitCredentialsProvider != null) {
- return this.gitCredentialsProvider;
- }
-
- if (hasText(getUsername()) && hasText(getPassword())) {
- return new UsernamePasswordCredentialsProvider(getUsername(), getPassword());
- }
-
- if (hasText(getPassphrase())) {
- return new PassphraseCredentialsProvider(getPassphrase());
- }
-
- return null;
+ return this.gitCredentialsProviderFactory.createFor(this.getUri(), getUsername(),
+ getPassword(), getPassphrase(), isSkipSslValidation());
}
private boolean isClean(Git git, String label) {
@@ -621,6 +659,14 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
}
}
+ public void setLastRefresh(long lastRefresh) {
+ this.lastRefresh = lastRefresh;
+ }
+
+ public long getLastRefresh() {
+ return lastRefresh;
+ }
+
/**
* Wraps the static method calls to {@link org.eclipse.jgit.api.Git} and
* {@link org.eclipse.jgit.api.CloneCommand} allowing for easier unit testing.
@@ -637,18 +683,4 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
return command;
}
}
-
- /**
- * @return the gitCredentialsProvider
- */
- public CredentialsProvider getGitCredentialsProvider() {
- return gitCredentialsProvider;
- }
-
- /**
- * @param gitCredentialsProvider the gitCredentialsProvider to set
- */
- public void setGitCredentialsProvider(CredentialsProvider gitCredentialsProvider) {
- this.gitCredentialsProvider = gitCredentialsProvider;
- }
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JdbcEnvironmentProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JdbcEnvironmentProperties.java
index 4125fa93..5a05b344 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JdbcEnvironmentProperties.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JdbcEnvironmentProperties.java
@@ -27,6 +27,7 @@ public class JdbcEnvironmentProperties implements EnvironmentRepositoryPropertie
private static final String DEFAULT_SQL = "SELECT KEY, VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?";
private int order = Ordered.LOWEST_PRECEDENCE - 10;
+ /** SQL used to query database for keys and values */
private String sql = DEFAULT_SQL;
public int getOrder() {
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProperties.java
index 72160806..3a1353a5 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProperties.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentProperties.java
@@ -19,12 +19,25 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.config.server.ssh.HostKeyAlgoSupported;
+import org.springframework.cloud.config.server.ssh.HostKeyAndAlgoBothExist;
+import org.springframework.cloud.config.server.ssh.KnownHostsFileIsValid;
+import org.springframework.cloud.config.server.ssh.PrivateKeyIsValid;
+import org.springframework.validation.annotation.Validated;
/**
* @author Dylan Roberts
*/
@ConfigurationProperties("spring.cloud.config.server.git")
+@Validated
+@PrivateKeyIsValid
+@HostKeyAndAlgoBothExist
+@HostKeyAlgoSupported
+@KnownHostsFileIsValid
public class MultipleJGitEnvironmentProperties extends JGitEnvironmentProperties {
+ /**
+ * Map of repository identifier to location and other properties.
+ */
private Map repos = new LinkedHashMap<>();
public Map getRepos() {
@@ -36,7 +49,13 @@ public class MultipleJGitEnvironmentProperties extends JGitEnvironmentProperties
}
public static class PatternMatchingJGitEnvironmentProperties extends JGitEnvironmentProperties {
+ /**
+ * Pattern to match on application name and profiles.
+ */
private String[] pattern = new String[0];
+ /**
+ * Name of repository (same as map key by default).
+ */
private String name;
public String[] getPattern() {
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepository.java
index 99b57fbc..d737a30a 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepository.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepository.java
@@ -27,7 +27,6 @@ import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.config.environment.Environment;
-import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;
@@ -44,6 +43,7 @@ import org.springframework.util.StringUtils;
*
* @author Andy Chan (iceycake)
* @author Dave Syer
+ * @author Gareth Clay
*
*/
public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository {
@@ -66,9 +66,6 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository
@Override
public void afterPropertiesSet() throws Exception {
- GitCredentialsProviderFactory credentialFactory = new GitCredentialsProviderFactory();
- super.setGitCredentialsProvider(credentialFactory.createFor(getUri(),
- getUsername(), getPassword(), getPassphrase()));
super.afterPropertiesSet();
for (String name : this.repos.keySet()) {
PatternMatchingJGitEnvironmentRepository repo = this.repos.get(name);
@@ -85,18 +82,21 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository
if (getTimeout() != 0 && repo.getTimeout() == 0) {
repo.setTimeout(getTimeout());
}
+ if (getRefreshRate() != 0 && repo.getRefreshRate() == 0) {
+ repo.setRefreshRate(getRefreshRate());
+ }
String user = repo.getUsername();
- String pass = repo.getPassword();
String passphrase = repo.getPassphrase();
if (user == null) {
- user = getUsername();
- pass = getPassword();
+ repo.setUsername(getUsername());
+ repo.setPassword(getPassword());
}
if (passphrase == null) {
- passphrase = getPassphrase();
+ repo.setPassphrase(getPassphrase());
+ }
+ if (isSkipSslValidation()) {
+ repo.setSkipSslValidation(true);
}
- repo.setGitCredentialsProvider(
- credentialFactory.createFor(repo.getUri(), user, pass, passphrase));
repo.afterPropertiesSet();
}
if (!getBasedir().exists() &&
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryFactory.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryFactory.java
index 73e02e14..a01aaa9b 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryFactory.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryFactory.java
@@ -20,6 +20,8 @@ import java.util.Optional;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.springframework.cloud.config.server.config.ConfigServerProperties;
+import org.springframework.cloud.config.server.ssh.FileBasedSshTransportConfigCallback;
+import org.springframework.cloud.config.server.ssh.PropertiesBasedSshTransportConfigCallback;
import org.springframework.core.env.ConfigurableEnvironment;
/**
@@ -29,23 +31,31 @@ public class MultipleJGitEnvironmentRepositoryFactory implements EnvironmentRepo
MultipleJGitEnvironmentProperties> {
private ConfigurableEnvironment environment;
private ConfigServerProperties server;
- private Optional transportConfigCallback;
+ private Optional customTransportConfigCallback;
public MultipleJGitEnvironmentRepositoryFactory(ConfigurableEnvironment environment, ConfigServerProperties server,
- Optional transportConfigCallback) {
+ Optional customTransportConfigCallback) {
this.environment = environment;
this.server = server;
- this.transportConfigCallback = transportConfigCallback;
+ this.customTransportConfigCallback = customTransportConfigCallback;
}
@Override
public MultipleJGitEnvironmentRepository build(MultipleJGitEnvironmentProperties environmentProperties) {
MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository(environment,
environmentProperties);
- repository.setTransportConfigCallback(transportConfigCallback.orElse(null));
+ repository.setTransportConfigCallback(customTransportConfigCallback
+ .orElse(buildTransportConfigCallback(environmentProperties)));
if (server.getDefaultLabel() != null) {
repository.setDefaultLabel(server.getDefaultLabel());
}
return repository;
}
+
+ private TransportConfigCallback buildTransportConfigCallback(final MultipleJGitEnvironmentProperties gitEnvironmentProperties) {
+ if (gitEnvironmentProperties.isIgnoreLocalSshSettings()) {
+ return new PropertiesBasedSshTransportConfigCallback(gitEnvironmentProperties);
+ }
+ return new FileBasedSshTransportConfigCallback(gitEnvironmentProperties);
+ }
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentProperties.java
index dcaeb883..432b52b4 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentProperties.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/NativeEnvironmentProperties.java
@@ -24,10 +24,23 @@ import org.springframework.core.Ordered;
*/
@ConfigurationProperties("spring.cloud.config.server.native")
public class NativeEnvironmentProperties implements EnvironmentRepositoryProperties {
+ /**
+ * Flag to determine how to handle exceptions during decryption (default false).
+ */
private Boolean failOnError = false;
+ /**
+ * Flag to determine whether label locations should be added.
+ */
private Boolean addLabelLocations = true;
private String defaultLabel = "master";
+ /**
+ * Locations to search for configuration files. Defaults to the same as a Spring Boot
+ * app so [classpath:/,classpath:/config/,file:./,file:./config/].
+ */
private String[] searchLocations = new String[0];
+ /**
+ * Version string to be reported for native repository
+ */
private String version;
private int order = Ordered.LOWEST_PRECEDENCE;
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentProperties.java
index 6f8a12f9..4d17c7af 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentProperties.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentProperties.java
@@ -24,11 +24,17 @@ import org.springframework.core.Ordered;
*/
@ConfigurationProperties("spring.cloud.config.server.vault")
public class VaultEnvironmentProperties implements EnvironmentRepositoryProperties {
+ /** Vault host. Defaults to 127.0.0.1. */
private String host = "127.0.0.1";
+ /** Vault port. Defaults to 8200. */
private Integer port = 8200;
+ /** Vault scheme. Defaults to http. */
private String scheme = "http";
+ /** Vault backend. Defaults to secret. */
private String backend = "secret";
+ /** The key in vault shared by all applications. Defaults to application. Set to empty to disable. */
private String defaultKey = "application";
+ /** Vault profile separator. Defaults to comma. */
private String profileSeparator = ",";
private int order = Ordered.LOWEST_PRECEDENCE;
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepository.java
index cec7df18..d8d53ae6 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepository.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepository.java
@@ -20,15 +20,18 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
+
import javax.servlet.http.HttpServletRequest;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.databind.JsonNode;
-import org.hibernate.validator.constraints.NotEmpty;
-import org.hibernate.validator.constraints.Range;
+import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
@@ -61,7 +64,8 @@ public class VaultEnvironmentRepository implements EnvironmentRepository, Ordere
private String host;
/** Vault port. Defaults to 8200. */
- @Range(min = 1, max = 65535)
+ @Min(1)
+ @Max(65535)
private int port;
/** Vault scheme. Defaults to http. */
@@ -83,11 +87,11 @@ public class VaultEnvironmentRepository implements EnvironmentRepository, Ordere
private RestTemplate rest;
// TODO: move to watchState:String on findOne?
- private HttpServletRequest request;
+ private ObjectProvider request;
private EnvironmentWatch watch;
- public VaultEnvironmentRepository(HttpServletRequest request, EnvironmentWatch watch, RestTemplate rest,
+ public VaultEnvironmentRepository(ObjectProvider request, EnvironmentWatch watch, RestTemplate rest,
VaultEnvironmentProperties properties) {
this.request = request;
this.watch = watch;
@@ -104,7 +108,12 @@ public class VaultEnvironmentRepository implements EnvironmentRepository, Ordere
@Override
public Environment findOne(String application, String profile, String label) {
- String state = request.getHeader(STATE_HEADER);
+ HttpServletRequest servletRequest = request.getIfAvailable();
+ if (servletRequest == null) {
+ throw new IllegalStateException("No HttpServletRequest available");
+ }
+
+ String state = servletRequest.getHeader(STATE_HEADER);
String newState = this.watch.watch(state);
String[] profiles = StringUtils.commaDelimitedListToStringArray(profile);
@@ -116,7 +125,7 @@ public class VaultEnvironmentRepository implements EnvironmentRepository, Ordere
for (String key : keys) {
// read raw 'data' key from vault
- String data = read(key);
+ String data = read(servletRequest, key);
if (data != null) {
// data is in json format of which, yaml is a superset, so parse
final YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
@@ -162,12 +171,12 @@ public class VaultEnvironmentRepository implements EnvironmentRepository, Ordere
}
}
- String read(String key) {
+ String read(HttpServletRequest servletRequest, String key) {
String url = String.format("%s://%s:%s/v1/{backend}/{key}", this.scheme, this.host, this.port);
HttpHeaders headers = new HttpHeaders();
- String token = request.getHeader(TOKEN_HEADER);
+ String token = servletRequest.getHeader(TOKEN_HEADER);
if (!StringUtils.hasLength(token)) {
throw new IllegalArgumentException("Missing required header: " + TOKEN_HEADER);
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryFactory.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryFactory.java
index ce2a6e4b..9639a716 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryFactory.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryFactory.java
@@ -17,6 +17,7 @@ package org.springframework.cloud.config.server.environment;
import javax.servlet.http.HttpServletRequest;
+import org.springframework.beans.factory.ObjectProvider;
import org.springframework.web.client.RestTemplate;
/**
@@ -24,10 +25,10 @@ import org.springframework.web.client.RestTemplate;
*/
public class VaultEnvironmentRepositoryFactory implements EnvironmentRepositoryFactory {
- private HttpServletRequest request;
+ private ObjectProvider request;
private EnvironmentWatch watch;
- public VaultEnvironmentRepositoryFactory(HttpServletRequest request, EnvironmentWatch watch) {
+ public VaultEnvironmentRepositoryFactory(ObjectProvider request, EnvironmentWatch watch) {
this.request = request;
this.watch = watch;
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/FileBasedSshTransportConfigCallback.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/FileBasedSshTransportConfigCallback.java
new file mode 100644
index 00000000..b4541ac7
--- /dev/null
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/FileBasedSshTransportConfigCallback.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.cloud.config.server.ssh;
+
+import com.jcraft.jsch.Session;
+import org.eclipse.jgit.api.TransportConfigCallback;
+import org.eclipse.jgit.transport.JschConfigSessionFactory;
+import org.eclipse.jgit.transport.OpenSshConfig;
+import org.eclipse.jgit.transport.SshSessionFactory;
+import org.eclipse.jgit.transport.Transport;
+
+import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
+
+/**
+ * Configure JGit transport command to use a default SSH session factory based on local machines SSH config.
+ * Allow strict host key checking to be set.
+ */
+public class FileBasedSshTransportConfigCallback implements TransportConfigCallback {
+
+ private MultipleJGitEnvironmentProperties sshUriProperties;
+
+ public FileBasedSshTransportConfigCallback(MultipleJGitEnvironmentProperties sshUriProperties) {
+ this.sshUriProperties = sshUriProperties;
+ }
+
+ public MultipleJGitEnvironmentProperties getSshUriProperties() {
+ return sshUriProperties;
+ }
+
+ @Override
+ public void configure(Transport transport) {
+ SshSessionFactory.setInstance(new JschConfigSessionFactory() {
+ @Override
+ protected void configure(OpenSshConfig.Host hc, Session session) {
+ session.setConfig("StrictHostKeyChecking",
+ sshUriProperties.isStrictHostKeyChecking() ? "yes" : "no");
+ }
+ });
+ }
+}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/HostKeyAlgoSupportedValidator.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/HostKeyAlgoSupportedValidator.java
index d75d2e48..e3652592 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/HostKeyAlgoSupportedValidator.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/HostKeyAlgoSupportedValidator.java
@@ -23,6 +23,8 @@ import java.util.Set;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
+import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties;
+import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
import org.springframework.validation.annotation.Validated;
import static java.lang.String.format;
@@ -30,14 +32,14 @@ import static org.springframework.cloud.config.server.ssh.SshPropertyValidator.i
import static org.springframework.util.StringUtils.hasText;
/**
- * JSR-303 Cross Field validator that ensures that a {@link SshUriProperties} bean for the constraints:
+ * JSR-303 Cross Field validator that ensures that a {@link MultipleJGitEnvironmentProperties} bean for the constraints:
* - If host key algo is supported
*
* Beans annotated with {@link HostKeyAlgoSupported} and {@link Validated} will have the constraints applied.
*
* @author Ollie Hughes
*/
-public class HostKeyAlgoSupportedValidator implements ConstraintValidator {
+public class HostKeyAlgoSupportedValidator implements ConstraintValidator {
private static final String GIT_PROPERTY_PREFIX = "spring.cloud.config.server.git.";
private final SshPropertyValidator sshPropertyValidator = new SshPropertyValidator();
private static final Set VALID_HOST_KEY_ALGORITHMS = new LinkedHashSet<>(Arrays.asList(
@@ -49,12 +51,12 @@ public class HostKeyAlgoSupportedValidator implements ConstraintValidator validationResults = new HashSet<>();
- List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
+ List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
- for (SshUri extractedProperty : extractedProperties) {
+ for (JGitEnvironmentProperties extractedProperty : extractedProperties) {
if (sshUriProperties.isIgnoreLocalSshSettings() && isSshUri(extractedProperty.getUri())) {
validationResults.add(isHostKeySpecifiedWhenAlgorithmSet(extractedProperty, context));
}
@@ -62,7 +64,7 @@ public class HostKeyAlgoSupportedValidator implements ConstraintValidator {
+public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator {
private static final String GIT_PROPERTY_PREFIX = "spring.cloud.config.server.git.";
private final SshPropertyValidator sshPropertyValidator = new SshPropertyValidator();
@@ -46,11 +48,11 @@ public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator validationResults = new HashSet<>();
- List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
+ List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
- for (SshUri extractedProperty : extractedProperties) {
+ for (JGitEnvironmentProperties extractedProperty : extractedProperties) {
if (sshUriProperties.isIgnoreLocalSshSettings() && isSshUri(extractedProperty.getUri())) {
validationResults.add(
isAlgorithmSpecifiedWhenHostKeySet(extractedProperty, context)
@@ -60,7 +62,7 @@ public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator
* Beans annotated with {@link KnownHostsFileIsValid} and {@link Validated} will have the constraints applied.
*
* @author Edgars Jasmans
*/
-public class KnownHostsFileValidator implements ConstraintValidator {
+public class KnownHostsFileValidator implements ConstraintValidator {
@Override
public void initialize(KnownHostsFileIsValid knownHostsFileIsValid) {
@@ -40,7 +41,7 @@ public class KnownHostsFileValidator implements ConstraintValidator {
+public class PrivateKeyValidator implements ConstraintValidator {
private static final String GIT_PROPERTY_PREFIX = "spring.cloud.config.server.git.";
private final SshPropertyValidator sshPropertyValidator = new SshPropertyValidator();
@@ -49,12 +51,12 @@ public class PrivateKeyValidator implements ConstraintValidator validationResults = new HashSet<>();
- List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
+ List extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
- for (SshUri extractedProperty : extractedProperties) {
+ for (JGitEnvironmentProperties extractedProperty : extractedProperties) {
if (extractedProperty.isIgnoreLocalSshSettings() && isSshUri(extractedProperty.getUri())) {
validationResults.add(
isPrivateKeyPresent(extractedProperty, context)
@@ -65,7 +67,7 @@ public class PrivateKeyValidator implements ConstraintValidator sshKeysByHostname;
+ private final Map sshKeysByHostname;
private final JSch jSch;
- public PropertyBasedSshSessionFactory(Map sshKeysByHostname, JSch jSch) {
+ public PropertyBasedSshSessionFactory(Map sshKeysByHostname, JSch jSch) {
this.sshKeysByHostname = sshKeysByHostname;
this.jSch = jSch;
}
@Override
protected void configure(Host hc, Session session) {
- SshUri sshProperties = sshKeysByHostname.get(hc.getHostName());
+ JGitEnvironmentProperties sshProperties = sshKeysByHostname.get(hc.getHostName());
String hostKeyAlgorithm = sshProperties.getHostKeyAlgorithm();
if (hostKeyAlgorithm != null) {
session.setConfig(SERVER_HOST_KEY, hostKeyAlgorithm);
@@ -69,7 +71,7 @@ public class PropertyBasedSshSessionFactory extends JschConfigSessionFactory {
@Override
protected Session createSession(Host hc, String user, String host, int port, FS fs) throws JSchException {
if (sshKeysByHostname.containsKey(host)) {
- SshUri sshUriProperties = sshKeysByHostname.get(host);
+ JGitEnvironmentProperties sshUriProperties = sshKeysByHostname.get(host);
jSch.addIdentity(host, sshUriProperties.getPrivateKey().getBytes(), null, null);
if (sshUriProperties.getKnownHostsFile() != null) {
jSch.setKnownHosts(sshUriProperties.getKnownHostsFile());
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshPropertyValidator.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshPropertyValidator.java
index 6b1b1475..75b1fc4a 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshPropertyValidator.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshPropertyValidator.java
@@ -24,6 +24,8 @@ import java.util.Map;
import org.eclipse.jgit.transport.URIish;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties;
+import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
import org.springframework.stereotype.Component;
import static org.springframework.util.StringUtils.hasText;
@@ -34,7 +36,7 @@ import static org.springframework.util.StringUtils.hasText;
* @author Ollie Hughes
*/
@Component
-@EnableConfigurationProperties(SshUriProperties.class)
+@EnableConfigurationProperties(MultipleJGitEnvironmentProperties.class)
public class SshPropertyValidator {
protected static boolean isSshUri(Object uri) {
@@ -55,10 +57,10 @@ public class SshPropertyValidator {
return false;
}
- protected List extractRepoProperties(SshUriProperties sshUriProperties) {
- List allRepoProperties = new ArrayList<>();
+ protected List extractRepoProperties(MultipleJGitEnvironmentProperties sshUriProperties) {
+ List allRepoProperties = new ArrayList<>();
allRepoProperties.add(sshUriProperties);
- Map repos = sshUriProperties.getRepos();
+ Map repos = sshUriProperties.getRepos();
if (repos != null) {
allRepoProperties.addAll(repos.values());
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUri.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUri.java
deleted file mode 100644
index a7211160..00000000
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUri.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.config.server.ssh;
-
-import org.springframework.cloud.config.server.ssh.SshUriProperties.SshUriNestedRepoProperties;
-
-import javax.validation.constraints.Pattern;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Base class that contains configuration properties for Git SSH properties
- *
- * @author Ollie Hughes
- */
-public abstract class SshUri {
- private String privateKey;
- private String uri;
- private String hostKeyAlgorithm;
- private String hostKey;
- private String knownHostsFile;
- @Pattern(regexp = "([\\w -]+,)*([\\w -]+)")
- private String preferredAuthentications;
- private boolean ignoreLocalSshSettings;
- private boolean strictHostKeyChecking = true;
-
- public static SshUriPropertiesBuilder builder() {
- return new SshUriPropertiesBuilder();
- }
-
- public String getUri() {
- return this.uri;
- }
-
- public String getHostKeyAlgorithm() {
- return this.hostKeyAlgorithm;
- }
-
- public String getHostKey() {
- return this.hostKey;
- }
-
- public String getKnownHostsFile() {
- return this.knownHostsFile;
- }
-
- public String getPreferredAuthentications() {
- return this.preferredAuthentications;
- }
-
- public String getPrivateKey() {
- return this.privateKey;
- }
-
- public boolean isIgnoreLocalSshSettings() {
- return this.ignoreLocalSshSettings;
- }
-
- public boolean isStrictHostKeyChecking() {
- return this.strictHostKeyChecking;
- }
-
- public void setUri(String uri) {
- this.uri = uri;
- }
-
- public void setHostKeyAlgorithm(String hostKeyAlgorithm) {
- this.hostKeyAlgorithm = hostKeyAlgorithm;
- }
-
- public void setHostKey(String hostKey) {
- this.hostKey = hostKey;
- }
-
- public void setKnownHostsFile(String knownHostsFile) {
- this.knownHostsFile = knownHostsFile;
- }
-
- public void setPreferredAuthentications(String preferredAuthentications) {
- this.preferredAuthentications = preferredAuthentications;
- }
-
- public void setPrivateKey(String privateKey) {
- this.privateKey = privateKey;
- }
-
- public void setIgnoreLocalSshSettings(boolean ignoreLocalSshSettings) {
- this.ignoreLocalSshSettings = ignoreLocalSshSettings;
- }
-
- public void setStrictHostKeyChecking(boolean strictHostKeyChecking) {
- this.strictHostKeyChecking = strictHostKeyChecking;
- }
-
- public String toString() {
- return "org.springframework.cloud.config.server.ssh.SshUriProperties(uri=" + this.getUri()
- + " hostKeyAlgorithm=" + this.getHostKeyAlgorithm()
- + ", hostKey=" + this.getHostKey()
- + ", privateKey=" + this.getPrivateKey()
- + ", ignoreLocalSshSettings=" + this.isIgnoreLocalSshSettings()
- + ", knownHostsFile=" + this.getKnownHostsFile()
- + ", preferredAuthentications=" + this.getPreferredAuthentications()
- + ", strictHostKeyChecking=" + this.isStrictHostKeyChecking() + ",)";
- }
-
- public static class SshUriPropertiesBuilder {
- private String uri;
- private String hostKeyAlgorithm;
- private String hostKey;
- private String privateKey;
- private String knownHostsFile;
- private String preferredAuthentications;
- private boolean ignoreLocalSshSettings;
- private boolean strictHostKeyChecking = true;
- private Map repos = new LinkedHashMap<>();
-
- SshUriPropertiesBuilder() {
- }
-
- public SshUri.SshUriPropertiesBuilder uri(String uri) {
- this.uri = uri;
- return this;
- }
-
- public SshUri.SshUriPropertiesBuilder hostKeyAlgorithm(String hostKeyAlgorithm) {
- this.hostKeyAlgorithm = hostKeyAlgorithm;
- return this;
- }
-
- public SshUri.SshUriPropertiesBuilder hostKey(String hostKey) {
- this.hostKey = hostKey;
- return this;
- }
-
- public SshUri.SshUriPropertiesBuilder privateKey(String privateKey) {
- this.privateKey = privateKey;
- return this;
- }
-
- public SshUri.SshUriPropertiesBuilder knownHostsFile(String knownHostsFile) {
- this.knownHostsFile = knownHostsFile;
- return this;
- }
-
- public SshUri.SshUriPropertiesBuilder preferredAuthentications(String preferredAuthentications) {
- this.preferredAuthentications = preferredAuthentications;
- return this;
- }
-
- public SshUri.SshUriPropertiesBuilder ignoreLocalSshSettings(boolean ignoreLocalSshSettings) {
- this.ignoreLocalSshSettings = ignoreLocalSshSettings;
- return this;
- }
-
- public SshUri.SshUriPropertiesBuilder strictHostKeyChecking(boolean strictHostKeyChecking) {
- this.strictHostKeyChecking = strictHostKeyChecking;
- return this;
- }
-
- public SshUri.SshUriPropertiesBuilder repos(Map repos) {
- this.repos = repos;
- return this;
- }
-
- public SshUriProperties build() {
- SshUriProperties sshUriProperties = new SshUriProperties();
- sshUriProperties.setRepos(repos);
- build(sshUriProperties);
- return sshUriProperties;
- }
-
- public SshUriNestedRepoProperties buildAsNestedRepo() {
- SshUriNestedRepoProperties sshUriNestedRepoProperties = new SshUriNestedRepoProperties();
- build(sshUriNestedRepoProperties);
- return sshUriNestedRepoProperties;
- }
-
- private void build(SshUri sshUriNestedRepoProperties) {
- sshUriNestedRepoProperties.setUri(uri);
- sshUriNestedRepoProperties.setHostKeyAlgorithm(hostKeyAlgorithm);
- sshUriNestedRepoProperties.setHostKey(hostKey);
- sshUriNestedRepoProperties.setPrivateKey(privateKey);
- sshUriNestedRepoProperties.setKnownHostsFile(knownHostsFile);
- sshUriNestedRepoProperties.setPreferredAuthentications(preferredAuthentications);
- sshUriNestedRepoProperties.setIgnoreLocalSshSettings(ignoreLocalSshSettings);
- sshUriNestedRepoProperties.setStrictHostKeyChecking(strictHostKeyChecking);
- }
-
- public String toString() {
- return "org.springframework.cloud.config.server.ssh.SshUriProperties.SshUriPropertiesBuilder(uri=" + this.uri
- + "hostKeyAlgorithm=" + this.hostKeyAlgorithm
- + ", hostKey=" + this.hostKey
- + ", privateKey=" + this.privateKey
- + ", knownHostsFile=" + this.knownHostsFile
- + ", preferredAuthentications=" + this.preferredAuthentications
- + ", ignoreLocalSshSettings=" + this.ignoreLocalSshSettings
- + ", strictHostKeyChecking=" + this.strictHostKeyChecking
- + ", repos=" + this.repos + ")";
- }
- }
-}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriProperties.java
deleted file mode 100644
index 7aa9879d..00000000
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriProperties.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2015 - 2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.config.server.ssh;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.validation.annotation.Validated;
-
-/**
- * Data container for property based SSH config
- *
- * @author Ollie Hughes
- */
-@ConfigurationProperties("spring.cloud.config.server.git")
-@Validated
-@PrivateKeyIsValid
-@HostKeyAndAlgoBothExist
-@HostKeyAlgoSupported
-@KnownHostsFileIsValid
-public class SshUriProperties extends SshUri {
-
- private Map repos = new LinkedHashMap<>();
-
- public Map getRepos() {
- return this.repos;
- }
-
- public void setRepos(Map repos) {
- this.repos = repos;
- }
-
- public void addRepo(String repoName, SshUriProperties.SshUriNestedRepoProperties properties) {
- this.repos.put(repoName, properties);
- }
-
- @Override
- public String toString() {
- return super.toString() + "{repos=" + repos + "}";
- }
-
- /**
- * Differentiate between sets of properties that are defined in nested Git repos.
- * This is to prevent boot from guarding against a potential infinite deserialization of nested properties.
- * This sub class differentiates from {@link SshUriProperties} as it does not contain the self mao
- */
- public static class SshUriNestedRepoProperties extends SshUri {
-
- }
-}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java
index 36cbf85a..c5465fb1 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 the original author or authors.
+ * Copyright 2015-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,9 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.jgit.transport.URIish;
-import org.springframework.cloud.config.server.ssh.SshUriProperties.SshUriNestedRepoProperties;
+
+import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties;
+import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
import static org.springframework.cloud.config.server.ssh.SshPropertyValidator.isSshUri;
@@ -32,25 +34,25 @@ import static org.springframework.cloud.config.server.ssh.SshPropertyValidator.i
*/
public class SshUriPropertyProcessor {
- private final SshUriProperties sshUriProperties;
+ private final MultipleJGitEnvironmentProperties sshUriProperties;
- public SshUriPropertyProcessor(SshUriProperties sshUriProperties) {
+ public SshUriPropertyProcessor(MultipleJGitEnvironmentProperties sshUriProperties) {
this.sshUriProperties = sshUriProperties;
}
- public Map getSshKeysByHostname() {
+ public Map getSshKeysByHostname() {
return extractNestedProperties(sshUriProperties);
}
- private Map extractNestedProperties(SshUriProperties uriProperties) {
- Map sshUriPropertyMap = new HashMap<>();
+ private Map extractNestedProperties(MultipleJGitEnvironmentProperties uriProperties) {
+ Map sshUriPropertyMap = new HashMap<>();
String parentUri = uriProperties.getUri();
if (isSshUri(parentUri) && getHostname(parentUri) != null) {
sshUriPropertyMap.put(getHostname(parentUri), uriProperties);
}
- Map repos = uriProperties.getRepos();
+ Map repos = uriProperties.getRepos();
if(repos != null) {
- for (SshUriNestedRepoProperties repoProperties : repos.values()) {
+ for (MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties repoProperties : repos.values()) {
String repoUri = repoProperties.getUri();
if (isSshUri(repoUri) && getHostname(repoUri) != null) {
sshUriPropertyMap.put(getHostname(repoUri), repoProperties);
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/AbstractScmAccessorProperties.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/AbstractScmAccessorProperties.java
index 0e050ed8..650fb5cc 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/AbstractScmAccessorProperties.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/AbstractScmAccessorProperties.java
@@ -25,14 +25,39 @@ import org.springframework.core.Ordered;
public class AbstractScmAccessorProperties implements EnvironmentRepositoryProperties {
static final String[] DEFAULT_LOCATIONS = new String[] { "/" };
+ /**
+ * URI of remote repository.
+ */
private String uri;
+ /**
+ * Base directory for local working copy of repository.
+ */
private File basedir;
+ /**
+ * Search paths to use within local working copy. By default searches only the root.
+ */
private String[] searchPaths = DEFAULT_LOCATIONS.clone();;
+ /**
+ * Username for authentication with remote repository.
+ */
private String username;
+ /**
+ * Password for authentication with remote repository.
+ */
private String password;
+ /**
+ * Passphrase for unlocking your ssh private key.
+ */
private String passphrase;
+ /**
+ * Reject incoming SSH host keys from remote servers not in the known host list.
+ */
private boolean strictHostKeyChecking = true;
+
+ /** The order of the environment repository. */
private int order = Ordered.LOWEST_PRECEDENCE;
+
+ /** The default label to be used with the remore repository */
private String defaultLabel;
public String getUri() {
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/GitCredentialsProviderFactory.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/GitCredentialsProviderFactory.java
index 8766255f..f69fc817 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/GitCredentialsProviderFactory.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/GitCredentialsProviderFactory.java
@@ -16,19 +16,21 @@
package org.springframework.cloud.config.server.support;
-import static org.springframework.util.StringUtils.hasText;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
+
import org.springframework.util.ClassUtils;
+import static org.springframework.util.StringUtils.hasText;
+
/**
- * A CredentialsProvider factory for Git repositories. Can handle AWS CodeCommit
+ * A CredentialsProvider factory for Git repositories. Can handle AWS CodeCommit
* repositories and other repositories with username/password.
*
* @author Don Laidlaw
+ * @author Gareth Clay
*
*/
public class GitCredentialsProviderFactory {
@@ -41,20 +43,43 @@ public class GitCredentialsProviderFactory {
* Enabled by default.
*/
protected boolean awsCodeCommitEnabled = true;
-
+
/**
- * Search for a credential provider that will handle the specified URI. If
- * not found, and the username has text, then create a default using the
- * provided username and password. Otherwise null.
+ * Search for a credential provider that will handle the specified URI. If not found,
+ * and the username or passphrase has text, then create a default using the provided
+ * username and password or passphrase. Otherwise null.
* @param uri the URI of the repository (cannot be null)
* @param username the username provided for the repository (may be null)
* @param password the password provided for the repository (may be null)
* @param passphrase the passphrase to unlock the ssh private key (may be null)
* @return the first matched credentials provider or the default or null.
+ * @deprecated in favour of {@link #createFor(String, String, String, String, boolean)}
*/
- public CredentialsProvider createFor(String uri,
- String username, String password, String passphrase) {
+ @Deprecated
+ public CredentialsProvider createFor(String uri, String username, String password,
+ String passphrase) {
+ return createFor(uri, username, password, passphrase, false);
+ }
+ /**
+ * Search for a credential provider that will handle the specified URI. If not found,
+ * and the username or passphrase has text, then create a default using the provided
+ * username and password or passphrase.
+ *
+ * If skipSslValidation is true and the URI has an https scheme, the default credential
+ * provider's behaviour is modified to suppress any SSL validation errors that occur
+ * when communicating via the URI.
+ *
+ * Otherwise null.
+ * @param uri the URI of the repository (cannot be null)
+ * @param username the username provided for the repository (may be null)
+ * @param password the password provided for the repository (may be null)
+ * @param passphrase the passphrase to unlock the ssh private key (may be null)
+ * @param skipSslValidation whether to skip SSL validation when connecting via HTTPS
+ * @return the first matched credentials provider or the default or null.
+ */
+ public CredentialsProvider createFor(String uri, String username, String password,
+ String passphrase, boolean skipSslValidation) {
CredentialsProvider provider = null;
if (awsAvailable() && AwsCodeCommitCredentialProvider.canHandle(uri)) {
logger.debug("Constructing AwsCodeCommitCredentialProvider for URI " + uri);
@@ -72,10 +97,15 @@ public class GitCredentialsProviderFactory {
provider = new PassphraseCredentialsProvider(passphrase);
}
+ if (skipSslValidation && GitSkipSslValidationCredentialsProvider.canHandle(uri)) {
+ logger.debug("Constructing GitSkipSslValidationCredentialsProvider for URI "
+ + uri);
+ provider = new GitSkipSslValidationCredentialsProvider(provider);
+ }
else {
logger.debug("No credentials provider required for URI " + uri);
}
-
+
return provider;
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/GitSkipSslValidationCredentialsProvider.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/GitSkipSslValidationCredentialsProvider.java
new file mode 100644
index 00000000..c3d8a61a
--- /dev/null
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/support/GitSkipSslValidationCredentialsProvider.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.cloud.config.server.support;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.errors.UnsupportedCredentialItem;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.transport.CredentialItem;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.URIish;
+
+/**
+ * A {@link CredentialsProvider} that will ignore any SSL validation errors that occur.
+ * This is primarily intended as a convenience for testing scenarios where self-signed
+ * certificates are being used.
+ *
+ * This class can be used as a decorator for another CredentialsProvider, adding SSL
+ * validation skipping behaviour to a repository that also requires authentication, for
+ * example.
+ *
+ * @author Gareth Clay
+ */
+public class GitSkipSslValidationCredentialsProvider extends CredentialsProvider {
+
+ private final CredentialsProvider delegate;
+
+ public GitSkipSslValidationCredentialsProvider(CredentialsProvider delegate) {
+ this.delegate = delegate;
+ }
+
+ /**
+ * This provider can handle uris like https://github.com/org/repo
+ */
+ public static boolean canHandle(String uri) {
+ return uri != null && uri.toLowerCase().startsWith("https://");
+ }
+
+ @Override
+ public boolean isInteractive() {
+ return (delegate != null) && delegate.isInteractive();
+ }
+
+ @Override
+ public boolean supports(CredentialItem... items) {
+ List unprocessedItems = new ArrayList<>();
+
+ for (CredentialItem item : items) {
+ if (item instanceof CredentialItem.InformationalMessage
+ && item.getPromptText() != null && item.getPromptText()
+ .contains(JGitText.get().sslFailureTrustExplanation))
+ continue;
+
+ if (item instanceof CredentialItem.YesNoType && item.getPromptText() != null
+ && (item.getPromptText().equals(JGitText.get().sslTrustNow)
+ || item.getPromptText()
+ .startsWith(stripFormattingPlaceholders(
+ JGitText.get().sslTrustForRepo))
+ || item.getPromptText()
+ .equals(JGitText.get().sslTrustAlways)))
+ continue;
+
+ unprocessedItems.add(item);
+ }
+
+ return unprocessedItems.isEmpty() || (delegate != null
+ && delegate.supports(unprocessedItems.toArray(new CredentialItem[0])));
+ }
+
+ @Override
+ public boolean get(URIish uri, CredentialItem... items)
+ throws UnsupportedCredentialItem {
+ List unprocessedItems = new ArrayList<>();
+
+ for (CredentialItem item : items) {
+ if (item instanceof CredentialItem.YesNoType) {
+ CredentialItem.YesNoType yesNoItem = (CredentialItem.YesNoType) item;
+ String prompt = yesNoItem.getPromptText();
+ if (prompt == null) {
+ unprocessedItems.add(item);
+ }
+ else if (prompt.equals(JGitText.get().sslTrustNow) || prompt.startsWith(
+ stripFormattingPlaceholders(JGitText.get().sslTrustForRepo))) {
+ yesNoItem.setValue(true);
+ }
+ else if (prompt.equals(JGitText.get().sslTrustAlways)) {
+ yesNoItem.setValue(false);
+ }
+ else {
+ unprocessedItems.add(item);
+ }
+ }
+ else if (!item.getPromptText()
+ .contains(JGitText.get().sslFailureTrustExplanation)) {
+ unprocessedItems.add(item);
+ }
+ }
+
+ if (unprocessedItems.isEmpty()) {
+ return true;
+ }
+ if (delegate != null) {
+ return delegate.get(uri, unprocessedItems.toArray(new CredentialItem[0]));
+ }
+ throw new UnsupportedCredentialItem(uri,
+ unprocessedItems.size() + " credential items not supported");
+ }
+
+ @Override
+ public void reset(URIish uri) {
+ if (delegate != null) {
+ delegate.reset(uri);
+ }
+ }
+
+ private static String stripFormattingPlaceholders(String string) {
+ return string.replaceAll("\\s*\\{\\d}\\s*", "");
+ }
+}
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java
index 98a06fd9..3ca53211 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2017 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import org.junit.runners.Suite.SuiteClasses;
import org.springframework.cloud.config.server.config.ConfigServerHealthIndicatorTests;
import org.springframework.cloud.config.server.config.CustomCompositeEnvironmentRepositoryTests;
import org.springframework.cloud.config.server.config.CustomEnvironmentRepositoryTests;
-import org.springframework.cloud.config.server.config.TransportConfigurationTest;
import org.springframework.cloud.config.server.credentials.AwsCodeCommitCredentialsProviderTests;
import org.springframework.cloud.config.server.credentials.GitCredentialsProviderFactoryTests;
import org.springframework.cloud.config.server.encryption.CipherEnvironmentEncryptorTests;
@@ -108,7 +107,6 @@ import org.springframework.cloud.config.server.ssh.SshUriPropertyProcessorTest;
ConfigServerHealthIndicatorTests.class,
CustomCompositeEnvironmentRepositoryTests.class,
CustomEnvironmentRepositoryTests.class,
- TransportConfigurationTest.class,
BootstrapConfigServerIntegrationTests.class,
})
@Ignore
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/TransportConfigurationIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/TransportConfigurationIntegrationTests.java
index b22b3166..3d755412 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/TransportConfigurationIntegrationTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/TransportConfigurationIntegrationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 the original author or authors.
+ * Copyright 2015-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,9 @@
package org.springframework.cloud.config.server;
+import java.io.File;
+import java.lang.reflect.Method;
+
import com.jcraft.jsch.Session;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
@@ -25,20 +28,22 @@ import org.eclipse.jgit.util.FS;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.cloud.config.server.config.TransportConfiguration;
+import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentRepository;
+import org.springframework.cloud.config.server.ssh.FileBasedSshTransportConfigCallback;
+import org.springframework.cloud.config.server.ssh.PropertiesBasedSshTransportConfigCallback;
import org.springframework.cloud.config.server.ssh.SshPropertyValidator;
-import org.springframework.cloud.config.server.ssh.SshUriProperties;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
-import java.io.File;
-import java.lang.reflect.Method;
-
import static junit.framework.TestCase.assertTrue;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -49,124 +54,251 @@ import static org.mockito.Mockito.verify;
*/
public class TransportConfigurationIntegrationTests {
- @RunWith(SpringRunner.class)
- @SpringBootTest(classes = {ConfigServerApplication.class, TransportConfiguration.class, SshPropertyValidator.class},
- webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
- properties = {
- "spring.config.name:ssh/ssh-private-key-block",})
- @ActiveProfiles({"test", "git"})
public static class PropertyBasedCallbackTest {
- @Autowired
- private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
+ @RunWith(SpringRunner.class)
+ @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class},
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {"spring.config.name:ssh/ssh-private-key-block"})
+ @ActiveProfiles({"test", "git"})
+ public static class StaticTest {
- @Test
- public void propertyBasedTransportCallbackIsConfigured() throws Exception {
- TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
- assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.PropertiesBasedSshTransportConfigCallback.class)));
- }
- }
+ @Autowired
+ private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
- @RunWith(SpringRunner.class)
- @SpringBootTest(classes = {ConfigServerApplication.class, TransportConfiguration.class, SshPropertyValidator.class},
- webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
- properties = {
- "spring.config.name:ssh/ssh-private-key-newline"
- })
- @ActiveProfiles({"test", "git"})
- public static class PrivateKeyPropertyWithLineBreaks {
-
- @Autowired
- private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
-
- @Test
- public void privateKeyPropertyWithLineBreaks() throws Exception {
- TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
- assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.PropertiesBasedSshTransportConfigCallback.class)));
-
- TransportConfiguration.PropertiesBasedSshTransportConfigCallback configCallback =
- (TransportConfiguration.PropertiesBasedSshTransportConfigCallback) transportConfigCallback;
- assertThat(configCallback.getSshUriProperties().getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1)));
- }
- }
-
-
- @RunWith(SpringRunner.class)
- @SpringBootTest(classes = {ConfigServerApplication.class, TransportConfiguration.class, SshPropertyValidator.class},
- webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
- properties = {
- "spring.config.name:ssh/ssh-nested-settings"
- })
- @ActiveProfiles({"test", "git"})
- public static class SshPropertiesWithinNestedRepo {
-
- @Autowired
- private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
-
- @Test
- public void sshPropertiesWithinNestedRepo() throws Exception {
- TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
- assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.PropertiesBasedSshTransportConfigCallback.class)));
-
- TransportConfiguration.PropertiesBasedSshTransportConfigCallback configCallback =
- (TransportConfiguration.PropertiesBasedSshTransportConfigCallback) transportConfigCallback;
- SshUriProperties sshUriProperties = configCallback.getSshUriProperties();
- assertThat(sshUriProperties.getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1)));
-
- assertThat(sshUriProperties.getRepos().get("repo1"), is(notNullValue()));
- assertThat(sshUriProperties.getRepos().get("repo1").getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_2)));
- }
- }
-
- @RunWith(SpringRunner.class)
- @SpringBootTest(classes = {ConfigServerApplication.class, TransportConfiguration.class, SshPropertyValidator.class},
- webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
- properties = {
- "spring.cloud.config.server.git.uri=git@gitserver.com:team/repo.git",
- "spring.cloud.config.server.git.ignoreLocalSshSettings=false",})
- @ActiveProfiles({"test", "git"})
- public static class FileBasedCallbackTest {
-
- @Autowired
- private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
-
- @Test
- public void fileBasedTransportCallbackIsConfigured() throws Exception {
- TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
- assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.FileBasedSshTransportConfigCallback.class)));
- }
-
-
- @Test
- public void strictHostKeyCheckShouldCheck() throws Exception {
- String uri = "git+ssh://git@somegitserver/somegitrepo";
- SshSessionFactory.setInstance(null);
- jGitEnvironmentRepository.setUri(uri);
- jGitEnvironmentRepository.setBasedir(new File("./mybasedir"));
- assertTrue(jGitEnvironmentRepository.isStrictHostKeyChecking());
- jGitEnvironmentRepository.setCloneOnStart(true);
- try {
- // this will throw but we don't care about connecting.
- jGitEnvironmentRepository.afterPropertiesSet();
- } catch (Exception e) {
- final OpenSshConfig.Host hc = OpenSshConfig.get(FS.detect()).lookup("github.com");
- JschConfigSessionFactory factory = (JschConfigSessionFactory) SshSessionFactory.getInstance();
- // There's no public method that can be used to inspect the ssh
- // configuration, so we'll reflect
- // the configure method to allow us to check that the config
- // property is set as expected.
- Method configure = factory.getClass().getDeclaredMethod("configure", OpenSshConfig.Host.class,
- Session.class);
- configure.setAccessible(true);
- Session session = mock(Session.class);
- ArgumentCaptor keyCaptor = ArgumentCaptor.forClass(String.class);
- ArgumentCaptor valueCaptor = ArgumentCaptor.forClass(String.class);
- configure.invoke(factory, hc, session);
- verify(session).setConfig(keyCaptor.capture(), valueCaptor.capture());
- configure.setAccessible(false);
- assertTrue("yes".equals(valueCaptor.getValue()));
+ @Test
+ public void propertyBasedTransportCallbackIsConfigured() throws Exception {
+ TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
+ assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class)));
}
}
+
+ @RunWith(SpringRunner.class)
+ @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class},
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {"spring.config.name:ssh/ssh-private-key-block-list"})
+ @ActiveProfiles({"test", "composite"})
+ public static class ListTest {
+
+ @Autowired
+ private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
+
+ @Test
+ public void propertyBasedTransportCallbackIsConfigured() throws Exception {
+ TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
+ assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class)));
+ }
+ }
+
+ }
+
+ public static class PrivateKeyPropertyWithLineBreaks {
+
+ @RunWith(SpringRunner.class)
+ @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class},
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {
+ "spring.config.name:ssh/ssh-private-key-newline"
+ })
+ @ActiveProfiles({"test", "git"})
+ public static class StaticTest {
+
+ @Autowired
+ private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
+
+ @Test
+ public void privateKeyPropertyWithLineBreaks() throws Exception {
+ TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
+ assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class)));
+
+ PropertiesBasedSshTransportConfigCallback configCallback =
+ (PropertiesBasedSshTransportConfigCallback) transportConfigCallback;
+ assertThat(configCallback.getSshUriProperties().getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1)));
+ }
+ }
+
+ @RunWith(SpringRunner.class)
+ @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class},
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {
+ "spring.config.name:ssh/ssh-private-key-newline-list"
+ })
+ @ActiveProfiles({"test", "composite"})
+ public static class ListTest {
+
+ @Autowired
+ private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
+
+ @Test
+ public void privateKeyPropertyWithLineBreaks() throws Exception {
+ TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
+ assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class)));
+
+ PropertiesBasedSshTransportConfigCallback configCallback =
+ (PropertiesBasedSshTransportConfigCallback) transportConfigCallback;
+ assertThat(configCallback.getSshUriProperties().getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1)));
+ }
+ }
+
+ }
+
+ public static class SshPropertiesWithinNestedRepo {
+
+ @RunWith(SpringRunner.class)
+ @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class},
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {
+ "spring.config.name:ssh/ssh-nested-settings"
+ })
+ @ActiveProfiles({"test", "git"})
+ public static class StaticTest {
+ @Autowired
+ private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
+
+ @Test
+ public void sshPropertiesWithinNestedRepo() throws Exception {
+ TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
+ assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class)));
+
+ PropertiesBasedSshTransportConfigCallback configCallback =
+ (PropertiesBasedSshTransportConfigCallback) transportConfigCallback;
+ MultipleJGitEnvironmentProperties sshUriProperties = configCallback.getSshUriProperties();
+ assertThat(sshUriProperties.getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1)));
+
+ assertThat(sshUriProperties.getRepos().get("repo1"), is(notNullValue()));
+ assertThat(sshUriProperties.getRepos().get("repo1").getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_2)));
+ }
+ }
+
+ @RunWith(SpringRunner.class)
+ @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class},
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {
+ "spring.config.name:ssh/ssh-nested-settings-list"
+ })
+ @ActiveProfiles({"test", "composite"})
+ public static class ListTest {
+ @Autowired
+ private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
+
+ @Test
+ public void sshPropertiesWithinNestedRepo() throws Exception {
+ TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
+ assertThat(transportConfigCallback, is(instanceOf(PropertiesBasedSshTransportConfigCallback.class)));
+
+ PropertiesBasedSshTransportConfigCallback configCallback =
+ (PropertiesBasedSshTransportConfigCallback) transportConfigCallback;
+ MultipleJGitEnvironmentProperties sshUriProperties = configCallback.getSshUriProperties();
+ assertThat(sshUriProperties.getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_1)));
+
+ assertThat(sshUriProperties.getRepos().get("repo1"), is(notNullValue()));
+ assertThat(sshUriProperties.getRepos().get("repo1").getPrivateKey(), is(equalTo(TestProperties.TEST_PRIVATE_KEY_2)));
+ }
+ }
+
+ }
+
+ public static class FileBasedCallbackTest {
+
+ @RunWith(SpringRunner.class)
+ @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class},
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {
+ "spring.cloud.config.server.git.uri=git@gitserver.com:team/repo.git",
+ "spring.cloud.config.server.git.ignoreLocalSshSettings=false",})
+ @ActiveProfiles({"test", "git"})
+ public static class StaticTest {
+ @Autowired
+ private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
+
+ @Test
+ public void fileBasedTransportCallbackIsConfigured() throws Exception {
+ TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
+ assertThat(transportConfigCallback, is(instanceOf(FileBasedSshTransportConfigCallback.class)));
+ }
+
+ @Test
+ public void strictHostKeyCheckShouldCheck() throws Exception {
+ String uri = "git+ssh://git@somegitserver/somegitrepo";
+ SshSessionFactory.setInstance(null);
+ jGitEnvironmentRepository.setUri(uri);
+ jGitEnvironmentRepository.setBasedir(new File("./mybasedir"));
+ assertTrue(jGitEnvironmentRepository.isStrictHostKeyChecking());
+ jGitEnvironmentRepository.setCloneOnStart(true);
+ try {
+ // this will throw but we don't care about connecting.
+ jGitEnvironmentRepository.afterPropertiesSet();
+ } catch (Exception e) {
+ final OpenSshConfig.Host hc = OpenSshConfig.get(FS.detect()).lookup("github.com");
+ JschConfigSessionFactory factory = (JschConfigSessionFactory) SshSessionFactory.getInstance();
+ // There's no public method that can be used to inspect the ssh
+ // configuration, so we'll reflect
+ // the configure method to allow us to check that the config
+ // property is set as expected.
+ Method configure = factory.getClass().getDeclaredMethod("configure", OpenSshConfig.Host.class,
+ Session.class);
+ configure.setAccessible(true);
+ Session session = mock(Session.class);
+ ArgumentCaptor keyCaptor = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor valueCaptor = ArgumentCaptor.forClass(String.class);
+ configure.invoke(factory, hc, session);
+ verify(session).setConfig(keyCaptor.capture(), valueCaptor.capture());
+ configure.setAccessible(false);
+ assertTrue("yes".equals(valueCaptor.getValue()));
+ }
+ }
+ }
+
+ @RunWith(SpringRunner.class)
+ @SpringBootTest(classes = {ConfigServerApplication.class, SshPropertyValidator.class},
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {
+ "spring.cloud.config.server.composite[0].type=git",
+ "spring.cloud.config.server.composite[0].uri=git@gitserver.com:team/repo.git",
+ "spring.cloud.config.server.composite[0].ignoreLocalSshSettings=false",})
+ @ActiveProfiles({"test", "composite"})
+ public static class ListTest {
+ @Autowired
+ private MultipleJGitEnvironmentRepository jGitEnvironmentRepository;
+
+ @Test
+ public void fileBasedTransportCallbackIsConfigured() throws Exception {
+ TransportConfigCallback transportConfigCallback = jGitEnvironmentRepository.getTransportConfigCallback();
+ assertThat(transportConfigCallback, is(instanceOf(FileBasedSshTransportConfigCallback.class)));
+ }
+
+ @Test
+ public void strictHostKeyCheckShouldCheck() throws Exception {
+ String uri = "git+ssh://git@somegitserver/somegitrepo";
+ SshSessionFactory.setInstance(null);
+ jGitEnvironmentRepository.setUri(uri);
+ jGitEnvironmentRepository.setBasedir(new File("./mybasedir"));
+ assertTrue(jGitEnvironmentRepository.isStrictHostKeyChecking());
+ jGitEnvironmentRepository.setCloneOnStart(true);
+ try {
+ // this will throw but we don't care about connecting.
+ jGitEnvironmentRepository.afterPropertiesSet();
+ } catch (Exception e) {
+ final OpenSshConfig.Host hc = OpenSshConfig.get(FS.detect()).lookup("github.com");
+ JschConfigSessionFactory factory = (JschConfigSessionFactory) SshSessionFactory.getInstance();
+ // There's no public method that can be used to inspect the ssh
+ // configuration, so we'll reflect
+ // the configure method to allow us to check that the config
+ // property is set as expected.
+ Method configure = factory.getClass().getDeclaredMethod("configure", OpenSshConfig.Host.class,
+ Session.class);
+ configure.setAccessible(true);
+ Session session = mock(Session.class);
+ ArgumentCaptor keyCaptor = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor valueCaptor = ArgumentCaptor.forClass(String.class);
+ configure.invoke(factory, hc, session);
+ verify(session).setConfig(keyCaptor.capture(), valueCaptor.capture());
+ configure.setAccessible(false);
+ assertTrue("yes".equals(valueCaptor.getValue()));
+ }
+ }
+ }
+
}
private static class TestProperties {
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/TransportConfigurationTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/TransportConfigurationTest.java
deleted file mode 100644
index 40296eef..00000000
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/TransportConfigurationTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2015 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cloud.config.server.config;
-
-import org.eclipse.jgit.api.TransportConfigCallback;
-import org.junit.Test;
-import org.springframework.cloud.config.server.ssh.SshUri;
-import org.springframework.cloud.config.server.ssh.SshUriProperties;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.instanceOf;
-/**
-* @author Ollie Hughes
-*/
-public class TransportConfigurationTest {
- @Test
- public void propertiesBasedSshTransportCallbackCreated() throws Exception {
- SshUriProperties ignoreLocalSettings = SshUri.builder()
- .uri("user@gitrepo.com:proj/repo")
- .ignoreLocalSshSettings(true)
- .build();
- TransportConfiguration transportConfiguration = new TransportConfiguration();
- TransportConfigCallback transportConfigCallback = transportConfiguration.propertiesBasedSshTransportCallback(ignoreLocalSettings);
- assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.PropertiesBasedSshTransportConfigCallback.class)));
- }
-
- @Test
- public void fileBasedSshTransportCallbackCreated() throws Exception {
- SshUriProperties dontIgnoreLocalSettings = SshUri.builder()
- .uri("user@gitrepo.com:proj/repo")
- .ignoreLocalSshSettings(false)
- .build();
-
- TransportConfiguration transportConfiguration = new TransportConfiguration();
- TransportConfigCallback transportConfigCallback = transportConfiguration.propertiesBasedSshTransportCallback(dontIgnoreLocalSettings);
- assertThat(transportConfigCallback, is(instanceOf(TransportConfiguration.FileBasedSshTransportConfigCallback.class)));
-
- }
-
-}
\ No newline at end of file
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/AwsCodeCommitCredentialsProviderTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/AwsCodeCommitCredentialsProviderTests.java
index 6eb6018f..9909d491 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/AwsCodeCommitCredentialsProviderTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/AwsCodeCommitCredentialsProviderTests.java
@@ -18,16 +18,16 @@ package org.springframework.cloud.config.server.credentials;
import java.net.URISyntaxException;
+import com.amazonaws.auth.AWSCredentialsProvider;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.URIish;
import org.junit.Before;
import org.junit.Test;
+
import org.springframework.cloud.config.server.support.AwsCodeCommitCredentialProvider;
import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory;
-import com.amazonaws.auth.AWSCredentialsProvider;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -56,7 +56,7 @@ public class AwsCodeCommitCredentialsProviderTests {
public void init() {
GitCredentialsProviderFactory factory = new GitCredentialsProviderFactory();
provider = (AwsCodeCommitCredentialProvider)
- factory.createFor(AWS_REPO, USER, PASSWORD, null);
+ factory.createFor(AWS_REPO, USER, PASSWORD, null, false);
}
@Test
@@ -116,7 +116,7 @@ public class AwsCodeCommitCredentialsProviderTests {
public void testUriWithCurlyBracesReturnsTrue() throws UnsupportedCredentialItem, URISyntaxException {
GitCredentialsProviderFactory factory = new GitCredentialsProviderFactory();
provider = (AwsCodeCommitCredentialProvider)
- factory.createFor(CURLY_BRACES_REPO, USER, PASSWORD, null);
+ factory.createFor(CURLY_BRACES_REPO, USER, PASSWORD, null, false);
CredentialItem[] credentialItems = makeCredentialItems();
assertTrue(provider.get(new URIish(CURLY_BRACES_REPO), credentialItems));
}
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/GitCredentialsProviderFactoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/GitCredentialsProviderFactoryTests.java
index 7ed5107e..5718fe01 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/GitCredentialsProviderFactoryTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/credentials/GitCredentialsProviderFactoryTests.java
@@ -20,9 +20,11 @@ import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.junit.Before;
import org.junit.Test;
+
import org.springframework.cloud.config.server.support.AwsCodeCommitCredentialProvider;
import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory;
import org.springframework.cloud.config.server.support.PassphraseCredentialsProvider;
+import org.springframework.cloud.config.server.support.GitSkipSslValidationCredentialsProvider;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -32,13 +34,14 @@ import static org.junit.Assert.assertTrue;
/**
* @author don laidlaw
- *
+ * @author Gareth Clay
*/
public class GitCredentialsProviderFactoryTests {
private static final String PASSWORD = "secret";
private static final String USER = "test";
private static final String FILE_REPO = "file:///home/user/repo";
- private static final String GIT_REPO = "https://github.com/spring-cloud/spring-cloud-config-test";
+ private static final String HTTPS_GIT_REPO = "https://github.com/spring-cloud/spring-cloud-config-test";
+ private static final String SSH_GIT_REPO = "git@github.com:spring-cloud/spring-cloud-config-test.git";
private static final String AWS_REPO = "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/test";
private GitCredentialsProviderFactory factory;
@@ -50,33 +53,62 @@ public class GitCredentialsProviderFactoryTests {
@Test
public void testCreateForFileNoUsernameIsNull() {
- CredentialsProvider provider = factory.createFor(FILE_REPO, null, null, null);
+ CredentialsProvider provider = factory.createFor(FILE_REPO, null, null, null,
+ false);
assertNull(provider);
}
@Test
public void testCreateForFileWithUsername() {
- CredentialsProvider provider = factory.createFor(FILE_REPO, USER, PASSWORD, null);
+ CredentialsProvider provider = factory.createFor(FILE_REPO, USER, PASSWORD, null,
+ false);
assertNotNull(provider);
assertTrue(provider instanceof UsernamePasswordCredentialsProvider);
}
@Test
public void testCreateForServerNoUsernameIsNull() {
- CredentialsProvider provider = factory.createFor(GIT_REPO, null, null, null);
+ CredentialsProvider provider = factory.createFor(HTTPS_GIT_REPO, null, null, null,
+ false);
assertNull(provider);
}
@Test
public void testCreateForServerWithUsername() {
- CredentialsProvider provider = factory.createFor(GIT_REPO, USER, PASSWORD, null);
+ CredentialsProvider provider = factory.createFor(HTTPS_GIT_REPO, USER, PASSWORD,
+ null, false);
+ assertNotNull(provider);
+ assertTrue(provider instanceof UsernamePasswordCredentialsProvider);
+ }
+
+ @Test
+ public void testCreateForHttpsServerWithSkipSslValidation() {
+ CredentialsProvider provider = factory.createFor(HTTPS_GIT_REPO, USER, PASSWORD,
+ null, true);
+ assertNotNull(provider);
+ assertTrue(provider instanceof GitSkipSslValidationCredentialsProvider);
+ }
+
+ @Test
+ public void testCreateForHttpsServerWithoutSpecifyingSkipSslValidation() {
+ CredentialsProvider provider = factory.createFor(HTTPS_GIT_REPO, USER, PASSWORD, null);
+ assertNotNull(provider);
+ assertTrue("deprecated createFor() should not enable ssl validation skipping",
+ provider instanceof UsernamePasswordCredentialsProvider);
+ }
+
+ @Test
+ public void testCreateForSshServerWithSkipSslValidation() {
+ CredentialsProvider provider = factory.createFor(SSH_GIT_REPO, USER, PASSWORD,
+ null, true);
assertNotNull(provider);
assertTrue(provider instanceof UsernamePasswordCredentialsProvider);
}
@Test
public void testCreateForAwsNoUsername() {
- CredentialsProvider provider = factory.createFor(AWS_REPO, null, null, null);
+ CredentialsProvider provider = factory.createFor(AWS_REPO, null, null, null,
+ false);
assertNotNull(provider);
assertTrue(provider instanceof AwsCodeCommitCredentialProvider);
AwsCodeCommitCredentialProvider aws = (AwsCodeCommitCredentialProvider) provider;
@@ -86,7 +118,8 @@ public class GitCredentialsProviderFactoryTests {
@Test
public void testCreateForAwsWithUsername() {
- CredentialsProvider provider = factory.createFor(AWS_REPO, USER, PASSWORD, null);
+ CredentialsProvider provider = factory.createFor(AWS_REPO, USER, PASSWORD, null,
+ false);
assertNotNull(provider);
assertTrue(provider instanceof AwsCodeCommitCredentialProvider);
AwsCodeCommitCredentialProvider aws = (AwsCodeCommitCredentialProvider) provider;
@@ -97,20 +130,21 @@ public class GitCredentialsProviderFactoryTests {
@Test
public void testCreateForAwsDisabled() {
factory.setAwsCodeCommitEnabled(false);
- CredentialsProvider provider = factory.createFor(AWS_REPO, null, null, null);
+ CredentialsProvider provider = factory.createFor(AWS_REPO, null, null, null,
+ false);
assertNull(provider);
- provider = factory.createFor(AWS_REPO, USER, PASSWORD, null);
+ provider = factory.createFor(AWS_REPO, USER, PASSWORD, null, false);
assertNotNull(provider);
assertTrue(provider instanceof UsernamePasswordCredentialsProvider);
}
@Test
public void testCreatePassphraseCredentialProvider() {
- CredentialsProvider provider = factory.createFor(GIT_REPO, null, null, PASSWORD);
+ CredentialsProvider provider = factory.createFor(HTTPS_GIT_REPO, null, null,
+ PASSWORD, false);
assertNotNull(provider);
assertTrue(provider instanceof PassphraseCredentialsProvider);
}
-
@Test
public void testIsAwsCodeCommitEnabled() {
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java
index 8aa218ff..0f3c01bc 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerIntegrationTests.java
@@ -16,16 +16,17 @@
package org.springframework.cloud.config.server.environment;
+import java.util.HashMap;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
-
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.config.environment.Environment;
+import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.cloud.config.server.environment.EnvironmentControllerIntegrationTests.ControllerConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -52,23 +53,26 @@ public class EnvironmentControllerIntegrationTests {
private MockMvc mvc;
@Autowired
private EnvironmentRepository repository;
+
+ private Environment environment = new Environment("foo", "default");
@Before
public void init() {
Mockito.reset(this.repository);
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
+ environment.add(new PropertySource("foo", new HashMap<>()));
}
@Test
public void environmentNoLabel() throws Exception {
- Mockito.when(this.repository.findOne("foo", "default", null)).thenReturn(new Environment("foo", "default"));
+ Mockito.when(this.repository.findOne("foo", "default", null)).thenReturn(this.environment);
this.mvc.perform(MockMvcRequestBuilders.get("/foo/default")).andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(this.repository).findOne("foo", "default", null);
}
@Test
public void propertiesNoLabel() throws Exception {
- Mockito.when(this.repository.findOne("foo", "default", null)).thenReturn(new Environment("foo", "default"));
+ Mockito.when(this.repository.findOne("foo", "default", null)).thenReturn(this.environment);
this.mvc.perform(MockMvcRequestBuilders.get("/foo-default.properties"))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(this.repository).findOne("foo", "default", null);
@@ -76,7 +80,7 @@ public class EnvironmentControllerIntegrationTests {
@Test
public void propertiesLabel() throws Exception {
- Mockito.when(this.repository.findOne("foo", "default", "label")).thenReturn(new Environment("foo", "default"));
+ Mockito.when(this.repository.findOne("foo", "default", "label")).thenReturn(this.environment);
this.mvc.perform(MockMvcRequestBuilders.get("/label/foo-default.properties"))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(this.repository).findOne("foo", "default", "label");
@@ -84,8 +88,10 @@ public class EnvironmentControllerIntegrationTests {
@Test
public void propertiesLabelWhenApplicationNameContainsHyphen() throws Exception {
+ Environment environment = new Environment("foo-bar", "default");
+ environment.add(new PropertySource("foo", new HashMap<>()));
Mockito.when(this.repository.findOne("foo-bar", "default", "label"))
- .thenReturn(new Environment("foo-bar", "default"));
+ .thenReturn(this.environment);
this.mvc.perform(MockMvcRequestBuilders.get("/label/foo-bar-default.properties"))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(this.repository).findOne("foo-bar", "default", "label");
@@ -93,8 +99,9 @@ public class EnvironmentControllerIntegrationTests {
@Test
public void propertiesLabelWithSlash() throws Exception {
+
Mockito.when(this.repository.findOne("foo", "default", "label/spam"))
- .thenReturn(new Environment("foo", "default"));
+ .thenReturn(this.environment);
this.mvc.perform(MockMvcRequestBuilders.get("/label(_)spam/foo-default.properties"))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(this.repository).findOne("foo", "default", "label/spam");
@@ -103,7 +110,7 @@ public class EnvironmentControllerIntegrationTests {
@Test
public void environmentWithLabel() throws Exception {
Mockito.when(this.repository.findOne("foo", "default", "awesome"))
- .thenReturn(new Environment("foo", "default"));
+ .thenReturn(this.environment);
this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/awesome"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
@@ -126,7 +133,7 @@ public class EnvironmentControllerIntegrationTests {
@Test
public void environmentWithLabelContainingPeriod() throws Exception {
- Mockito.when(this.repository.findOne("foo", "default", "1.0.0")).thenReturn(new Environment("foo", "default"));
+ Mockito.when(this.repository.findOne("foo", "default", "1.0.0")).thenReturn(this.environment);
this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/1.0.0"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
@@ -134,7 +141,7 @@ public class EnvironmentControllerIntegrationTests {
@Test
public void environmentWithLabelContainingSlash() throws Exception {
Mockito.when(this.repository.findOne("foo", "default", "feature/puff"))
- .thenReturn(new Environment("foo", "default"));
+ .thenReturn(this.environment);
this.mvc.perform(MockMvcRequestBuilders.get("/foo/default/feature(_)puff"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string(Matchers.containsString("\"propertySources\":")));
@@ -142,8 +149,10 @@ public class EnvironmentControllerIntegrationTests {
@Test
public void environmentWithApplicationContainingSlash() throws Exception {
+ Environment environment = new Environment("foo/app", "default");
+ environment.add(new PropertySource("foo", new HashMap<>()));
Mockito.when(this.repository.findOne("foo/app", "default", null))
- .thenReturn(new Environment("foo/app", "default"));
+ .thenReturn(environment);
this.mvc.perform(MockMvcRequestBuilders.get("/foo(_)app/default"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string(Matchers.containsString("\"propertySources\":")));
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerTests.java
index 7e1d92e5..d6c8cbbe 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/EnvironmentControllerTests.java
@@ -65,6 +65,7 @@ public class EnvironmentControllerTests {
@Before
public void init() {
this.controller = new EnvironmentController(this.repository);
+ environment.add(new PropertySource("foo", new HashMap<>()));
}
@After
@@ -195,27 +196,47 @@ public class EnvironmentControllerTests {
assertThat(environment.getProfiles(), equalTo(new String[] { "master" }));
assertThat(environment.getLabel(), equalTo("master"));
assertThat(environment.getVersion(), nullValue());
- assertThat(environment.getPropertySources(), hasSize(2));
+ assertThat(environment.getPropertySources(), hasSize(3));
assertThat(environment.getPropertySources().get(0).getName(), equalTo("two"));
assertThat(environment.getPropertySources().get(0).getSource().entrySet(),
hasSize(2));
- assertThat(environment.getPropertySources().get(1).getName(), equalTo("one"));
- assertThat(environment.getPropertySources().get(1).getSource().entrySet(),
+ assertThat(environment.getPropertySources().get(2).getName(), equalTo("one"));
+ assertThat(environment.getPropertySources().get(2).getSource().entrySet(),
hasSize(3));
}
@Test
public void testNameWithSlash() {
- this.controller.labelled("foo(_)spam", "bar", "two");
-
- Mockito.verify(this.repository).findOne("foo/spam", "bar", "two");
- }
+ Mockito.when(this.repository.findOne("foo/spam", "bar", "two")).thenReturn(this.environment);
+ Environment returnedEnvironment = this.controller.labelled("foo(_)spam", "bar", "two");
+
+ assertEquals(this.environment.getLabel(), returnedEnvironment.getLabel());
+ assertEquals(this.environment.getName(), returnedEnvironment.getName());
+
+ }
+ @Test(expected=EnvironmentNotFoundException.class)
+ public void testEnvironmentNotFound() {
+ this.controller.setAcceptEmpty(false);
+ this.controller.labelled("foo", "bar", null);
+ }
+ @Test
+ public void testwithValidEnvironment() {
+ Mockito.when(this.repository.findOne("foo", "bar",null))
+ .thenReturn(this.environment);
+ Environment environment = this.controller.labelled("foo", "bar", null);
+ assertThat(environment, not(nullValue()));
+
+ }
@Test
public void testLabelWithSlash() {
- this.controller.labelled("foo", "bar", "two(_)spam");
- Mockito.verify(this.repository).findOne("foo", "bar", "two/spam");
+ Mockito.when(this.repository.findOne("foo", "bar", "two/spam")).thenReturn(this.environment);
+
+ Environment returnedEnvironment = this.controller.labelled("foo", "bar", "two(_)spam");
+
+ assertEquals(this.environment.getLabel(), returnedEnvironment.getLabel());
+ assertEquals(this.environment.getName(), returnedEnvironment.getName());
}
@Test
@@ -491,6 +512,15 @@ public class EnvironmentControllerTests {
mvc.perform(MockMvcRequestBuilders.get("/foo/bar/other"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
+
+ @Test
+ public void environmentMissing() throws Exception {
+ Mockito.when(this.repository.findOne("foo1", "notfound", null))
+ .thenThrow(new EnvironmentNotFoundException("Missing Environment"));
+ MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
+ mvc.perform(MockMvcRequestBuilders.get("/foo1/notfound"))
+ .andExpect(MockMvcResultMatchers.status().isNotFound());
+ }
@Test
public void mappingForYaml() throws Exception {
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositorySslTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositorySslTests.java
new file mode 100644
index 00000000..cb744124
--- /dev/null
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositorySslTests.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.config.server.environment;
+
+import java.io.File;
+import java.net.URL;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.junit.http.SimpleHttpServer;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.config.server.config.ConfigServerProperties;
+import org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+public class JGitEnvironmentRepositorySslTests {
+
+ private static SimpleHttpServer server;
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ URL repoUrl = JGitEnvironmentRepositorySslTests.class
+ .getResource("/test1-config-repo/git");
+ Repository repo = new FileRepository(new File(repoUrl.toURI()));
+ server = new SimpleHttpServer(repo, true);
+ server.start();
+ }
+
+ @AfterClass
+ public static void teardown() throws Exception {
+ server.stop();
+ }
+
+ @Test(expected = CertificateException.class)
+ public void selfSignedCertIsRejected() throws Throwable {
+ ConfigurableApplicationContext context = new SpringApplicationBuilder(
+ TestConfiguration.class).properties(configServerProperties())
+ .web(WebApplicationType.NONE).run();
+
+ JGitEnvironmentRepository repository = context
+ .getBean(JGitEnvironmentRepository.class);
+
+ try {
+ repository.findOne("bar", "staging", "master");
+ }
+ catch (Throwable e) {
+ while (e.getCause() != null) {
+ e = e.getCause();
+ if (e instanceof CertificateException)
+ break;
+ }
+ throw e;
+ }
+ }
+
+ @Test
+ public void selfSignedCertWithSkipSslValidationIsAccepted() {
+ ConfigurableApplicationContext context = new SpringApplicationBuilder(
+ TestConfiguration.class)
+ .properties(configServerProperties(
+ "spring.cloud.config.server.git.skipSslValidation=true"))
+ .web(WebApplicationType.NONE).run();
+
+ JGitEnvironmentRepository repository = context
+ .getBean(JGitEnvironmentRepository.class);
+ repository.findOne("bar", "staging", "master");
+ }
+
+ private static String[] configServerProperties(String... extraProperties) {
+ List properties = new ArrayList<>(Arrays.asList(extraProperties));
+ properties.add("spring.cloud.config.server.git.uri=" + server.getSecureUri());
+ properties.add("spring.cloud.config.server.git.username=agitter");
+ properties.add("spring.cloud.config.server.git.password=letmein");
+ return properties.toArray(new String[0]);
+ }
+
+ @Configuration
+ @EnableConfigurationProperties(ConfigServerProperties.class)
+ @Import({ PropertyPlaceholderAutoConfiguration.class,
+ EnvironmentRepositoryConfiguration.class })
+ static class TestConfiguration {
+ }
+}
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java
index 61f65557..f8bd9b50 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java
@@ -38,7 +38,6 @@ import org.eclipse.jgit.api.StatusCommand;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
-import org.eclipse.jgit.api.errors.NoMessageException;
import org.eclipse.jgit.api.errors.NotMergedException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.ObjectId;
@@ -60,17 +59,17 @@ import org.junit.rules.ExpectedException;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.server.support.AwsCodeCommitCredentialProvider;
-import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory;
+import org.springframework.cloud.config.server.support.GitSkipSslValidationCredentialsProvider;
import org.springframework.cloud.config.server.support.PassphraseCredentialsProvider;
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
import org.springframework.core.env.StandardEnvironment;
+
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
-import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -82,7 +81,7 @@ import static org.mockito.Mockito.when;
/**
* @author Dave Syer
- *
+ * @author Gareth Clay
*/
public class JGitEnvironmentRepositoryTests {
@@ -332,6 +331,70 @@ public class JGitEnvironmentRepositoryTests {
assertThat("shouldPull was false", shouldPull, is(true));
}
+ @Test
+ public void shouldNotRefresh() throws Exception {
+ Git git = mock(Git.class);
+ StatusCommand statusCommand = mock(StatusCommand.class);
+ Status status = mock(Status.class);
+ Repository repository = mock(Repository.class);
+ StoredConfig storedConfig = mock(StoredConfig.class);
+
+ when(git.status()).thenReturn(statusCommand);
+ when(git.getRepository()).thenReturn(repository);
+ when(repository.getConfig()).thenReturn(storedConfig);
+ when(storedConfig.getString("remote", "origin", "url")).thenReturn("http://example/git");
+ when(statusCommand.call()).thenReturn(status);
+ when(status.isClean()).thenReturn(true);
+
+ JGitEnvironmentProperties properties = new JGitEnvironmentProperties();
+ properties.setRefreshRate(2);
+
+ JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment, properties);
+
+ repo.setLastRefresh(System.currentTimeMillis() - 5000);
+
+ boolean shouldPull = repo.shouldPull(git);
+
+ assertThat("shouldPull was false", shouldPull, is(true));
+
+ repo.setRefreshRate(30);
+
+ shouldPull = repo.shouldPull(git);
+
+ assertThat("shouldPull was true", shouldPull, is(false));
+ }
+
+ @Test
+ public void shouldUpdateLastRefresh() throws Exception {
+ Git git = mock(Git.class);
+ StatusCommand statusCommand = mock(StatusCommand.class);
+ Status status = mock(Status.class);
+ Repository repository = mock(Repository.class);
+ StoredConfig storedConfig = mock(StoredConfig.class);
+ FetchCommand fetchCommand = mock(FetchCommand.class);
+ FetchResult fetchResult = mock(FetchResult.class);
+
+ when(git.status()).thenReturn(statusCommand);
+ when(git.getRepository()).thenReturn(repository);
+ when(fetchCommand.call()).thenReturn(fetchResult);
+ when(git.fetch()).thenReturn(fetchCommand);
+ when(repository.getConfig()).thenReturn(storedConfig);
+ when(storedConfig.getString("remote", "origin", "url")).thenReturn("http://example/git");
+ when(statusCommand.call()).thenReturn(status);
+ when(status.isClean()).thenReturn(true);
+
+ JGitEnvironmentProperties properties = new JGitEnvironmentProperties();
+ properties.setRefreshRate(1000);
+ JGitEnvironmentRepository repo = new JGitEnvironmentRepository(this.environment, properties);
+
+ repo.setLastRefresh(0);
+ repo.fetch(git, "master");
+
+ long timeDiff = System.currentTimeMillis() - repo.getLastRefresh();
+
+ assertThat("time difference ("+timeDiff+") was longer than 1 second", timeDiff < 1000L, is(true));
+ }
+
@Test
public void testFetchException() throws Exception {
@@ -617,7 +680,6 @@ public class JGitEnvironmentRepositoryTests {
public void gitCredentialsProviderFactoryCreatesPassphraseProvider() throws Exception {
final String passphrase = "mypassphrase";
final String gitUri = "git+ssh://git@somegitserver/somegitrepo";
- GitCredentialsProviderFactory credentialsFactory = new GitCredentialsProviderFactory();
Git mockGit = mock(Git.class);
MockCloneCommand mockCloneCommand = new MockCloneCommand(mockGit);
@@ -626,7 +688,7 @@ public class JGitEnvironmentRepositoryTests {
envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand));
envRepository.setUri(gitUri);
envRepository.setBasedir(new File("./mybasedir"));
- envRepository.setGitCredentialsProvider(credentialsFactory.createFor(gitUri, null, null, passphrase));
+ envRepository.setPassphrase(passphrase);
envRepository.setCloneOnStart(true);
envRepository.afterPropertiesSet();
@@ -646,7 +708,6 @@ public class JGitEnvironmentRepositoryTests {
@Test
public void gitCredentialsProviderFactoryCreatesUsernamePasswordProvider() throws Exception {
- GitCredentialsProviderFactory credentialsFactory = new GitCredentialsProviderFactory();
Git mockGit = mock(Git.class);
MockCloneCommand mockCloneCommand = new MockCloneCommand(mockGit);
final String username = "someuser";
@@ -657,8 +718,8 @@ public class JGitEnvironmentRepositoryTests {
envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand));
envRepository.setUri("git+ssh://git@somegitserver/somegitrepo");
envRepository.setBasedir(new File("./mybasedir"));
- envRepository.setGitCredentialsProvider(
- credentialsFactory.createFor(envRepository.getUri(), username, password, null));
+ envRepository.setUsername(username);
+ envRepository.setPassword(password);
envRepository.setCloneOnStart(true);
envRepository.afterPropertiesSet();
@@ -678,7 +739,6 @@ public class JGitEnvironmentRepositoryTests {
@Test
public void gitCredentialsProviderFactoryCreatesAwsCodeCommitProvider() throws Exception {
- GitCredentialsProviderFactory credentialsFactory = new GitCredentialsProviderFactory();
Git mockGit = mock(Git.class);
MockCloneCommand mockCloneCommand = new MockCloneCommand(mockGit);
final String awsUri = "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/test";
@@ -687,12 +747,44 @@ public class JGitEnvironmentRepositoryTests {
new JGitEnvironmentProperties());
envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand));
envRepository.setUri(awsUri);
- envRepository.setGitCredentialsProvider(credentialsFactory.createFor(envRepository.getUri(), null, null, null));
envRepository.setCloneOnStart(true);
envRepository.afterPropertiesSet();
assertTrue(mockCloneCommand.getCredentialsProvider() instanceof AwsCodeCommitCredentialProvider);
+ }
+ @Test
+ public void gitCredentialsProviderFactoryCreatesSkipSslValidationProvider()
+ throws Exception {
+ Git mockGit = mock(Git.class);
+ MockCloneCommand mockCloneCommand = new MockCloneCommand(mockGit);
+ final String username = "someuser";
+ final String password = "mypassword";
+
+ JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(
+ this.environment, new JGitEnvironmentProperties());
+ envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand));
+ envRepository.setUri("https://somegitserver/somegitrepo");
+ envRepository.setBasedir(new File("./mybasedir"));
+ envRepository.setUsername(username);
+ envRepository.setPassword(password);
+ envRepository.setSkipSslValidation(true);
+ envRepository.setCloneOnStart(true);
+ envRepository.afterPropertiesSet();
+
+ CredentialsProvider provider = mockCloneCommand.getCredentialsProvider();
+
+ assertTrue(provider instanceof GitSkipSslValidationCredentialsProvider);
+
+ CredentialItem.Username usernameCredential = new CredentialItem.Username();
+ CredentialItem.Password passwordCredential = new CredentialItem.Password();
+ assertTrue(provider.supports(usernameCredential));
+ assertTrue(provider.supports(passwordCredential));
+
+ provider.get(new URIish(), usernameCredential);
+ assertEquals(usernameCredential.getValue(), username);
+ provider.get(new URIish(), passwordCredential);
+ assertEquals(String.valueOf(passwordCredential.getValue()), password);
}
@Test
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryIntegrationTests.java
index 30acff54..a81a3d82 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryIntegrationTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryIntegrationTests.java
@@ -105,6 +105,26 @@ public class MultipleJGitEnvironmentRepositoryIntegrationTests {
assertEquals(2, environment.getPropertySources().size());
}
+ @Test
+ public void mappingRepoWithRefreshRate() throws IOException {
+ String defaultRepoUri = ConfigServerTestUtils.prepareLocalRepo("config-repo");
+ String test1RepoUri = ConfigServerTestUtils.prepareLocalRepo("test1-config-repo");
+
+ Map repoMapping = new LinkedHashMap();
+ repoMapping.put("spring.cloud.config.server.git.repos[test1].pattern", "*test1*");
+ repoMapping.put("spring.cloud.config.server.git.repos[test1].uri", test1RepoUri);
+ repoMapping.put("spring.cloud.config.server.git.refresh-rate", "30");
+ this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE)
+ .properties("spring.cloud.config.server.git.uri:" + defaultRepoUri)
+ .properties(repoMapping).run();
+ EnvironmentRepository repository = this.context
+ .getBean(EnvironmentRepository.class);
+ repository.findOne("test1-svc", "staging", "master");
+ Environment environment = repository.findOne("test1-svc", "staging", "master");
+ assertEquals(2, environment.getPropertySources().size());
+ assertEquals(((MultipleJGitEnvironmentRepository) repository).getRepos().get("test1").getRefreshRate(), 30);
+ }
+
@Test
public void mappingRepoWithProfile() throws IOException {
String defaultRepoUri = ConfigServerTestUtils.prepareLocalRepo("config-repo");
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryTests.java
index ea9ccefc..e243340c 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/MultipleJGitEnvironmentRepositoryTests.java
@@ -36,6 +36,7 @@ import org.springframework.core.env.StandardEnvironment;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
@@ -46,6 +47,7 @@ import static org.mockito.Mockito.when;
* @author Andy Chan (iceycake)
* @author Dave Syer
* @author Spencer Gibb
+ * @author Gareth Clay
*
*/
public class MultipleJGitEnvironmentRepositoryTests {
@@ -204,6 +206,85 @@ public class MultipleJGitEnvironmentRepositoryTests {
assertEquals(repo2.getTransportConfigCallback(), mockCallback2);
}
+ @Test
+ public void setCorrectCredentials() throws Exception {
+ final String repo1Username = "repo1-username";
+ final String repo1Password = "repo1-password";
+ final String repo2Passphrase = "repo2-passphrase";
+ final String multiRepoUsername = "multi-repo-username";
+ final String multiRepoPassword = "multi-repo-password";
+ final String multiRepoPassphrase = "multi-repo-passphrase";
+ PatternMatchingJGitEnvironmentRepository repo1 = createRepository("test1",
+ "*test1*", "test1Uri");
+ repo1.setUsername(repo1Username);
+ repo1.setPassword(repo1Password);
+ PatternMatchingJGitEnvironmentRepository repo2 = createRepository("test2",
+ "*test2*", "test2Uri");
+ repo2.setPassphrase(repo2Passphrase);
+
+ Map repos = new HashMap<>();
+ repos.put("test1", repo1);
+ repos.put("test2", repo2);
+
+ this.repository.setRepos(repos);
+ this.repository.setUsername(multiRepoUsername);
+ this.repository.setPassword(multiRepoPassword);
+ this.repository.setPassphrase(multiRepoPassphrase);
+ this.repository.afterPropertiesSet();
+
+ assertEquals("Repo1 has its own username which should not be overwritten",
+ repo1.getUsername(), repo1Username);
+ assertEquals("Repo1 has its own password which should not be overwritten",
+ repo1.getPassword(), repo1Password);
+ assertEquals(
+ "Repo1 did not specify a passphrase so this should have been copied from the multi repo",
+ repo1.getPassphrase(), multiRepoPassphrase);
+ assertEquals(
+ "Repo2 did not specify a username so this should have been copied from the multi repo",
+ repo2.getUsername(), multiRepoUsername);
+ assertEquals(
+ "Repo2 did not specify a username so this should have been copied from the multi repo",
+ repo2.getPassword(), multiRepoPassword);
+ assertEquals(
+ "Repo2 has its own passphrase which should not have been overwritten",
+ repo2.getPassphrase(), repo2Passphrase);
+ }
+
+ @Test
+ public void setSkipSslValidation() throws Exception {
+ final boolean repo1SkipSslValidation = false;
+ final boolean repo2SkipSslValidation = true;
+ PatternMatchingJGitEnvironmentRepository repo1 = createRepository("test1",
+ "*test1*", "test1Uri");
+ repo1.setSkipSslValidation(repo1SkipSslValidation);
+ PatternMatchingJGitEnvironmentRepository repo2 = createRepository("test2",
+ "*test2*", "test2Uri");
+ repo2.setSkipSslValidation(repo2SkipSslValidation);
+
+ Map repos = new HashMap<>();
+ repos.put("test1", repo1);
+ repos.put("test2", repo2);
+
+ this.repository.setRepos(repos);
+ this.repository.setSkipSslValidation(false);
+ this.repository.afterPropertiesSet();
+ assertFalse(
+ "If skip SSL validation is false at multi-repo level, then per-repo settings take priority",
+ repo1.isSkipSslValidation());
+ assertTrue(
+ "If skip SSL validation is false at multi-repo level, then per-repo settings take priority",
+ repo2.isSkipSslValidation());
+
+ this.repository.setSkipSslValidation(true);
+ this.repository.afterPropertiesSet();
+ assertTrue(
+ "If explicitly set to skip SSL validation at the multi-repo level, then apply same setting to sub-repos",
+ repo1.isSkipSslValidation());
+ assertTrue(
+ "If explicitly set to skip SSL validation at the multi-repo level, then apply same setting to sub-repos",
+ repo2.isSkipSslValidation());
+ }
+
@Test
// test for gh-700
public void basedirCreatedIfNotExists() throws Exception {
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java
index c5887f84..703e1ec1 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/VaultEnvironmentRepositoryTests.java
@@ -1,14 +1,16 @@
package org.springframework.cloud.config.server.environment;
-import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+
import org.junit.Before;
import org.junit.Test;
-import org.mockito.Mockito;
+import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.config.environment.Environment;
+import org.springframework.cloud.config.server.environment.VaultEnvironmentRepository.VaultResponse;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
@@ -17,6 +19,10 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.client.RestTemplate;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
/**
* @author Spencer Gibb
@@ -27,133 +33,170 @@ public class VaultEnvironmentRepositoryTests {
@Before
public void init() {}
- @Test
- public void testFindOneNoDefaultKey() throws IOException {
- MockHttpServletRequest configRequest = new MockHttpServletRequest();
- configRequest.addHeader("X-CONFIG-TOKEN", "mytoken");
- RestTemplate rest = Mockito.mock(RestTemplate.class);
-
- ResponseEntity myAppResp = Mockito.mock(ResponseEntity.class);
- Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
- VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
- Mockito.when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
- Mockito.when(myAppResp.getBody()).thenReturn(myAppVaultResp);
- Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
- Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
- Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp);
-
- ResponseEntity appResp = Mockito.mock(ResponseEntity.class);
- Mockito.when(appResp.getStatusCode()).thenReturn(HttpStatus.OK);
- VaultEnvironmentRepository.VaultResponse appVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
- Mockito.when(appVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
- Mockito.when(appResp.getBody()).thenReturn(appVaultResp);
- Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
- Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
- Mockito.eq("secret"), Mockito.eq("application"))).thenReturn(appResp);
-
- VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
-
- Environment e = repo.findOne("myapp", null, null);
- assertEquals("Name should be the same as the application argument", "myapp", e.getName());
- assertEquals("Properties for specified application and default application with key 'application' should be returned", 2, e.getPropertySources().size());
- Map firstResult = new HashMap();
- firstResult.put("foo", "bar");
- assertEquals("Properties for specified application should be returned in priority position", firstResult, e.getPropertySources().get(0).getSource());
-
- Map secondResult = new HashMap();
- secondResult.put("def-foo", "def-bar");
- assertEquals("Properties for default application with key 'application' should be returned in second position", secondResult, e.getPropertySources().get(1).getSource());
+ @SuppressWarnings("unchecked")
+ private ObjectProvider mockProvide(HttpServletRequest request) {
+ ObjectProvider objectProvider = mock(ObjectProvider.class);
+ when(objectProvider.getIfAvailable()).thenReturn(request);
+ return objectProvider;
}
@Test
- public void testFindOneDefaultKeySetAndDifferentToApplication() throws IOException {
+ @SuppressWarnings("unchecked")
+ public void testFindOneNoDefaultKey() {
MockHttpServletRequest configRequest = new MockHttpServletRequest();
configRequest.addHeader("X-CONFIG-TOKEN", "mytoken");
- RestTemplate rest = Mockito.mock(RestTemplate.class);
- ResponseEntity myAppResp = Mockito.mock(ResponseEntity.class);
- Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
- VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
- Mockito.when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
- Mockito.when(myAppResp.getBody()).thenReturn(myAppVaultResp);
- Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
- Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
- Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp);
+ RestTemplate rest = mock(RestTemplate.class);
- ResponseEntity myDefaultKeyResp = Mockito.mock(ResponseEntity.class);
- Mockito.when(myDefaultKeyResp.getStatusCode()).thenReturn(HttpStatus.OK);
- VaultEnvironmentRepository.VaultResponse myDefaultKeyVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
- Mockito.when(myDefaultKeyVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
- Mockito.when(myDefaultKeyResp.getBody()).thenReturn(myDefaultKeyVaultResp);
- Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
- Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
- Mockito.eq("secret"), Mockito.eq("mydefaultkey"))).thenReturn(myDefaultKeyResp);
+ ResponseEntity myAppResp = mock(ResponseEntity.class);
+ when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
+ VaultResponse myAppVaultResp = mock(VaultResponse.class);
+ when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
+ when(myAppResp.getBody()).thenReturn(myAppVaultResp);
+ when(rest.exchange(eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
+ eq(HttpMethod.GET), any(HttpEntity.class), eq(VaultResponse.class),
+ eq("secret"), eq("myapp"))).thenReturn(myAppResp);
- VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
+ ResponseEntity appResp = mock(ResponseEntity.class);
+ when(appResp.getStatusCode()).thenReturn(HttpStatus.OK);
+ VaultResponse appVaultResp = mock(VaultResponse.class);
+ when(appVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
+ when(appResp.getBody()).thenReturn(appVaultResp);
+ when(rest.exchange(eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
+ eq(HttpMethod.GET), any(HttpEntity.class), eq(VaultResponse.class),
+ eq("secret"), eq("application"))).thenReturn(appResp);
+
+ VaultEnvironmentRepository repo = new VaultEnvironmentRepository(mockProvide(configRequest),
+ new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
+
+ Environment e = repo.findOne("myapp", null, null);
+ assertEquals("Name should be the same as the application argument", "myapp", e.getName());
+ assertEquals("Properties for specified application and default application with key 'application' should be returned",
+ 2, e.getPropertySources().size());
+ Map firstResult = new HashMap();
+ firstResult.put("foo", "bar");
+ assertEquals("Properties for specified application should be returned in priority position",
+ firstResult, e.getPropertySources().get(0).getSource());
+
+ Map secondResult = new HashMap();
+ secondResult.put("def-foo", "def-bar");
+ assertEquals("Properties for default application with key 'application' should be returned in second position",
+ secondResult, e.getPropertySources().get(1).getSource());
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testFindOneDefaultKeySetAndDifferentToApplication() {
+ MockHttpServletRequest configRequest = new MockHttpServletRequest();
+ configRequest.addHeader("X-CONFIG-TOKEN", "mytoken");
+ RestTemplate rest = mock(RestTemplate.class);
+
+ ResponseEntity myAppResp = mock(ResponseEntity.class);
+ when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
+ VaultResponse myAppVaultResp = mock(VaultResponse.class);
+ when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
+ when(myAppResp.getBody()).thenReturn(myAppVaultResp);
+ when(rest.exchange(eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
+ eq(HttpMethod.GET), any(HttpEntity.class), eq(VaultResponse.class),
+ eq("secret"), eq("myapp"))).thenReturn(myAppResp);
+
+ ResponseEntity myDefaultKeyResp = mock(ResponseEntity.class);
+ when(myDefaultKeyResp.getStatusCode()).thenReturn(HttpStatus.OK);
+ VaultResponse myDefaultKeyVaultResp = mock(VaultResponse.class);
+ when(myDefaultKeyVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
+ when(myDefaultKeyResp.getBody()).thenReturn(myDefaultKeyVaultResp);
+ when(rest.exchange(eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
+ eq(HttpMethod.GET), any(HttpEntity.class), eq(VaultResponse.class),
+ eq("secret"), eq("mydefaultkey"))).thenReturn(myDefaultKeyResp);
+
+ VaultEnvironmentRepository repo = new VaultEnvironmentRepository(mockProvide(configRequest),
+ new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
repo.setDefaultKey("mydefaultkey");
Environment e = repo.findOne("myapp", null, null);
assertEquals("Name should be the same as the application argument", "myapp", e.getName());
- assertEquals("Properties for specified application and default application with key 'mydefaultkey' should be returned", 2, e.getPropertySources().size());
+ assertEquals("Properties for specified application and default application with key 'mydefaultkey' should be returned",
+ 2, e.getPropertySources().size());
Map firstResult = new HashMap();
firstResult.put("foo", "bar");
- assertEquals("Properties for specified application should be returned in priority position", firstResult, e.getPropertySources().get(0).getSource());
+ assertEquals("Properties for specified application should be returned in priority position",
+ firstResult, e.getPropertySources().get(0).getSource());
Map secondResult = new HashMap();
secondResult.put("def-foo", "def-bar");
- assertEquals("Properties for default application with key 'mydefaultkey' should be returned in second position", secondResult, e.getPropertySources().get(1).getSource());
+ assertEquals("Properties for default application with key 'mydefaultkey' should be returned in second position",
+ secondResult, e.getPropertySources().get(1).getSource());
}
@Test
- public void testFindOneDefaultKeySetAndEqualToApplication() throws IOException {
+ @SuppressWarnings("unchecked")
+ public void testFindOneDefaultKeySetAndEqualToApplication() {
MockHttpServletRequest configRequest = new MockHttpServletRequest();
configRequest.addHeader("X-CONFIG-TOKEN", "mytoken");
- RestTemplate rest = Mockito.mock(RestTemplate.class);
+ RestTemplate rest = mock(RestTemplate.class);
- ResponseEntity myAppResp = Mockito.mock(ResponseEntity.class);
- Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
- VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
- Mockito.when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
- Mockito.when(myAppResp.getBody()).thenReturn(myAppVaultResp);
- Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
- Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
- Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp);
+ ResponseEntity myAppResp = mock(ResponseEntity.class);
+ when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
+ VaultResponse myAppVaultResp = mock(VaultResponse.class);
+ when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
+ when(myAppResp.getBody()).thenReturn(myAppVaultResp);
+ when(rest.exchange(eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
+ eq(HttpMethod.GET), any(HttpEntity.class), eq(VaultResponse.class),
+ eq("secret"), eq("myapp"))).thenReturn(myAppResp);
- ResponseEntity appResp = Mockito.mock(ResponseEntity.class);
- Mockito.when(appResp.getStatusCode()).thenReturn(HttpStatus.OK);
- VaultEnvironmentRepository.VaultResponse appVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
- Mockito.when(appVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
- Mockito.when(appResp.getBody()).thenReturn(appVaultResp);
- Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
- Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
- Mockito.eq("secret"), Mockito.eq("application"))).thenReturn(appResp);
+ ResponseEntity appResp = mock(ResponseEntity.class);
+ when(appResp.getStatusCode()).thenReturn(HttpStatus.OK);
+ VaultResponse appVaultResp = mock(VaultResponse.class);
+ when(appVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
+ when(appResp.getBody()).thenReturn(appVaultResp);
+ when(rest.exchange(eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
+ eq(HttpMethod.GET), any(HttpEntity.class), eq(VaultResponse.class),
+ eq("secret"), eq("application"))).thenReturn(appResp);
- VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
+ VaultEnvironmentRepository repo = new VaultEnvironmentRepository(mockProvide(configRequest),
+ new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
repo.setDefaultKey("myapp");
Environment e = repo.findOne("myapp", null, null);
- assertEquals("Name should be the same as the application argument", "myapp", e.getName());
- assertEquals("Only properties for specified application should be returned", 1, e.getPropertySources().size());
+ assertEquals("Name should be the same as the application argument",
+ "myapp", e.getName());
+ assertEquals("Only properties for specified application should be returned",
+ 1, e.getPropertySources().size());
Map result = new HashMap();
result.put("foo", "bar");
- assertEquals("Properties should be returned for specified application", result, e.getPropertySources().get(0).getSource());
+ assertEquals("Properties should be returned for specified application",
+ result, e.getPropertySources().get(0).getSource());
}
@Test(expected = IllegalArgumentException.class)
- public void missingConfigToken() throws IOException {
+ @SuppressWarnings("unchecked")
+ public void missingConfigToken() {
MockHttpServletRequest configRequest = new MockHttpServletRequest();
- RestTemplate rest = Mockito.mock(RestTemplate.class);
- ResponseEntity myAppResp = Mockito.mock(ResponseEntity.class);
- Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
- VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
- Mockito.when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
- Mockito.when(myAppResp.getBody()).thenReturn(myAppVaultResp);
- Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
- Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
- Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp);
- VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
+ RestTemplate rest = mock(RestTemplate.class);
+ ResponseEntity myAppResp = mock(ResponseEntity.class);
+ when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
+ VaultResponse myAppVaultResp = mock(VaultResponse.class);
+ when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
+ when(myAppResp.getBody()).thenReturn(myAppVaultResp);
+ when(rest.exchange(eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
+ eq(HttpMethod.GET), any(HttpEntity.class), eq(VaultResponse.class),
+ eq("secret"), eq("myapp"))).thenReturn(myAppResp);
+ VaultEnvironmentRepository repo = new VaultEnvironmentRepository(mockProvide(configRequest),
+ new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
+ repo.findOne("myapp", null, null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ @SuppressWarnings("unchecked")
+ public void missingHttpRequest() {
+ ObjectProvider objectProvider = mock(ObjectProvider.class);
+ when(objectProvider.getIfAvailable()).thenReturn(null);
+
+ RestTemplate rest = mock(RestTemplate.class);
+ VaultEnvironmentRepository repo = new VaultEnvironmentRepository(objectProvider,
+ new EnvironmentWatch.Default(), rest, new VaultEnvironmentProperties());
repo.findOne("myapp", null, null);
}
}
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactoryTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactoryTest.java
index a8eeeb43..0a00e1d5 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactoryTest.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/PropertyBasedSshSessionFactoryTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2017 the original author or authors.
+ * Copyright 2015 - 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,10 @@ import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
+import com.jcraft.jsch.HostKey;
+import com.jcraft.jsch.HostKeyRepository;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.junit.Assert;
import org.junit.Test;
@@ -29,19 +33,11 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+
+import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
-import com.jcraft.jsch.HostKey;
-import com.jcraft.jsch.HostKeyRepository;
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.Session;
-
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -70,10 +66,9 @@ public class PropertyBasedSshSessionFactoryTest {
@Test
public void strictHostKeyCheckingIsOptional() {
- SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder()
- .uri("ssh://gitlab.example.local:3322/somerepo.git")
- .privateKey(PRIVATE_KEY)
- .build();
+ JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties();
+ sshKey.setUri("ssh://gitlab.example.local:3322/somerepo.git");
+ sshKey.setPrivateKey(PRIVATE_KEY);
setupSessionFactory(sshKey);
factory.configure(hc, session);
@@ -84,11 +79,10 @@ public class PropertyBasedSshSessionFactoryTest {
@Test
public void strictHostKeyCheckingIsUsed() {
- SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder()
- .uri("ssh://gitlab.example.local:3322/somerepo.git")
- .hostKey(HOST_KEY)
- .privateKey(PRIVATE_KEY)
- .build();
+ JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties();
+ sshKey.setUri("ssh://gitlab.example.local:3322/somerepo.git");
+ sshKey.setHostKey(HOST_KEY);
+ sshKey.setPrivateKey(PRIVATE_KEY);
setupSessionFactory(sshKey);
factory.configure(hc, session);
@@ -99,12 +93,11 @@ public class PropertyBasedSshSessionFactoryTest {
@Test
public void hostKeyAlgorithmIsSpecified() {
- SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder()
- .uri("ssh://gitlab.example.local:3322/somerepo.git")
- .hostKeyAlgorithm(HOST_KEY_ALGORITHM)
- .hostKey(HOST_KEY)
- .privateKey(PRIVATE_KEY)
- .build();
+ JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties();
+ sshKey.setUri("ssh://gitlab.example.local:3322/somerepo.git");
+ sshKey.setHostKeyAlgorithm(HOST_KEY_ALGORITHM);
+ sshKey.setHostKey(HOST_KEY);
+ sshKey.setPrivateKey(PRIVATE_KEY);
setupSessionFactory(sshKey);
factory.configure(hc, session);
@@ -115,10 +108,9 @@ public class PropertyBasedSshSessionFactoryTest {
@Test
public void privateKeyIsUsed() throws Exception {
- SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder()
- .uri("git@gitlab.example.local:someorg/somerepo.git")
- .privateKey(PRIVATE_KEY)
- .build();
+ JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties();
+ sshKey.setUri("git@gitlab.example.local:someorg/somerepo.git");
+ sshKey.setPrivateKey(PRIVATE_KEY);
setupSessionFactory(sshKey);
factory.createSession(hc, null, SshUriPropertyProcessor.getHostname(sshKey.getUri()), 22, null);
@@ -127,11 +119,10 @@ public class PropertyBasedSshSessionFactoryTest {
@Test
public void hostKeyIsUsed() throws Exception {
- SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder()
- .uri("git@gitlab.example.local:someorg/somerepo.git")
- .hostKey(HOST_KEY)
- .privateKey(PRIVATE_KEY)
- .build();
+ JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties();
+ sshKey.setUri("git@gitlab.example.local:someorg/somerepo.git");
+ sshKey.setHostKey(HOST_KEY);
+ sshKey.setPrivateKey(PRIVATE_KEY);
setupSessionFactory(sshKey);
factory.createSession(hc, null, SshUriPropertyProcessor.getHostname(sshKey.getUri()), 22, null);
@@ -144,11 +135,10 @@ public class PropertyBasedSshSessionFactoryTest {
@Test
public void preferredAuthenticationsIsSpecified() {
- SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder()
- .uri("ssh://gitlab.example.local:3322/somerepo.git")
- .privateKey(PRIVATE_KEY)
- .preferredAuthentications("password,keyboard-interactive")
- .build();
+ JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties();
+ sshKey.setUri("ssh://gitlab.example.local:3322/somerepo.git");
+ sshKey.setPrivateKey(PRIVATE_KEY);
+ sshKey.setPreferredAuthentications("password,keyboard-interactive");
setupSessionFactory(sshKey);
factory.configure(hc, session);
@@ -159,11 +149,10 @@ public class PropertyBasedSshSessionFactoryTest {
@Test
public void customKnownHostsFileIsUsed() throws Exception {
- SshUri sshKey = new SshUriProperties.SshUriPropertiesBuilder()
- .uri("git@gitlab.example.local:someorg/somerepo.git")
- .privateKey(PRIVATE_KEY)
- .knownHostsFile("/ssh/known_hosts")
- .build();
+ JGitEnvironmentProperties sshKey = new JGitEnvironmentProperties();
+ sshKey.setUri("git@gitlab.example.local:someorg/somerepo.git");
+ sshKey.setPrivateKey(PRIVATE_KEY);
+ sshKey.setKnownHostsFile("/ssh/known_hosts");
setupSessionFactory(sshKey);
factory.createSession(hc, null, SshUriPropertyProcessor.getHostname(sshKey.getUri()), 22, null);
@@ -173,8 +162,8 @@ public class PropertyBasedSshSessionFactoryTest {
Assert.assertEquals("/ssh/known_hosts", captor.getValue());
}
- private void setupSessionFactory(SshUri sshKey) {
- Map sshKeysByHostname = new HashMap<>();
+ private void setupSessionFactory(JGitEnvironmentProperties sshKey) {
+ Map sshKeysByHostname = new HashMap<>();
sshKeysByHostname.put(SshUriPropertyProcessor.getHostname(sshKey.getUri()), sshKey);
factory = new PropertyBasedSshSessionFactory(sshKeysByHostname, jSch) ;
when(hc.getHostName()).thenReturn(SshUriPropertyProcessor.getHostname(sshKey.getUri()));
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshPropertyValidatorTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshPropertyValidatorTest.java
index 942f96ec..921067aa 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshPropertyValidatorTest.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshPropertyValidatorTest.java
@@ -16,14 +16,16 @@
package org.springframework.cloud.config.server.ssh;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
+import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
-import java.util.Set;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
@@ -76,119 +78,102 @@ public class SshPropertyValidatorTest {
@Test
public void supportedParametersSuccesful() throws Exception {
- SshUriProperties validSettings = SshUri.builder()
- .uri(SSH_URI)
- .ignoreLocalSshSettings(true)
- .privateKey(VALID_PRIVATE_KEY)
- .hostKey(VALID_HOST_KEY)
- .hostKeyAlgorithm("ssh-rsa")
- .build();
+ MultipleJGitEnvironmentProperties validSettings = new MultipleJGitEnvironmentProperties();
+ validSettings.setUri(SSH_URI);
+ validSettings.setIgnoreLocalSshSettings(true);
+ validSettings.setPrivateKey(VALID_PRIVATE_KEY);
+ validSettings.setHostKey(VALID_HOST_KEY);
+ validSettings.setHostKeyAlgorithm("ssh-rsa");
- Set> constraintViolations = validator.validate(validSettings);
+ Set> constraintViolations = validator.validate(validSettings);
assertThat(constraintViolations, hasSize(0));
-
}
@Test
public void invalidPrivateKeyFails() throws Exception {
+ MultipleJGitEnvironmentProperties invalidKey = new MultipleJGitEnvironmentProperties();
+ invalidKey.setUri(SSH_URI);
+ invalidKey.setIgnoreLocalSshSettings(true);
+ invalidKey.setPrivateKey("invalid_key");
- SshUriProperties invalidKey = SshUri.builder()
- .uri(SSH_URI)
- .ignoreLocalSshSettings(true)
- .privateKey("invalid_key")
- .build();
-
- Set> constraintViolations = validator.validate(invalidKey);
+ Set> constraintViolations = validator.validate(invalidKey);
assertThat(constraintViolations, hasSize(1));
-
}
@Test
public void missingPrivateKeyFails() throws Exception {
+ MultipleJGitEnvironmentProperties missingKey = new MultipleJGitEnvironmentProperties();
+ missingKey.setUri(SSH_URI);
+ missingKey.setIgnoreLocalSshSettings(true);
- SshUriProperties missingKey = SshUri.builder()
- .uri(SSH_URI)
- .ignoreLocalSshSettings(true)
- .build();
-
- Set> constraintViolations = validator.validate(missingKey);
+ Set> constraintViolations = validator.validate(missingKey);
assertThat(constraintViolations, hasSize(1));
}
@Test
public void hostKeyWithMissingAlgoFails() throws Exception {
+ MultipleJGitEnvironmentProperties missingAlgo = new MultipleJGitEnvironmentProperties();
+ missingAlgo.setUri(SSH_URI);
+ missingAlgo.setIgnoreLocalSshSettings(true);
+ missingAlgo.setPrivateKey(VALID_PRIVATE_KEY);
+ missingAlgo.setHostKey("some_host");
- SshUriProperties missingAlgo = SshUri.builder()
- .uri(SSH_URI)
- .ignoreLocalSshSettings(true)
- .privateKey(VALID_PRIVATE_KEY)
- .hostKey("some_host")
- .build();
-
- Set> constraintViolations = validator.validate(missingAlgo);
+ Set> constraintViolations = validator.validate(missingAlgo);
assertThat(constraintViolations, hasSize(1));
}
@Test
public void algoWithMissingHostKeyFails() throws Exception {
+ MultipleJGitEnvironmentProperties missingHostKey = new MultipleJGitEnvironmentProperties();
+ missingHostKey.setUri(SSH_URI);
+ missingHostKey.setIgnoreLocalSshSettings(true);
+ missingHostKey.setPrivateKey(VALID_PRIVATE_KEY);
+ missingHostKey.setHostKeyAlgorithm("ssh-rsa");
- SshUriProperties missingHostKey = SshUri.builder()
- .uri(SSH_URI)
- .ignoreLocalSshSettings(true)
- .privateKey(VALID_PRIVATE_KEY)
- .hostKeyAlgorithm("ssh-rsa")
- .build();
-
- Set> constraintViolations = validator.validate(missingHostKey);
+ Set> constraintViolations = validator.validate(missingHostKey);
assertThat(constraintViolations, hasSize(1));
}
@Test
public void unsupportedAlgoFails() throws Exception {
+ MultipleJGitEnvironmentProperties unsupportedAlgo = new MultipleJGitEnvironmentProperties();
+ unsupportedAlgo.setUri(SSH_URI);
+ unsupportedAlgo.setIgnoreLocalSshSettings(true);
+ unsupportedAlgo.setPrivateKey(VALID_PRIVATE_KEY);
+ unsupportedAlgo.setHostKey("some_host_key");
+ unsupportedAlgo.setHostKeyAlgorithm("unsupported");
- SshUriProperties unsupportedAlgo = SshUri.builder()
- .uri(SSH_URI)
- .ignoreLocalSshSettings(true)
- .privateKey(VALID_PRIVATE_KEY)
- .hostKey("some_host_key")
- .hostKeyAlgorithm("unsupported")
- .build();
-
- Set> constraintViolations = validator.validate(unsupportedAlgo);
+ Set> constraintViolations = validator.validate(unsupportedAlgo);
assertThat(constraintViolations, hasSize(1));
}
@Test
public void validatorNotRunIfIgnoreLocalSettingsFalse() throws Exception {
+ MultipleJGitEnvironmentProperties useLocal = new MultipleJGitEnvironmentProperties();
+ useLocal.setUri(SSH_URI);
+ useLocal.setIgnoreLocalSshSettings(false);
+ useLocal.setPrivateKey("invalid_key");
- SshUriProperties useLocal = (SshUri.builder()
- .uri(SSH_URI)
- .ignoreLocalSshSettings(false)
- .privateKey("invalid_key")
- .build());
-
- Set> constraintViolations = validator.validate(useLocal);
+ Set> constraintViolations = validator.validate(useLocal);
assertThat(constraintViolations, hasSize(0));
}
@Test
public void validatorNotRunIfHttpsUri() throws Exception {
+ MultipleJGitEnvironmentProperties httpsUri = new MultipleJGitEnvironmentProperties();
+ httpsUri.setUri("https://somerepo.com/team/project.git");
+ httpsUri.setIgnoreLocalSshSettings(true);
+ httpsUri.setPrivateKey("invalid_key");
- SshUriProperties httpsUri = (SshUri.builder()
- .uri("https://somerepo.com/team/project.git")
- .ignoreLocalSshSettings(true)
- .privateKey("invalid_key")
- .build());
-
- Set> constraintViolations = validator.validate(httpsUri);
+ Set> constraintViolations = validator.validate(httpsUri);
assertThat(constraintViolations, hasSize(0));
}
@Test
public void preferredAuthenticationsIsValidated() throws Exception {
- SshUriProperties sshUriProperties = new SshUriProperties();
+ MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties();
assertThat(validator.validate(sshUriProperties), hasSize(0));
sshUriProperties.setPreferredAuthentications("keyboard-interactive, public-key ,kerberos");
@@ -200,7 +185,7 @@ public class SshPropertyValidatorTest {
@Test
public void knowHostsFileIsValidated() throws Exception {
- SshUriProperties sshUriProperties = new SshUriProperties();
+ MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties();
assertThat(validator.validate(sshUriProperties), hasSize(0));
sshUriProperties.setKnownHostsFile("non-existing.file");
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessorTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessorTest.java
index 8f7fd49a..c1cb8e22 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessorTest.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 the original author or authors.
+ * Copyright 2015 - 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,13 +18,19 @@ package org.springframework.cloud.config.server.ssh;
import java.util.Map;
+
import org.eclipse.jgit.transport.SshSessionFactory;
import org.junit.After;
import org.junit.Test;
-import org.springframework.cloud.config.server.ssh.SshUriProperties.SshUriNestedRepoProperties;
+import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties;
+import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
/**
@@ -54,43 +60,45 @@ public class SshUriPropertyProcessorTest {
@Test
public void testSingleSshUriProperties() {
SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(mainRepoPropertiesFixture());
- Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
+ Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
assertThat(sshKeysByHostname.values(), hasSize(1));
- SshUri sshKey = sshKeysByHostname.get(HOST1);
+ JGitEnvironmentProperties sshKey = sshKeysByHostname.get(HOST1);
assertMainRepo(sshKey);
}
@Test
public void testMultipleSshUriPropertiess() {
- SshUriProperties sshUriProperties = mainRepoPropertiesFixture();
- addRepoProperties(sshUriProperties, SshUri.builder()
- .uri(URI2)
- .privateKey(PRIVATE_KEY2)
- .buildAsNestedRepo(), "repo2");
- addRepoProperties(sshUriProperties, SshUri.builder()
- .uri(URI3)
- .privateKey(PRIVATE_KEY3)
- .buildAsNestedRepo(), "repo3");
+ MultipleJGitEnvironmentProperties sshUriProperties = mainRepoPropertiesFixture();
+ MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties nestedSshUriProperties1 =
+ new MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties();
+ nestedSshUriProperties1.setUri(URI2);
+ nestedSshUriProperties1.setPrivateKey(PRIVATE_KEY2);
+ MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties nestedSshUriProperties2 =
+ new MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties();
+ nestedSshUriProperties2.setUri(URI3);
+ nestedSshUriProperties2.setPrivateKey(PRIVATE_KEY3);
+ addRepoProperties(sshUriProperties, nestedSshUriProperties1, "repo2");
+ addRepoProperties(sshUriProperties, nestedSshUriProperties2, "repo3");
SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties);
- Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
+ Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
assertThat(sshKeysByHostname.values(), hasSize(3));
- SshUri sshKey1 = sshKeysByHostname.get(HOST1);
+ JGitEnvironmentProperties sshKey1 = sshKeysByHostname.get(HOST1);
assertMainRepo(sshKey1);
- SshUri sshKey2 = sshKeysByHostname.get(HOST2);
+ JGitEnvironmentProperties sshKey2 = sshKeysByHostname.get(HOST2);
assertThat(SshUriPropertyProcessor.getHostname(sshKey2.getUri()), is(equalTo(HOST2)));
assertThat(sshKey2.getHostKeyAlgorithm(), is(nullValue()));
assertThat(sshKey2.getHostKey(), is(nullValue()));
assertThat(sshKey2.getPrivateKey(), is(equalTo(PRIVATE_KEY2)));
- SshUri sshKey3 = sshKeysByHostname.get(HOST3);
+ JGitEnvironmentProperties sshKey3 = sshKeysByHostname.get(HOST3);
assertThat(SshUriPropertyProcessor.getHostname(sshKey3.getUri()), is(equalTo(HOST3)));
assertThat(sshKey3.getHostKeyAlgorithm(), is(nullValue()));
@@ -100,58 +108,62 @@ public class SshUriPropertyProcessorTest {
@Test
public void testSameHostnameDifferentKeysFirstOneWins() {
- SshUriProperties sshUriProperties = mainRepoPropertiesFixture();
- addRepoProperties(sshUriProperties, SshUri.builder().uri(URI1)
- .privateKey(PRIVATE_KEY1)
- .hostKey(HOST_KEY1)
- .hostKeyAlgorithm(ALGO1)
- .buildAsNestedRepo(), "repo2");
+ MultipleJGitEnvironmentProperties sshUriProperties = mainRepoPropertiesFixture();
+ MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties nestedSshUriProperties = new MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties();
+ nestedSshUriProperties.setUri(URI1);
+ nestedSshUriProperties.setPrivateKey(PRIVATE_KEY1);
+ nestedSshUriProperties.setHostKey(HOST_KEY1);
+ nestedSshUriProperties.setHostKeyAlgorithm(ALGO1);
+ addRepoProperties(sshUriProperties, nestedSshUriProperties, "repo2");
SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties);
- Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
+ Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
assertThat(sshKeysByHostname.values(), hasSize(1));
- SshUri sshKey = sshKeysByHostname.get(HOST1);
+ JGitEnvironmentProperties sshKey = sshKeysByHostname.get(HOST1);
assertMainRepo(sshKey);
}
@Test
public void testNoSshUriProperties() {
- SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(new SshUriProperties());
- Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
+ SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(new MultipleJGitEnvironmentProperties());
+ Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
assertThat(sshKeysByHostname.values(), hasSize(0));
}
@Test
public void testInvalidUriDoesNotAddEntry() {
- SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(SshUri.builder().uri("invalid_uri").build());
- Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
+ MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties();
+ sshUriProperties.setUri("invalid_uri");
+ SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties);
+ Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
assertThat(sshKeysByHostname.values(), hasSize(0));
}
@Test
public void testHttpsUriDoesNotAddEntry() {
- SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(SshUri.builder().uri("https://user@github.com/proj/repo.git").build());
- Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
+ MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties();
+ sshUriProperties.setUri("https://user@github.com/proj/repo.git");
+ SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties);
+ Map sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
assertThat(sshKeysByHostname.values(), hasSize(0));
}
- private SshUriProperties mainRepoPropertiesFixture() {
-
- return SshUri.builder()
- .uri(URI1)
- .hostKeyAlgorithm(ALGO1)
- .hostKey(HOST_KEY1)
- .privateKey(PRIVATE_KEY1)
- .build();
+ private MultipleJGitEnvironmentProperties mainRepoPropertiesFixture() {
+ MultipleJGitEnvironmentProperties result = new MultipleJGitEnvironmentProperties();
+ result.setUri(URI1);
+ result.setHostKeyAlgorithm(ALGO1);
+ result.setHostKey(HOST_KEY1);
+ result.setPrivateKey(PRIVATE_KEY1);
+ return result;
}
- private void addRepoProperties(SshUriProperties mainRepoProperties, SshUriNestedRepoProperties repoProperties, String repoName) {
- mainRepoProperties.addRepo(repoName, repoProperties);
+ private void addRepoProperties(MultipleJGitEnvironmentProperties mainRepoProperties, MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties repoProperties, String repoName) {
+ mainRepoProperties.getRepos().put(repoName, repoProperties);
}
- private void assertMainRepo(SshUri sshKey) {
+ private void assertMainRepo(JGitEnvironmentProperties sshKey) {
assertThat(sshKey, is(notNullValue()));
assertThat(SshUriPropertyProcessor.getHostname(sshKey.getUri()), is(equalTo(HOST1)));
assertThat(sshKey.getHostKeyAlgorithm(), is(equalTo(ALGO1)));
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/support/GitSkipSslValidationCredentialsProviderTest.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/support/GitSkipSslValidationCredentialsProviderTest.java
new file mode 100644
index 00000000..148a51e9
--- /dev/null
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/support/GitSkipSslValidationCredentialsProviderTest.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.config.server.support;
+
+import java.net.URISyntaxException;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.errors.UnsupportedCredentialItem;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.transport.CredentialItem;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.URIish;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Gareth Clay
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class GitSkipSslValidationCredentialsProviderTest {
+
+ @Mock
+ private CredentialsProvider mockDelegateCredentialsProvider;
+ private GitSkipSslValidationCredentialsProvider skipSslValidationCredentialsProvider;
+
+ @Before
+ public void setup() {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ null);
+ }
+
+ @Test
+ public void testCanHandle() {
+ assertTrue("GitSkipSslValidationCredentialsProvider only handles HTTPS uris",
+ GitSkipSslValidationCredentialsProvider
+ .canHandle("https://github.com/org/repo"));
+ assertFalse("GitSkipSslValidationCredentialsProvider only handles HTTPS uris",
+ GitSkipSslValidationCredentialsProvider
+ .canHandle("git@github.com:org/repo"));
+ }
+
+ @Test
+ public void testIsInteractive() {
+ assertFalse(
+ "GitSkipSslValidationCredentialsProvider with no delegate requires no user interaction",
+ skipSslValidationCredentialsProvider.isInteractive());
+ }
+
+ @Test
+ public void testIsInteractiveWithDelegate() {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ mockDelegateCredentialsProvider);
+
+ when(mockDelegateCredentialsProvider.isInteractive()).thenReturn(true);
+
+ assertTrue(
+ "With a delegate provider, isInteractive value depends on the delegate",
+ skipSslValidationCredentialsProvider.isInteractive());
+ }
+
+ @Test
+ public void testSupportsSslFailureInformationalMessage() {
+ CredentialItem informationalMessage = new CredentialItem.InformationalMessage(
+ "text " + JGitText.get().sslFailureTrustExplanation + " more text");
+ assertTrue(
+ "GitSkipSslValidationCredentialsProvider should always support SSL failure InformationalMessage",
+ skipSslValidationCredentialsProvider.supports(informationalMessage));
+
+ informationalMessage = new CredentialItem.InformationalMessage("unrelated");
+ assertFalse(
+ "GitSkipSslValidationCredentialsProvider should not support unrelated InformationalMessage items",
+ skipSslValidationCredentialsProvider.supports(informationalMessage));
+ }
+
+ @Test
+ public void testSupportsSslFailureInformationalMessageWithDelegate() {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ mockDelegateCredentialsProvider);
+
+ testSupportsSslFailureInformationalMessage();
+ }
+
+ @Test
+ public void testSupportsSslValidationYesNoTypes() {
+ CredentialItem yesNoType = new CredentialItem.YesNoType(
+ JGitText.get().sslTrustNow);
+ assertTrue(
+ "GitSkipSslValidationCredentialsProvider should always support the trust now YesNoType item",
+ skipSslValidationCredentialsProvider.supports(yesNoType));
+
+ yesNoType = new CredentialItem.YesNoType(
+ MessageFormat.format(JGitText.get().sslTrustForRepo, "/a/path.git"));
+ assertTrue(
+ "GitSkipSslValidationCredentialsProvider should always support the trust repo YesNoType item",
+ skipSslValidationCredentialsProvider.supports(yesNoType));
+
+ yesNoType = new CredentialItem.YesNoType(JGitText.get().sslTrustAlways);
+ assertTrue(
+ "GitSkipSslValidationCredentialsProvider should always support the trust always YesNoType item",
+ skipSslValidationCredentialsProvider.supports(yesNoType));
+
+ yesNoType = new CredentialItem.YesNoType("unrelated");
+ assertFalse(
+ "GitSkipSslValidationCredentialsProvider should not support unrelated YesNoType items",
+ skipSslValidationCredentialsProvider.supports(yesNoType));
+ }
+
+ @Test
+ public void testSupportsYesNoTypeWithDelegate() {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ mockDelegateCredentialsProvider);
+
+ testSupportsSslValidationYesNoTypes();
+ }
+
+ @Test
+ public void testSupportsUnrelatedCredentialItemTypes() {
+ CredentialItem usernameCredentialItem = new CredentialItem.Username();
+
+ boolean supportsItems = skipSslValidationCredentialsProvider
+ .supports(usernameCredentialItem);
+
+ assertFalse(
+ "Credential item types not related to SSL validation skipping should not be supported",
+ supportsItems);
+ }
+
+ @Test
+ public void testSupportsUnrelatedCredentialItemTypesWithDelegate() {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ mockDelegateCredentialsProvider);
+ CredentialItem usernameCredentialItem = new CredentialItem.Username();
+
+ when(mockDelegateCredentialsProvider.supports(usernameCredentialItem))
+ .thenReturn(true);
+
+ boolean supportsItems = skipSslValidationCredentialsProvider
+ .supports(usernameCredentialItem);
+
+ assertTrue(
+ "GitSkipSslValidationCredentialsProvider must support the types supported by its delegate CredentialsProvider",
+ supportsItems);
+ }
+
+ @Test(expected = UnsupportedCredentialItem.class)
+ public void testGetUnrelatedCredentialItemTypes() throws URISyntaxException {
+ URIish uri = new URIish("https://example.com/repo.git");
+ CredentialItem usernameCredentialItem = new CredentialItem.Username();
+ CredentialItem passwordCredentialItem = new CredentialItem.Password();
+
+ skipSslValidationCredentialsProvider.get(uri, usernameCredentialItem,
+ passwordCredentialItem);
+ }
+
+ @Test
+ public void testGetUnrelatedCredentialItemTypesWithDelegate()
+ throws URISyntaxException {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ mockDelegateCredentialsProvider);
+ URIish uri = new URIish("https://example.com/repo.git");
+ CredentialItem usernameCredentialItem = new CredentialItem.Username();
+ CredentialItem passwordCredentialItem = new CredentialItem.Password();
+
+ when(mockDelegateCredentialsProvider.get(uri, usernameCredentialItem,
+ passwordCredentialItem)).thenReturn(true);
+
+ boolean getSuccessful = skipSslValidationCredentialsProvider.get(uri,
+ usernameCredentialItem, passwordCredentialItem);
+
+ assertTrue(
+ "GitSkipSslValidationCredentialsProvider must successfully get the types supported by its delegate CredentialsProvider",
+ getSuccessful);
+ }
+
+ @Test
+ public void testGetSslTrustItems() throws URISyntaxException {
+ URIish uri = new URIish("https://example.com/repo.git");
+ CredentialItem message = new CredentialItem.InformationalMessage(
+ JGitText.get().sslFailureTrustExplanation);
+ CredentialItem.YesNoType trustNow = new CredentialItem.YesNoType(
+ JGitText.get().sslTrustNow);
+ CredentialItem.YesNoType trustAlways = new CredentialItem.YesNoType(
+ JGitText.get().sslTrustAlways);
+
+ boolean getSuccessful = skipSslValidationCredentialsProvider.get(uri, message,
+ trustNow, trustAlways);
+
+ assertTrue(
+ "SkipSSlValidationCredentialsProvider must successfully get the types required for SSL validation skipping",
+ getSuccessful);
+ assertTrue(
+ "SkipSSlValidationCredentialsProvider should trust the current repo operation",
+ trustNow.getValue());
+ assertFalse("We should not globally skip all SSL validation",
+ trustAlways.getValue());
+ }
+
+ @Test
+ public void testGetSslTrustItemsWithDelegate() throws URISyntaxException {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ mockDelegateCredentialsProvider);
+
+ testGetSslTrustItems();
+ }
+
+ @Test
+ public void testGetSslTrustItemsWithLocalRepo() throws URISyntaxException {
+ URIish uri = new URIish("https://example.com/repo.git");
+ CredentialItem message = new CredentialItem.InformationalMessage(
+ JGitText.get().sslFailureTrustExplanation);
+ CredentialItem.YesNoType trustNow = new CredentialItem.YesNoType(
+ JGitText.get().sslTrustNow);
+ CredentialItem.YesNoType trustForRepo = new CredentialItem.YesNoType(
+ JGitText.get().sslTrustForRepo);
+ CredentialItem.YesNoType trustAlways = new CredentialItem.YesNoType(
+ JGitText.get().sslTrustAlways);
+
+ boolean getSuccessful = skipSslValidationCredentialsProvider.get(uri, message,
+ trustNow, trustForRepo, trustAlways);
+
+ assertTrue(
+ "SkipSSlValidationCredentialsProvider must successfully get the types required for SSL validation skipping",
+ getSuccessful);
+ assertTrue(
+ "SkipSSlValidationCredentialsProvider should trust the current repo operation",
+ trustNow.getValue());
+ assertTrue("Future operations on this repository should also be trusted",
+ trustForRepo.getValue());
+ assertFalse("We should not globally skip all SSL validation",
+ trustAlways.getValue());
+ }
+
+ @Test
+ public void testGetSslTrustItemsWithLocalRepoAndDelegate() throws URISyntaxException {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ mockDelegateCredentialsProvider);
+
+ testGetSslTrustItemsWithLocalRepo();
+ }
+
+ @Test
+ public void testReset() throws URISyntaxException {
+ URIish uri = new URIish("https://example.com/repo.git");
+
+ skipSslValidationCredentialsProvider.reset(uri);
+ }
+
+ @Test
+ public void testResetWithDelegate() throws URISyntaxException {
+ this.skipSslValidationCredentialsProvider = new GitSkipSslValidationCredentialsProvider(
+ mockDelegateCredentialsProvider);
+ URIish uri = new URIish("https://example.com/repo.git");
+
+ skipSslValidationCredentialsProvider.reset(uri);
+
+ verify(mockDelegateCredentialsProvider).reset(uri);
+ }
+}
diff --git a/spring-cloud-config-server/src/test/resources/ssh/ssh-nested-settings-list.yml b/spring-cloud-config-server/src/test/resources/ssh/ssh-nested-settings-list.yml
new file mode 100644
index 00000000..c265f489
--- /dev/null
+++ b/spring-cloud-config-server/src/test/resources/ssh/ssh-nested-settings-list.yml
@@ -0,0 +1,42 @@
+spring:
+ cloud:
+ config:
+ server:
+ composite:
+ - type: git
+ uri: git@gitserver.com:team/repo1.git
+ ignoreLocalSshSettings: true
+ privateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAoqyz6YaYMTr7L8GLPSQpAQXaM04gRx4CCsGK2kfLQdw4BlqI\nyyxp38YcuZG9cUDBAxby+K2TKmwHaC1R61QTwbPuCRdIPrDwRz+FLoegm3iDLCmn\nuP6rjZDneYsqfU1KSdrOwIbCnONfDdvYL/vnZC/o8DDMlk5Orw2SfHkT3pq0o8km\nayBwN4Sf3bpyWTY0oZcmNeSCCoIdE59k8Pa7/t9bwY9caLj05C3DEsjucc7Ei/Eq\nTOyGyobtXwaya5CqKLUHes74Poz1aEP/yVFdUud91uezd8ZK1P1t5/ZKA3R6aHir\n+diDJ2/GQ2tD511FW46yw+EtBUJTO6ADVv4UnQIDAQABAoIBAF+5qwEfX82QfKFk\njfADqFFexUDtl1biFKeJrpC2MKhn01wByH9uejrhFKQqW8UaKroLthyZ34DWIyGt\nlDnHGv0gSVF2LuAdNLdobJGt49e4+c9yD61vxzm97Eh8mRs08SM2q/VlF35E2fmI\nxdWusUImYzd8L9e+6tRd8zZl9UhG5vR5XIstKqxC6S0g79aAt0hasE4Gw1FKOf2V\n4mlL15atjQSKCPdOicuyc4zpjAtU1A9AfF51iG8oOUuJebPW8tCftfOQxaeGFgMG\n7M9aai1KzXR6M5IBAKEv31yBvz/SHTneP7oZXNLeC1GIR420PKybmeZdNK8BbEAu\n3reKgm0CgYEA03Sx8JoF5UBsIvFPpP1fjSlTgKryM5EJR6KQtj5e4YfyxccJepN8\nq4MrqDfNKleG/a1acEtDMhBNovU7Usp2QIP7zpAeioHBOhmE5WSieZGc3icOGWWq\nmRkdulSONruqWKv76ZoluxftekE03bDhZDNlcCgmrslEKB/ufHd2oc8CgYEAxPFa\nlKOdSeiYFV5CtvO8Ro8em6rGpSsVz4qkPxbeBqUDCb9KXHhq6YrhRxOIfQJKfT7M\nZFCn8ArJXKgOGu+KsvwIErFHF9g2jJMG4DOUTpkQgi2yveihFxcmz/AltyVXgrnv\nZWQbAerH77pdKKhNivLGgEv72GYawdYjYNjemdMCgYA2kEMmMahZyrDcp2YEzfit\nBT/t0K6kzcUWPgWXcSqsiZcEn+J7RbmCzFskkhmX1nQX23adyV3yejB+X0dKisHO\nzf/ZAmlPFkJVCqa3RquCMSfIT02dEhXeYZPBM/Zqeyxuqxpa4hLgX0FBLbhFiFHw\nuC5xrXql2XuD2xF//peXEwKBgQC+pa28Cg7vRxxCQzduB9CQtWc55j3aEjVQ7bNF\n54sS/5ZLT0Ra8677WZfuyDfuW9NkHvCZg4Ku2qJG8eCFrrGjxlrCTZ62tHVJ6+JS\nE1xUIdRbUIWhVZrr0VufG6hG/P0T7Y6Tpi6G0pKtvMkF3LcD9TS3adboix8H2ZXx\n4L7MRQKBgQC0OO3qqNXOjIVYWOoqXLybOY/Wqu9lxCAgGyCYaMcstnBI7W0MZTBr\n/syluvGsaFc1sE7MMGOOzKi1tF4YvDmSnzA/R1nmaPguuD9fOA+w7Pwkv5vLvuJq\n2U7EeNwxq1I1L3Ag6E7wH4BHLHd4TKaZR6agFkn8oomz71yZPGjuZQ==\n-----END RSA PRIVATE KEY-----"
+ repos:
+ repo1:
+ uri: git@gitserver.com:team/repo2.git
+ hostKey: someHostKey
+ hostKeyAlgorithm: ssh-rsa
+ privateKey: |
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIEpgIBAAKCAQEAx4UbaDzY5xjW6hc9jwN0mX33XpTDVW9WqHp5AKaRbtAC3DqX
+ IXFMPgw3K45jxRb93f8tv9vL3rD9CUG1Gv4FM+o7ds7FRES5RTjv2RT/JVNJCoqF
+ ol8+ngLqRZCyBtQN7zYByWMRirPGoDUqdPYrj2yq+ObBBNhg5N+hOwKjjpzdj2Ud
+ 1l7R+wxIqmJo1IYyy16xS8WsjyQuyC0lL456qkd5BDZ0Ag8j2X9H9D5220Ln7s9i
+ oezTipXipS7p7Jekf3Ywx6abJwOmB0rX79dV4qiNcGgzATnG1PkXxqt76VhcGa0W
+ DDVHEEYGbSQ6hIGSh0I7BQun0aLRZojfE3gqHQIDAQABAoIBAQCZmGrk8BK6tXCd
+ fY6yTiKxFzwb38IQP0ojIUWNrq0+9Xt+NsypviLHkXfXXCKKU4zUHeIGVRq5MN9b
+ BO56/RrcQHHOoJdUWuOV2qMqJvPUtC0CpGkD+valhfD75MxoXU7s3FK7yjxy3rsG
+ EmfA6tHV8/4a5umo5TqSd2YTm5B19AhRqiuUVI1wTB41DjULUGiMYrnYrhzQlVvj
+ 5MjnKTlYu3V8PoYDfv1GmxPPh6vlpafXEeEYN8VB97e5x3DGHjZ5UrurAmTLTdO8
+ +AahyoKsIY612TkkQthJlt7FJAwnCGMgY6podzzvzICLFmmTXYiZ/28I4BX/mOSe
+ pZVnfRixAoGBAO6Uiwt40/PKs53mCEWngslSCsh9oGAaLTf/XdvMns5VmuyyAyKG
+ ti8Ol5wqBMi4GIUzjbgUvSUt+IowIrG3f5tN85wpjQ1UGVcpTnl5Qo9xaS1PFScQ
+ xrtWZ9eNj2TsIAMp/svJsyGG3OibxfnuAIpSXNQiJPwRlW3irzpGgVx/AoGBANYW
+ dnhshUcEHMJi3aXwR12OTDnaLoanVGLwLnkqLSYUZA7ZegpKq90UAuBdcEfgdpyi
+ PhKpeaeIiAaNnFo8m9aoTKr+7I6/uMTlwrVnfrsVTZv3orxjwQV20YIBCVRKD1uX
+ VhE0ozPZxwwKSPAFocpyWpGHGreGF1AIYBE9UBtjAoGBAI8bfPgJpyFyMiGBjO6z
+ FwlJc/xlFqDusrcHL7abW5qq0L4v3R+FrJw3ZYufzLTVcKfdj6GelwJJO+8wBm+R
+ gTKYJItEhT48duLIfTDyIpHGVm9+I1MGhh5zKuCqIhxIYr9jHloBB7kRm0rPvYY4
+ VAykcNgyDvtAVODP+4m6JvhjAoGBALbtTqErKN47V0+JJpapLnF0KxGrqeGIjIRV
+ cYA6V4WYGr7NeIfesecfOC356PyhgPfpcVyEztwlvwTKb3RzIT1TZN8fH4YBr6Ee
+ KTbTjefRFhVUjQqnucAvfGi29f+9oE3Ei9f7wA+H35ocF6JvTYUsHNMIO/3gZ38N
+ CPjyCMa9AoGBAMhsITNe3QcbsXAbdUR00dDsIFVROzyFJ2m40i4KCRM35bC/BIBs
+ q0TY3we+ERB40U8Z2BvU61QuwaunJ2+uGadHo58VSVdggqAo0BSkH58innKKt96J
+ 69pcVH/4rmLbXdcmNYGm6iu+MlPQk4BUZknHSmVHIFdJ0EPupVaQ8RHT
+ -----END RSA PRIVATE KEY-----
diff --git a/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-block-list.yml b/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-block-list.yml
new file mode 100644
index 00000000..90bb2009
--- /dev/null
+++ b/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-block-list.yml
@@ -0,0 +1,36 @@
+spring:
+ cloud:
+ config:
+ server:
+ composite:
+ - type: git
+ uri: git@gitserver.com:team/repo.git
+ ignoreLocalSshSettings: true
+ privateKey: |
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIEpAIBAAKCAQEAoqyz6YaYMTr7L8GLPSQpAQXaM04gRx4CCsGK2kfLQdw4BlqI
+ yyxp38YcuZG9cUDBAxby+K2TKmwHaC1Wf1QTwbPuCRdIPrDwRz+FLoegm3iDLCmn
+ uP6rjZDneYsqfU1sSdrOwIbCnONfDdvYL/vnZC/o8DDMlk5Orw2SfHkT3pq0o8km
+ ayBwN4Sf3bpyWTY0oZcmNeSCCoIdE59k8Pa7/t9bwY9caLj05C3DEsjucc7Ei/Eq
+ TOyGyobtXwaya5CqKLUHes74Poz1aEP/yVFdUud91uezd8ZK1P1t5/ZKA3R6aHir
+ +diDJ2/GQ2tD511FW46yw+EtBUJTO6ADVv4UnQIDAQABAoIBAF+5qwEfX82QfKFk
+ jfADqFFexUDtl1biFKeJrpC2MKhn01wByH9uejrhFKQqW8UaKroLthyZ34DWIyGt
+ lDnHGv0gSVF2LuAdNLdobJGt49e4+c9yD61vxzm97Eh8mRs08SM2q/VlF35E2fmI
+ xdWusUImYzd8L9e+6tRd8zZl9UhG5vR5XIstKqxC6S0g79aAt0hasE4Gw1FKOf2V
+ 4mlL15atjQSKCPdOicuyc4zpjAtU1A9AfF51iG8oOUuJebPW8tCftfOQxaeGFgMG
+ 7M9aai1KzXR6M5IBAKEv31yBvz/SHTneP7oZXNLeC1GIR420PKybmeZdNK8BbEAu
+ 3reKgm0CgYEA03Sx8JgF5UBsIvFPpP1fjSlTgKryM5EJR6KQtj5e4YfyxccJepN8
+ q4MrqDfNKleG/a1acEtDMhBNovU7Usp2QIP7zpAeioHBOhmE5WSieZGc3icOGWWq
+ mRkdulSONruqWKv76ZoluxftekE03bDhZDNlcCgmrslEKB/ufHd2oc8CgYEAxPFa
+ lKOdSeiYFV5CtvO8Ro8em6rGpSsVz4qkPxbeBqUDCb9KXHhq6YrhRxOIfQJKfT7M
+ ZFCn8ArJXKgOGu+KsvwIErFHF9g2jJMG4DOUTpkQgi2yveihFxcmz/AltyVXgrnv
+ ZWQbAerH77pdKKhNivLGgEv72GYawdYjYNjemdMCgYA2kEMmMahZyrDcp2YEzfit
+ BT/t0K6kzcUWPgWXcSqsiZcEn+J7RbmCzFskkhmX1nQX23adyV3yejB+X0dKisHO
+ zf/ZAmlPFkJVCqa3RquCMSfIT02dEhXeYZPBM/Zqeyxuqxpa4hLgX0FBLbhFiFHw
+ uC5xrXql2XuD2xF//peXEwKBgQC+pa28Cg7vRxxCQzduB9CQtWc55j3aEjVQ7bNF
+ 54sS/5ZLT0Ra8677WZfuyDfuW9NkHvCZg4Ku2qJG8eCFrrGjxlrCTZ62tHVJ6+JS
+ E1xUIdRbUIWhVZrr0VufG6hG/P0T7Y6Tpi6G0pKtvMkF3LcD9TS3adboix8H2ZXx
+ 4L7MRQKBgQC0OO3qqNXOjIVYWOoqXLybOY/Wqu9lxCAgGyCYaMcstnBI7W0MZTBr
+ /syluvGsaFc1sE7MMGOOzKi1tF4YvDmSnzA/R1nmaPguuD9fOA+w7Pwkv5vLvuJq
+ 2U7EeNwxq1I1L3Ag6E7wH4BHLHd4TKaZR6agFkn8oomz71yZPGjuZQ==
+ -----END RSA PRIVATE KEY-----
\ No newline at end of file
diff --git a/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-newline-list.yml b/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-newline-list.yml
new file mode 100644
index 00000000..2fe26da9
--- /dev/null
+++ b/spring-cloud-config-server/src/test/resources/ssh/ssh-private-key-newline-list.yml
@@ -0,0 +1,11 @@
+spring:
+ cloud:
+ config:
+ server:
+ composite:
+ - type: git
+ uri: git@gitserver.com:team/repo.git
+ ignoreLocalSshSettings: true
+ privateKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAoqyz6YaYMTr7L8GLPSQpAQXaM04gRx4CCsGK2kfLQdw4BlqI\nyyxp38YcuZG9cUDBAxby+K2TKmwHaC1R61QTwbPuCRdIPrDwRz+FLoegm3iDLCmn\nuP6rjZDneYsqfU1KSdrOwIbCnONfDdvYL/vnZC/o8DDMlk5Orw2SfHkT3pq0o8km\nayBwN4Sf3bpyWTY0oZcmNeSCCoIdE59k8Pa7/t9bwY9caLj05C3DEsjucc7Ei/Eq\nTOyGyobtXwaya5CqKLUHes74Poz1aEP/yVFdUud91uezd8ZK1P1t5/ZKA3R6aHir\n+diDJ2/GQ2tD511FW46yw+EtBUJTO6ADVv4UnQIDAQABAoIBAF+5qwEfX82QfKFk\njfADqFFexUDtl1biFKeJrpC2MKhn01wByH9uejrhFKQqW8UaKroLthyZ34DWIyGt\nlDnHGv0gSVF2LuAdNLdobJGt49e4+c9yD61vxzm97Eh8mRs08SM2q/VlF35E2fmI\nxdWusUImYzd8L9e+6tRd8zZl9UhG5vR5XIstKqxC6S0g79aAt0hasE4Gw1FKOf2V\n4mlL15atjQSKCPdOicuyc4zpjAtU1A9AfF51iG8oOUuJebPW8tCftfOQxaeGFgMG\n7M9aai1KzXR6M5IBAKEv31yBvz/SHTneP7oZXNLeC1GIR420PKybmeZdNK8BbEAu\n3reKgm0CgYEA03Sx8JoF5UBsIvFPpP1fjSlTgKryM5EJR6KQtj5e4YfyxccJepN8\nq4MrqDfNKleG/a1acEtDMhBNovU7Usp2QIP7zpAeioHBOhmE5WSieZGc3icOGWWq\nmRkdulSONruqWKv76ZoluxftekE03bDhZDNlcCgmrslEKB/ufHd2oc8CgYEAxPFa\nlKOdSeiYFV5CtvO8Ro8em6rGpSsVz4qkPxbeBqUDCb9KXHhq6YrhRxOIfQJKfT7M\nZFCn8ArJXKgOGu+KsvwIErFHF9g2jJMG4DOUTpkQgi2yveihFxcmz/AltyVXgrnv\nZWQbAerH77pdKKhNivLGgEv72GYawdYjYNjemdMCgYA2kEMmMahZyrDcp2YEzfit\nBT/t0K6kzcUWPgWXcSqsiZcEn+J7RbmCzFskkhmX1nQX23adyV3yejB+X0dKisHO\nzf/ZAmlPFkJVCqa3RquCMSfIT02dEhXeYZPBM/Zqeyxuqxpa4hLgX0FBLbhFiFHw\nuC5xrXql2XuD2xF//peXEwKBgQC+pa28Cg7vRxxCQzduB9CQtWc55j3aEjVQ7bNF\n54sS/5ZLT0Ra8677WZfuyDfuW9NkHvCZg4Ku2qJG8eCFrrGjxlrCTZ62tHVJ6+JS\nE1xUIdRbUIWhVZrr0VufG6hG/P0T7Y6Tpi6G0pKtvMkF3LcD9TS3adboix8H2ZXx\n4L7MRQKBgQC0OO3qqNXOjIVYWOoqXLybOY/Wqu9lxCAgGyCYaMcstnBI7W0MZTBr\n/syluvGsaFc1sE7MMGOOzKi1tF4YvDmSnzA/R1nmaPguuD9fOA+w7Pwkv5vLvuJq\n2U7EeNwxq1I1L3Ag6E7wH4BHLHd4TKaZR6agFkn8oomz71yZPGjuZQ==\n-----END RSA PRIVATE KEY-----"
+ hostKey: somekey
+ hostKeyAlgorithm: ssh-rsa
diff --git a/spring-cloud-config-server/src/test/resources/test1-config-repo/git/info/refs b/spring-cloud-config-server/src/test/resources/test1-config-repo/git/info/refs
new file mode 100644
index 00000000..c2763f61
--- /dev/null
+++ b/spring-cloud-config-server/src/test/resources/test1-config-repo/git/info/refs
@@ -0,0 +1 @@
+4e1f25bbdca5765e279b436b5b02d05b1654515c refs/heads/master