Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set wildcard '*' host name if key name start from 'default-' according to the the https://github.com/eclipse/che/issues/13494#issuecomment-512761661 #13901

Merged
merged 4 commits into from
Jul 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public void provision(KubernetesEnvironment k8sEnv, RuntimeIdentity identity)
StringBuilder sshConfigData = new StringBuilder();

for (SshPair sshPair : sshPairs) {
doProvisionSshKey(sshPair, k8sEnv);
doProvisionSshKey(sshPair, k8sEnv, identity.getWorkspaceId());

sshConfigData.append(buildConfig(sshPair.getName()));
}
Expand All @@ -116,7 +116,7 @@ public void provision(KubernetesEnvironment k8sEnv, RuntimeIdentity identity)
}
}

private void doProvisionSshKey(SshPair sshPair, KubernetesEnvironment k8sEnv) {
private void doProvisionSshKey(SshPair sshPair, KubernetesEnvironment k8sEnv, String wsId) {
if (isNullOrEmpty(sshPair.getName()) || isNullOrEmpty(sshPair.getPrivateKey())) {
return;
}
Expand All @@ -127,7 +127,7 @@ private void doProvisionSshKey(SshPair sshPair, KubernetesEnvironment k8sEnv) {
Base64.getEncoder().encodeToString(sshPair.getPrivateKey().getBytes()))
.withType(SECRET_TYPE_SSH)
.withNewMetadata()
.withName(getValidNameForSecret(sshPair.getName()))
.withName(wsId + "-" + getValidNameForSecret(sshPair.getName()))
.endMetadata()
.build();

Expand All @@ -136,10 +136,11 @@ private void doProvisionSshKey(SshPair sshPair, KubernetesEnvironment k8sEnv) {
k8sEnv
.getPodsData()
.values()
.forEach(p -> mountSshKeySecret(secret.getMetadata().getName(), p.getSpec()));
.forEach(
p -> mountSshKeySecret(secret.getMetadata().getName(), sshPair.getName(), p.getSpec()));
}

private void mountSshKeySecret(String secretName, PodSpec podSpec) {
private void mountSshKeySecret(String secretName, String sshKeyName, PodSpec podSpec) {
podSpec
.getVolumes()
.add(
Expand All @@ -155,7 +156,7 @@ private void mountSshKeySecret(String secretName, PodSpec podSpec) {
.withName(secretName)
.withNewReadOnly(false)
.withReadOnly(false)
.withMountPath(SSH_BASE_CONFIG_PATH + secretName)
.withMountPath(SSH_BASE_CONFIG_PATH + sshKeyName)
.build();
container.getVolumeMounts().add(volumeMount);
});
Expand Down Expand Up @@ -210,22 +211,32 @@ private void mountConfigFile(PodSpec podSpec, String sshConfigMapName) {
*
* <pre>
* host github.com
* HostName github.com
* IdentityFile /etc/ssh/github-com/ssh-privatekey
* </pre>
*
* @param host the host of version control service (e.g. github.com, gitlab.com and etc)
* or
*
* <pre>
* host *
* IdentityFile /etc/ssh/default-123456/ssh-privatekey
* </pre>
*
* @param name the of key given during generate for vcs service we will consider it as host of
* version control service (e.g. github.com, gitlab.com and etc) if name starts from
* "default-{anyString}" it will be replaced on wildcard "*" host name. Name with format
* "default-{anyString}" will be generated on client side by Theia SSH Plugin, if user doesn't
* provide own name. Details see here:
* https://github.com/eclipse/che/issues/13494#issuecomment-512761661. Note: behavior can be
* improved in 7.x releases after 7.0.0
* @return the ssh configuration which include host and identity file location
*/
private String buildConfig(@NotNull String host) {
private String buildConfig(@NotNull String name) {
String host = name.startsWith("default-") ? "*" : name;
return "host "
+ host
+ "\n"
+ "HostName "
+ host
+ "\nIdentityFile "
+ SSH_BASE_CONFIG_PATH
+ getValidNameForSecret(host)
+ getValidNameForSecret(name)
+ "/"
+ SSH_PRIVATE_KEY
+ "\n";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,22 @@ public void doNotDoAnythingIfNoSshKeys() throws Exception {

@Test
public void addSshKeysConfigInPod() throws Exception {
String keyName = UUID.randomUUID().toString();
String keyName1 = UUID.randomUUID().toString();
String keyName2 = "default-" + UUID.randomUUID().toString();
String keyName3 = "github.com";
when(sshManager.getPairs(someUser, "vcs"))
.thenReturn(
ImmutableList.of(new SshPairImpl(someUser, "vcs", keyName, "public", "private")));
ImmutableList.of(
new SshPairImpl(someUser, "vcs", keyName1, "public", "private"),
new SshPairImpl(someUser, "vcs", keyName2, "public", "private"),
new SshPairImpl(someUser, "vcs", keyName3, "public", "private")));

vcsSshKeysProvisioner.provision(k8sEnv, runtimeIdentity);

verify(podSpec, times(2)).getVolumes();
verify(podSpec, times(2)).getContainers();
verify(podSpec, times(4)).getVolumes();
verify(podSpec, times(4)).getContainers();

Secret secret = k8sEnv.getSecrets().get(keyName);
Secret secret = k8sEnv.getSecrets().get("wksp-" + keyName1);
assertNotNull(secret);
assertEquals(secret.getType(), "kubernetes.io/ssh-auth");

Expand All @@ -113,8 +118,13 @@ public void addSshKeysConfigInPod() throws Exception {
assertTrue(mapData.containsKey("ssh_config"));

String sshConfig = mapData.get("ssh_config");
assertTrue(sshConfig.contains("host " + keyName));
assertTrue(sshConfig.contains("HostName " + keyName));
assertTrue(sshConfig.contains("IdentityFile " + "/etc/ssh/" + keyName + "/ssh-privatekey"));
assertTrue(sshConfig.contains("host " + keyName1));
assertTrue(sshConfig.contains("IdentityFile " + "/etc/ssh/" + keyName1 + "/ssh-privatekey"));

assertTrue(sshConfig.contains("host *"));
assertTrue(sshConfig.contains("IdentityFile " + "/etc/ssh/" + keyName2 + "/ssh-privatekey"));

assertTrue(sshConfig.contains("host github.com"));
assertTrue(sshConfig.contains("IdentityFile /etc/ssh/github-com/ssh-privatekey"));
}
}