Enable Transport configuration for git repos in a composite (#981)

Merge Ssh configuration properties classes with JGitEnvironmentProperties

Fixes gh-976
This commit is contained in:
Dylan Roberts
2018-04-19 09:32:59 -04:00
committed by Ryan Baxter
parent 69d8bfc841
commit 54b505ffc3
27 changed files with 774 additions and 778 deletions

View File

@@ -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

View File

@@ -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 {
}

View File

@@ -17,7 +17,6 @@ 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;
@@ -114,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);
}
}
@@ -199,8 +198,8 @@ class CompositeRepositoryConfiguration {
@Bean
public MultipleJGitEnvironmentRepositoryFactory gitEnvironmentRepositoryFactory(
ConfigurableEnvironment environment, ConfigServerProperties server,
Optional<TransportConfigCallback> transportConfigCallback) {
return new MultipleJGitEnvironmentRepositoryFactory(environment, server, transportConfigCallback);
Optional<TransportConfigCallback> customTransportConfigCallback) {
return new MultipleJGitEnvironmentRepositoryFactory(environment, server, customTransportConfigCallback);
}
}

View File

@@ -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");
}
});
}
}
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.cloud.config.server.environment;
import javax.validation.constraints.Pattern;
import org.springframework.cloud.config.server.support.AbstractScmAccessorProperties;
/**
@@ -40,6 +42,42 @@ public class JGitEnvironmentProperties extends AbstractScmAccessorProperties {
*/
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);
@@ -84,4 +122,62 @@ public class JGitEnvironmentProperties extends AbstractScmAccessorProperties {
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;
}
}

View File

@@ -19,11 +19,21 @@ 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.

View File

@@ -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> transportConfigCallback;
private Optional<TransportConfigCallback> customTransportConfigCallback;
public MultipleJGitEnvironmentRepositoryFactory(ConfigurableEnvironment environment, ConfigServerProperties server,
Optional<TransportConfigCallback> transportConfigCallback) {
Optional<TransportConfigCallback> 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);
}
}

View File

@@ -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");
}
});
}
}

View File

