I want to set multiple ssh keys to access git repository. ex:
spring:
cloud:
config:
server:
git:
uri: git@github.com:team/repo1.git
private-key: "repo1 rsa private key"
repos:
repo2:
uri: git@github.com:team/repo2.git
private-key: "repo2 rsa private key"
````
But here is always the last ssh configuration for github.com hostname.
[SshUriPropertyProcessor](https://github.com/spring-cloud/spring-cloud-config/blob/541fbff3521cc9a14b5e8c94f3efe69366dd0e3a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ssh/SshUriPropertyProcessor.java)
```java
private Map<String, SshUri> extractNestedProperties(SshUriProperties uriProperties) {
Map<String, SshUri> sshUriPropertyMap = new HashMap<>();
String parentUri = uriProperties.getUri();
if (isSshUri(parentUri) && getHostname(parentUri) != null) {
sshUriPropertyMap.put(getHostname(parentUri), uriProperties);
}
Map<String, SshUriNestedRepoProperties> repos = uriProperties.getRepos();
if(repos != null) {
for (SshUriNestedRepoProperties repoProperties : repos.values()) {
String repoUri = repoProperties.getUri();
if (isSshUri(repoUri) && getHostname(repoUri) != null) {
sshUriPropertyMap.put(getHostname(repoUri), repoProperties);
}
}
}
return sshUriPropertyMap;
}
And JschConfigSessionFactory only sends github.com host to create session. PropertyBasedSshSessionFactory
@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);
jSch.addIdentity(host, sshUriProperties.getPrivateKey().getBytes(), null, null);
if (sshUriProperties.getKnownHostsFile() != null) {
jSch.setKnownHosts(sshUriProperties.getKnownHostsFile());
}
if (sshUriProperties.getHostKey() != null) {
HostKey hostkey = new HostKey(host, Base64.decode(sshUriProperties.getHostKey()));
jSch.getHostKeyRepository().add(hostkey, null);
}
return jSch.getSession(user, host, port);
}
throw new JSchException("no keys configured for hostname " + host);
}
Comment From: ryanjbaxter
If the host names were different than the problem would not exit right?
Comment From: babyblue94520
This is an example of the issue. https://github.com/babyblue94520/config-server-issue
Comment From: ryanjbaxter
You have two issues in the repo. Issue number 1 looks like it was fixed here #892. I will backport that fix to the 1.4.x stream so it will be in the next Edgware release.
I dont know if we can solve the problem you have described here. JschConfigSessionFactory operates based on host, it doesnt look like it supports separate keys for the same host. The API doesnt seem to support it. @ojhughes any thoughts?
Comment From: ryanjbaxter
I applied #892 to the 1.4.x branch https://github.com/spring-cloud/spring-cloud-config/commit/dbccf9e5351f138e2c055f909ca1683844ad1e84
Comment From: ojhughes
I agree @ryanjbaxter in both cases the Map key is github.com so there is a single entry. Perhaps using the full URL as the Map key would solve this?
Comment From: ryanjbaxter
@ojhughes it probably would but the JschConfigSessionFactory API is kind of limiting. The createSession API only takes in user, host, port.
createSession(Host hc, String user, String host, int port, FS fs)
Comment From: babyblue94520
The full URL as a Map key can solve the problem, but JschConfigSessionFactory must be modified, although not a good method. Ex: https://github.com/babyblue94520/config-server-issue
Comment From: ojhughes
The cleanest solution I can think is changing the type of sshKeysByHostname to Map<String, List<SshUri>> and generate the map using something like repos.values().stream() .collect(Collectors.groupingBy(sshUri -> sshUri.getHostname(repoUri))
Comment From: ryanjbaxter
@ojhughes bump
Comment From: ojhughes
This is next on my todo list, will pick up after Easter break next week
Comment From: ojhughes
@babyblue94520 I have looked again at this and I think using composite configuration is the best way to define multiple repo's with different key's. eg
cloud:
config:
server:
composite:
-
type: git
uri: git@github.com:team/repo1.git
privateKey: ....
-
type: git
uri: git@github.com:team/repo2.git
privateKey: ....
Currently there is an issue with this approach, see #976 but I think it is better to use the Composite method rather than complicating the existing SSH key handling
Comment From: Winnie2018
Hi @babyblue94520 , have you succeeded using only one ssh key to access github?
Comment From: babyblue94520
Yes,but this is not suitable for discussion.
Comment From: ryanjbaxter
Please reopen if this is still an issue.
Comment From: blackandcold
This is still not possible and GitHub Enterprise does not allow to add the same key to multiple repositories. Please reopen.
Scenario: - config A in repository A - config B in repository B - some general stuff in C
All on the same domain but in different repositories with different keys forced by GitHub. It is no alternative to use username and password for this problem and different hosts... you know.
So the key of the map should be the full repository URL and somehow mapped like @ojhughes suggested.
Comment From: spencergibb
Did you see that he also suggested it could be done with composite configuration https://github.com/spring-cloud/spring-cloud-config/issues/938#issuecomment-381148362?
Comment From: blackandcold
Did you see that he also suggested it could be done with composite configuration #938 (comment)?
Hi, no it can't be done with a composite repository. This would mix different types of base application configuration explicitly placed in another repository.
example: Group A has access to DB Group B has no access
Composite would provide the "no DB access" applications with default DB connection settings - which is not intended.
We run only one service (load balanced instances) providing configuration for all applications.
We need this fixed. I can open a new issue or provide a pull request if necessary.
Thanks!
Comment From: spencergibb
PRs welcome