@@ -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<HostKeyAlgoSupported, SshUriProperties> {
public class HostKeyAlgoSupportedValidator implements ConstraintValidator<HostKeyAlgoSupported, MultipleJGitEnvironmentProperties> {
private static final String GIT_PROPERTY_PREFIX = "spring.cloud.config.server.git.";
private final SshPropertyValidator sshPropertyValidator = new SshPropertyValidator();
private static final Set<String> VALID_HOST_KEY_ALGORITHMS = new LinkedHashSet<>(Arrays.asList(
@@ -49,12 +51,12 @@ public class HostKeyAlgoSupportedValidator implements ConstraintValidator<HostKe
}
@Override
public boolean isValid(SshUriProperties sshUriProperties, ConstraintValidatorContext context) {
public boolean isValid(MultipleJGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
context.disableDefaultConstraintViolation();
Set<Boolean> validationResults = new HashSet<>();
List<SshUri> extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
List<JGitEnvironmentProperties> 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<HostKe
return !validationResults.contains(false);
}
private boolean isHostKeySpecifiedWhenAlgorithmSet(SshUri sshUriProperties, ConstraintValidatorContext context) {
private boolean isHostKeySpecifiedWhenAlgorithmSet(JGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
if (hasText(sshUriProperties.getHostKeyAlgorithm())
&& !VALID_HOST_KEY_ALGORITHMS.contains(sshUriProperties.getHostKeyAlgorithm())) {

View File

@@ -21,6 +21,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;
@@ -28,7 +30,7 @@ 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 is set then host key algo must also be set
* - If host key algo is set then host key must also be set
*
@@ -36,7 +38,7 @@ import static org.springframework.util.StringUtils.hasText;
*
* @author Ollie Hughes
*/
public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator<HostKeyAndAlgoBothExist, SshUriProperties> {
public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator<HostKeyAndAlgoBothExist, MultipleJGitEnvironmentProperties> {
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<Hos
}
@Override
public boolean isValid(SshUriProperties sshUriProperties, ConstraintValidatorContext context) {
public boolean isValid(MultipleJGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
Set<Boolean> validationResults = new HashSet<>();
List<SshUri> extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
List<JGitEnvironmentProperties> 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<Hos
return !validationResults.contains(false);
}
private boolean isHostKeySpecifiedWhenAlgorithmSet(SshUri sshUriProperties, ConstraintValidatorContext context) {
private boolean isHostKeySpecifiedWhenAlgorithmSet(JGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
if (hasText(sshUriProperties.getHostKeyAlgorithm()) && !hasText(sshUriProperties.getHostKey())) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(
@@ -71,7 +73,7 @@ public class HostKeyAndAlgoBothExistValidator implements ConstraintValidator<Hos
return true;
}
private boolean isAlgorithmSpecifiedWhenHostKeySet(SshUri sshUriProperties, ConstraintValidatorContext context) {
private boolean isAlgorithmSpecifiedWhenHostKeySet(JGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
if (hasText(sshUriProperties.getHostKey()) && !hasText(sshUriProperties.getHostKeyAlgorithm())) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(

View File

@@ -16,23 +16,24 @@
package org.springframework.cloud.config.server.ssh;
import org.springframework.validation.annotation.Validated;
import java.io.File;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.io.File;
import static java.lang.String.*;
import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
import org.springframework.validation.annotation.Validated;
import static java.lang.String.format;
/**
* 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:
* - Verifies that known hosts file exists
* <p>
* Beans annotated with {@link KnownHostsFileIsValid} and {@link Validated} will have the constraints applied.
*
* @author Edgars Jasmans
*/
public class KnownHostsFileValidator implements ConstraintValidator<KnownHostsFileIsValid, SshUriProperties> {
public class KnownHostsFileValidator implements ConstraintValidator<KnownHostsFileIsValid, MultipleJGitEnvironmentProperties> {
@Override
public void initialize(KnownHostsFileIsValid knownHostsFileIsValid) {
@@ -40,7 +41,7 @@ public class KnownHostsFileValidator implements ConstraintValidator<KnownHostsFi
}
@Override
public boolean isValid(SshUriProperties sshUriProperties, ConstraintValidatorContext context) {
public boolean isValid(MultipleJGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
String knownHostsFile = sshUriProperties.getKnownHostsFile();
if (knownHostsFile != null && !new File(knownHostsFile).exists()) {
context.disableDefaultConstraintViolation();

View File

@@ -25,6 +25,8 @@ import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.KeyPair;
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;
@@ -32,14 +34,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 an {@link SshUriProperties} bean for the constraints:
* JSR-303 Cross Field validator that ensures that an {@link MultipleJGitEnvironmentProperties} bean for the constraints:
* - Private key is present and can be correctly parsed using {@link com.jcraft.jsch.KeyPair}
*
* Beans annotated with {@link PrivateKeyValidator} and {@link Validated} will have the constraints applied.
*
* @author Ollie Hughes
*/
public class PrivateKeyValidator implements ConstraintValidator<PrivateKeyIsValid, SshUriProperties> {
public class PrivateKeyValidator implements ConstraintValidator<PrivateKeyIsValid, MultipleJGitEnvironmentProperties> {
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<PrivateKeyIsVali
}
@Override
public boolean isValid(SshUriProperties sshUriProperties, ConstraintValidatorContext context) {
public boolean isValid(MultipleJGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
context.disableDefaultConstraintViolation();
Set<Boolean> validationResults = new HashSet<>();
List<SshUri> extractedProperties = sshPropertyValidator.extractRepoProperties(sshUriProperties);
List<JGitEnvironmentProperties> 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<PrivateKeyIsVali
}
private boolean isPrivateKeyPresent(SshUri sshUriProperties, ConstraintValidatorContext context) {
private boolean isPrivateKeyPresent(JGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
if (!hasText(sshUriProperties.getPrivateKey())) {
context.buildConstraintViolationWithTemplate(
format("Property '%sprivateKey' must be set when '%signoreLocalSshSettings' is specified", GIT_PROPERTY_PREFIX, GIT_PROPERTY_PREFIX))
@@ -75,7 +77,7 @@ public class PrivateKeyValidator implements ConstraintValidator<PrivateKeyIsVali
return true;
}
private boolean isPrivateKeyFormatCorrect(SshUri sshUriProperties, ConstraintValidatorContext context) {
private boolean isPrivateKeyFormatCorrect(JGitEnvironmentProperties sshUriProperties, ConstraintValidatorContext context) {
try {
KeyPair.load(new JSch(), sshUriProperties.getPrivateKey().getBytes(), null);
return true;

View File

@@ -0,0 +1,50 @@
/*
* 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.JSch;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.transport.SshTransport;
import org.eclipse.jgit.transport.Transport;
import org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties;
/**
* Configure JGit transport command to use a SSH session factory that is configured using properties defined
* in {@link MultipleJGitEnvironmentProperties}
*/
public class PropertiesBasedSshTransportConfigCallback implements TransportConfigCallback {
private MultipleJGitEnvironmentProperties sshUriProperties;
public PropertiesBasedSshTransportConfigCallback(MultipleJGitEnvironmentProperties sshUriProperties) {
this.sshUriProperties = sshUriProperties;
}
public MultipleJGitEnvironmentProperties 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()));
}
}
}

View File

@@ -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.
@@ -26,6 +26,8 @@ import org.eclipse.jgit.transport.OpenSshConfig.Host;
import org.eclipse.jgit.util.Base64;
import org.eclipse.jgit.util.FS;
import org.springframework.cloud.config.server.environment.JGitEnvironmentProperties;
/**
* In a cloud environment local SSH config files such as `.known_hosts` may not be suitable for providing
* configuration settings due to ephemeral filesystems. This flag enables SSH config to be provided as application
@@ -40,17 +42,17 @@ public class PropertyBasedSshSessionFactory extends JschConfigSessionFactory {
private static final String YES_OPTION = "yes";
private static final String NO_OPTION = "no";
private static final String SERVER_HOST_KEY = "server_host_key";
private final Map<String, SshUri> sshKeysByHostname;
private final Map<String, JGitEnvironmentProperties> sshKeysByHostname;
private final JSch jSch;
public PropertyBasedSshSessionFactory(Map<String, SshUri> sshKeysByHostname, JSch jSch) {
public PropertyBasedSshSessionFactory(Map<String, JGitEnvironmentProperties> 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());

View File

@@ -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<SshUri> extractRepoProperties(SshUriProperties sshUriProperties) {
List<SshUri> allRepoProperties = new ArrayList<>();
protected List<JGitEnvironmentProperties> extractRepoProperties(MultipleJGitEnvironmentProperties sshUriProperties) {
List<JGitEnvironmentProperties> allRepoProperties = new ArrayList<>();
allRepoProperties.add(sshUriProperties);
Map<String, SshUriProperties.SshUriNestedRepoProperties> repos = sshUriProperties.getRepos();
Map<String, MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties> repos = sshUriProperties.getRepos();
if (repos != null) {
allRepoProperties.addAll(repos.values());
}

View File

@@ -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<String, SshUriNestedRepoProperties> 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<String, SshUriNestedRepoProperties> 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 + ")";
}
}
}

View File

@@ -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<String, SshUriProperties.SshUriNestedRepoProperties> repos = new LinkedHashMap<>();
public Map<String, SshUriProperties.SshUriNestedRepoProperties> getRepos() {
return this.repos;
}
public void setRepos(Map<String, SshUriNestedRepoProperties> 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 {
}
}

View File

@@ -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<String, SshUri> getSshKeysByHostname() {
public Map<String, JGitEnvironmentProperties> getSshKeysByHostname() {
return extractNestedProperties(sshUriProperties);
}
private Map<String, SshUri> extractNestedProperties(SshUriProperties uriProperties) {
Map<String, SshUri> sshUriPropertyMap = new HashMap<>();
private Map<String, JGitEnvironmentProperties> extractNestedProperties(MultipleJGitEnvironmentProperties uriProperties) {
Map<String, JGitEnvironmentProperties> sshUriPropertyMap = new HashMap<>();
String parentUri = uriProperties.getUri();
if (isSshUri(parentUri) && getHostname(parentUri) != null) {
sshUriPropertyMap.put(getHostname(parentUri), uriProperties);
}
Map<String, SshUriNestedRepoProperties> repos = uriProperties.getRepos();
Map<String, MultipleJGitEnvironmentProperties.PatternMatchingJGitEnvironmentProperties> 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);

View File

@@ -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

View File

@@ -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<String> keyCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> 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<String> keyCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> 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<String> keyCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> 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 {

View File

@@ -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)));
}
}

View File

@@ -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<String, SshUri> sshKeysByHostname = new HashMap<>();
private void setupSessionFactory(JGitEnvironmentProperties sshKey) {
Map<String, JGitEnvironmentProperties> sshKeysByHostname = new HashMap<>();
sshKeysByHostname.put(SshUriPropertyProcessor.getHostname(sshKey.getUri()), sshKey);
factory = new PropertyBasedSshSessionFactory(sshKeysByHostname, jSch) ;
when(hc.getHostName()).thenReturn(SshUriPropertyProcessor.getHostname(sshKey.getUri()));

View File

@@ -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<ConstraintViolation<SshUriProperties>> constraintViolations = validator.validate(validSettings);
Set<ConstraintViolation<MultipleJGitEnvironmentProperties>> 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<ConstraintViolation<SshUriProperties>> constraintViolations = validator.validate(invalidKey);
Set<ConstraintViolation<MultipleJGitEnvironmentProperties>> 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<ConstraintViolation<SshUriProperties>> constraintViolations = validator.validate(missingKey);
Set<ConstraintViolation<MultipleJGitEnvironmentProperties>> 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<ConstraintViolation<SshUriProperties>> constraintViolations = validator.validate(missingAlgo);
Set<ConstraintViolation<MultipleJGitEnvironmentProperties>> 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<ConstraintViolation<SshUriProperties>> constraintViolations = validator.validate(missingHostKey);
Set<ConstraintViolation<MultipleJGitEnvironmentProperties>> 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<ConstraintViolation<SshUriProperties>> constraintViolations = validator.validate(unsupportedAlgo);
Set<ConstraintViolation<MultipleJGitEnvironmentProperties>> 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<ConstraintViolation<SshUriProperties>> constraintViolations = validator.validate(useLocal);
Set<ConstraintViolation<MultipleJGitEnvironmentProperties>> 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<ConstraintViolation<SshUriProperties>> constraintViolations = validator.validate(httpsUri);
Set<ConstraintViolation<MultipleJGitEnvironmentProperties>> 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");

View File

@@ -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<String, SshUri> sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
Map<String, JGitEnvironmentProperties> 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<String, SshUri> sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
Map<String, JGitEnvironmentProperties> 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<String, SshUri> sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
Map<String, JGitEnvironmentProperties> 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<String, SshUri> sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(new MultipleJGitEnvironmentProperties());
Map<String, JGitEnvironmentProperties> sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
assertThat(sshKeysByHostname.values(), hasSize(0));
}
@Test
public void testInvalidUriDoesNotAddEntry() {
SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(SshUri.builder().uri("invalid_uri").build());
Map<String, SshUri> sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties();
sshUriProperties.setUri("invalid_uri");
SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties);
Map<String, JGitEnvironmentProperties> 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<String, SshUri> sshKeysByHostname = sshUriPropertyProcessor.getSshKeysByHostname();
MultipleJGitEnvironmentProperties sshUriProperties = new MultipleJGitEnvironmentProperties();
sshUriProperties.setUri("https://user@github.com/proj/repo.git");
SshUriPropertyProcessor sshUriPropertyProcessor = new SshUriPropertyProcessor(sshUriProperties);
Map<String, JGitEnvironmentProperties> 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)));

View File

@@ -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-----

View File

@@ -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-----

View File

@@ -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