Skip to content

Commit 9765d8f

Browse files
authored
Merge pull request #122 from PizzaFactory/prp-update-to-the-upstream
[Scheduled] Update to the upstream
2 parents b0baccc + e009b6b commit 9765d8f

File tree

17 files changed

+981
-6
lines changed

17 files changed

+981
-6
lines changed

infrastructures/kubernetes/pom.xml

+4
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@
125125
<groupId>org.eclipse.che.core</groupId>
126126
<artifactId>che-core-api-dto</artifactId>
127127
</dependency>
128+
<dependency>
129+
<groupId>org.eclipse.che.core</groupId>
130+
<artifactId>che-core-api-factory</artifactId>
131+
</dependency>
128132
<dependency>
129133
<groupId>org.eclipse.che.core</groupId>
130134
<artifactId>che-core-api-model</artifactId>

infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/KubernetesInfraModule.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2021 Red Hat, Inc.
2+
* Copyright (c) 2012-2022 Red Hat, Inc.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -49,6 +49,7 @@
4949
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironmentFactory;
5050
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.RemoveNamespaceOnWorkspaceRemove;
5151
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.CredentialsSecretConfigurator;
52+
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.GitconfigUserDataConfigurator;
5253
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.NamespaceConfigurator;
5354
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.PreferencesConfigMapConfigurator;
5455
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.SshKeysConfigurator;
@@ -118,6 +119,7 @@ protected void configure() {
118119
namespaceConfigurators.addBinding().to(UserProfileConfigurator.class);
119120
namespaceConfigurators.addBinding().to(UserPreferencesConfigurator.class);
120121
namespaceConfigurators.addBinding().to(SshKeysConfigurator.class);
122+
namespaceConfigurators.addBinding().to(GitconfigUserDataConfigurator.class);
121123

122124
bind(KubernetesNamespaceService.class);
123125

infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/AbstractWorkspaceServiceAccount.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2021 Red Hat, Inc.
2+
* Copyright (c) 2012-2022 Red Hat, Inc.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -53,6 +53,7 @@ public abstract class AbstractWorkspaceServiceAccount<
5353
public static final String CONFIGMAPS_ROLE_NAME = "workspace-configmaps";
5454
public static final String CREDENTIALS_SECRET_NAME = "workspace-credentials-secret";
5555
public static final String PREFERENCES_CONFIGMAP_NAME = "workspace-preferences-configmap";
56+
public static final String GIT_USERDATA_CONFIGMAP_NAME = "workspace-userdata-gitconfig-configmap";
5657

5758
protected final String namespace;
5859
protected final String serviceAccountName;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) 2012-2022 Red Hat, Inc.
3+
* This program and the accompanying materials are made
4+
* available under the terms of the Eclipse Public License 2.0
5+
* which is available at https://www.eclipse.org/legal/epl-2.0/
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat, Inc. - initial API and implementation
11+
*/
12+
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator;
13+
14+
import static com.google.common.base.Strings.isNullOrEmpty;
15+
import static java.util.Collections.singletonMap;
16+
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.AbstractWorkspaceServiceAccount.GIT_USERDATA_CONFIGMAP_NAME;
17+
18+
import com.google.common.collect.ImmutableMap;
19+
import io.fabric8.kubernetes.api.model.ConfigMap;
20+
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
21+
import java.util.Map;
22+
import java.util.Set;
23+
import javax.inject.Inject;
24+
import org.eclipse.che.api.core.NotFoundException;
25+
import org.eclipse.che.api.core.ServerException;
26+
import org.eclipse.che.api.core.model.user.User;
27+
import org.eclipse.che.api.factory.server.scm.GitUserData;
28+
import org.eclipse.che.api.factory.server.scm.GitUserDataFetcher;
29+
import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException;
30+
import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException;
31+
import org.eclipse.che.api.user.server.UserManager;
32+
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
33+
import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext;
34+
import org.eclipse.che.commons.env.EnvironmentContext;
35+
import org.eclipse.che.commons.subject.Subject;
36+
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory;
37+
import org.slf4j.Logger;
38+
import org.slf4j.LoggerFactory;
39+
40+
public class GitconfigUserDataConfigurator implements NamespaceConfigurator {
41+
private static final Logger LOG = LoggerFactory.getLogger(GitconfigUserDataConfigurator.class);
42+
private final KubernetesClientFactory clientFactory;
43+
private final Set<GitUserDataFetcher> gitUserDataFetchers;
44+
private static final String CONFIGMAP_DATA_KEY = "gitconfig";
45+
private final UserManager userManager;
46+
47+
@Inject
48+
public GitconfigUserDataConfigurator(
49+
KubernetesClientFactory clientFactory,
50+
Set<GitUserDataFetcher> gitUserDataFetchers,
51+
UserManager userManager) {
52+
this.clientFactory = clientFactory;
53+
this.gitUserDataFetchers = gitUserDataFetchers;
54+
this.userManager = userManager;
55+
}
56+
57+
@Override
58+
public void configure(NamespaceResolutionContext namespaceResolutionContext, String namespaceName)
59+
throws InfrastructureException {
60+
var client = clientFactory.create();
61+
GitUserData gitUserData = null;
62+
for (GitUserDataFetcher fetcher : gitUserDataFetchers) {
63+
try {
64+
gitUserData = fetcher.fetchGitUserData();
65+
break;
66+
} catch (ScmUnauthorizedException | ScmCommunicationException e) {
67+
LOG.debug("No GitUserDataFetcher is configured. " + e.getMessage());
68+
}
69+
}
70+
71+
Map<String, String> annotations =
72+
ImmutableMap.of(
73+
"controller.devfile.io/mount-as",
74+
"subpath",
75+
"controller.devfile.io/mount-path",
76+
"/etc/");
77+
Map<String, String> labels =
78+
ImmutableMap.of(
79+
"controller.devfile.io/mount-to-devworkspace",
80+
"true",
81+
"controller.devfile.io/watch-configmap",
82+
"true");
83+
if (gitUserData == null) {
84+
Subject cheSubject = EnvironmentContext.getCurrent().getSubject();
85+
try {
86+
User user = userManager.getById(cheSubject.getUserId());
87+
if (!isNullOrEmpty(user.getName()) && !isNullOrEmpty(user.getEmail())) {
88+
gitUserData = new GitUserData(user.getName(), user.getEmail());
89+
}
90+
} catch (NotFoundException | ServerException e) {
91+
LOG.error(e.getMessage());
92+
}
93+
}
94+
if (gitUserData != null
95+
&& client
96+
.configMaps()
97+
.inNamespace(namespaceName)
98+
.withName(GIT_USERDATA_CONFIGMAP_NAME)
99+
.get()
100+
== null
101+
&& client
102+
.configMaps()
103+
.inNamespace(namespaceName)
104+
.withLabels(labels)
105+
.list()
106+
.getItems()
107+
.stream()
108+
.filter(configMap -> configMap.getMetadata().getAnnotations() != null)
109+
.noneMatch(
110+
configMap ->
111+
configMap
112+
.getMetadata()
113+
.getAnnotations()
114+
.entrySet()
115+
.containsAll(annotations.entrySet())
116+
&& configMap.getData().containsKey(CONFIGMAP_DATA_KEY))) {
117+
ConfigMap configMap =
118+
new ConfigMapBuilder()
119+
.withNewMetadata()
120+
.withName(GIT_USERDATA_CONFIGMAP_NAME)
121+
.withLabels(labels)
122+
.withAnnotations(annotations)
123+
.endMetadata()
124+
.build();
125+
configMap.setData(
126+
singletonMap(
127+
CONFIGMAP_DATA_KEY,
128+
String.format(
129+
"[user]\n\tname = %1$s\n\temail = %2$s",
130+
gitUserData.getScmUsername(), gitUserData.getScmUserEmail())));
131+
client.configMaps().inNamespace(namespaceName).create(configMap);
132+
}
133+
}
134+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*
2+
* Copyright (c) 2012-2022 Red Hat, Inc.
3+
* This program and the accompanying materials are made
4+
* available under the terms of the Eclipse Public License 2.0
5+
* which is available at https://www.eclipse.org/legal/epl-2.0/
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat, Inc. - initial API and implementation
11+
*/
12+
package org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator;
13+
14+
import static org.eclipse.che.workspace.infrastructure.kubernetes.namespace.AbstractWorkspaceServiceAccount.GIT_USERDATA_CONFIGMAP_NAME;
15+
import static org.mockito.ArgumentMatchers.anyString;
16+
import static org.mockito.Mockito.mock;
17+
import static org.mockito.Mockito.spy;
18+
import static org.mockito.Mockito.when;
19+
20+
import com.google.common.collect.ImmutableMap;
21+
import io.fabric8.kubernetes.api.model.ConfigMap;
22+
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
23+
import io.fabric8.kubernetes.client.KubernetesClient;
24+
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
25+
import java.util.Collections;
26+
import java.util.Map;
27+
import java.util.Set;
28+
import org.eclipse.che.api.core.NotFoundException;
29+
import org.eclipse.che.api.core.ServerException;
30+
import org.eclipse.che.api.core.model.user.User;
31+
import org.eclipse.che.api.factory.server.scm.GitUserData;
32+
import org.eclipse.che.api.factory.server.scm.GitUserDataFetcher;
33+
import org.eclipse.che.api.factory.server.scm.exception.ScmCommunicationException;
34+
import org.eclipse.che.api.factory.server.scm.exception.ScmUnauthorizedException;
35+
import org.eclipse.che.api.user.server.UserManager;
36+
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
37+
import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext;
38+
import org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesClientFactory;
39+
import org.mockito.Mock;
40+
import org.mockito.testng.MockitoTestNGListener;
41+
import org.testng.Assert;
42+
import org.testng.annotations.BeforeMethod;
43+
import org.testng.annotations.Listeners;
44+
import org.testng.annotations.Test;
45+
46+
@Listeners(MockitoTestNGListener.class)
47+
public class GitconfigUserdataConfiguratorTest {
48+
49+
private NamespaceConfigurator configurator;
50+
51+
@Mock private KubernetesClientFactory clientFactory;
52+
@Mock private GitUserDataFetcher gitUserDataFetcher;
53+
@Mock private UserManager userManager;
54+
private KubernetesServer serverMock;
55+
56+
private NamespaceResolutionContext namespaceResolutionContext;
57+
private final String TEST_NAMESPACE_NAME = "namespace123";
58+
private final String TEST_WORKSPACE_ID = "workspace123";
59+
private final String TEST_USER_ID = "user123";
60+
private final String TEST_USERNAME = "jondoe";
61+
62+
@BeforeMethod
63+
public void setUp()
64+
throws InfrastructureException, ScmCommunicationException, ScmUnauthorizedException {
65+
configurator =
66+
new GitconfigUserDataConfigurator(clientFactory, Set.of(gitUserDataFetcher), userManager);
67+
68+
serverMock = new KubernetesServer(true, true);
69+
serverMock.before();
70+
KubernetesClient client = spy(serverMock.getClient());
71+
when(clientFactory.create()).thenReturn(client);
72+
73+
namespaceResolutionContext =
74+
new NamespaceResolutionContext(TEST_WORKSPACE_ID, TEST_USER_ID, TEST_USERNAME);
75+
}
76+
77+
@Test
78+
public void createUserdataConfigmapWhenDoesNotExist()
79+
throws ScmCommunicationException, ScmUnauthorizedException, InfrastructureException,
80+
InterruptedException {
81+
// given
82+
when(gitUserDataFetcher.fetchGitUserData()).thenReturn(new GitUserData("gitUser", "gitEmail"));
83+
84+
// when
85+
configurator.configure(namespaceResolutionContext, TEST_NAMESPACE_NAME);
86+
87+
// then create a secret
88+
Assert.assertEquals(serverMock.getLastRequest().getMethod(), "POST");
89+
Assert.assertNotNull(
90+
serverMock
91+
.getClient()
92+
.configMaps()
93+
.inNamespace(TEST_NAMESPACE_NAME)
94+
.withName(GIT_USERDATA_CONFIGMAP_NAME)
95+
.get());
96+
}
97+
98+
@Test
99+
public void doNothingWhenGitUserDataAndCheUserAreNull()
100+
throws InfrastructureException, ServerException, NotFoundException {
101+
// when
102+
when(userManager.getById(anyString())).thenThrow(new NotFoundException("not found"));
103+
configurator.configure(namespaceResolutionContext, TEST_NAMESPACE_NAME);
104+
105+
// then - don't create the configmap
106+
var configMaps =
107+
serverMock.getClient().configMaps().inNamespace(TEST_NAMESPACE_NAME).list().getItems();
108+
Assert.assertEquals(configMaps.size(), 0);
109+
}
110+
111+
@Test
112+
public void doNothingWhenSecretAlreadyExists()
113+
throws InfrastructureException, InterruptedException, ScmCommunicationException,
114+
ScmUnauthorizedException {
115+
// given
116+
when(gitUserDataFetcher.fetchGitUserData()).thenReturn(new GitUserData("gitUser", "gitEmail"));
117+
Map<String, String> annotations =
118+
ImmutableMap.of(
119+
"controller.devfile.io/mount-as",
120+
"subpath",
121+
"controller.devfile.io/mount-path",
122+
"/etc/",
123+
"already",
124+
"created");
125+
Map<String, String> labels =
126+
ImmutableMap.of(
127+
"controller.devfile.io/mount-to-devworkspace",
128+
"true",
129+
"controller.devfile.io/watch-configmap",
130+
"true",
131+
"already",
132+
"created");
133+
ConfigMap configMap =
134+
new ConfigMapBuilder()
135+
.withNewMetadata()
136+
.withName(GIT_USERDATA_CONFIGMAP_NAME)
137+
.withLabels(labels)
138+
.withAnnotations(annotations)
139+
.endMetadata()
140+
.build();
141+
configMap.setData(Collections.singletonMap("gitconfig", "empty"));
142+
serverMock.getClient().configMaps().inNamespace(TEST_NAMESPACE_NAME).create(configMap);
143+
144+
// when
145+
configurator.configure(namespaceResolutionContext, TEST_NAMESPACE_NAME);
146+
147+
// then - don't create the configmap
148+
Assert.assertEquals(serverMock.getLastRequest().getMethod(), "GET");
149+
var configMaps =
150+
serverMock.getClient().configMaps().inNamespace(TEST_NAMESPACE_NAME).list().getItems();
151+
Assert.assertEquals(configMaps.size(), 1);
152+
Assert.assertEquals(configMaps.get(0).getMetadata().getAnnotations().get("already"), "created");
153+
}
154+
155+
@Test
156+
public void createUserdataConfigmapFromCheUserData()
157+
throws InfrastructureException, ServerException, NotFoundException, InterruptedException {
158+
// given
159+
User user = mock(User.class);
160+
when(user.getName()).thenReturn("test name");
161+
when(user.getEmail()).thenReturn("[email protected]");
162+
when(userManager.getById(anyString())).thenReturn(user);
163+
164+
// when
165+
configurator.configure(namespaceResolutionContext, TEST_NAMESPACE_NAME);
166+
167+
// then create a secret
168+
Assert.assertEquals(serverMock.getLastRequest().getMethod(), "POST");
169+
ConfigMap configMap =
170+
serverMock
171+
.getClient()
172+
.configMaps()
173+
.inNamespace(TEST_NAMESPACE_NAME)
174+
.withName(GIT_USERDATA_CONFIGMAP_NAME)
175+
.get();
176+
Assert.assertNotNull(configMap);
177+
Assert.assertTrue(configMap.getData().get("gitconfig").contains("test name"));
178+
Assert.assertTrue(configMap.getData().get("gitconfig").contains("[email protected]"));
179+
}
180+
}

infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfraModule.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2021 Red Hat, Inc.
2+
* Copyright (c) 2012-2022 Red Hat, Inc.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -54,6 +54,7 @@
5454
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironmentFactory;
5555
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory;
5656
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.CredentialsSecretConfigurator;
57+
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.GitconfigUserDataConfigurator;
5758
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.NamespaceConfigurator;
5859
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.PreferencesConfigMapConfigurator;
5960
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.SshKeysConfigurator;
@@ -127,6 +128,7 @@ protected void configure() {
127128
namespaceConfigurators.addBinding().to(OpenShiftWorkspaceServiceAccountConfigurator.class);
128129
namespaceConfigurators.addBinding().to(OpenShiftStopWorkspaceRoleConfigurator.class);
129130
namespaceConfigurators.addBinding().to(SshKeysConfigurator.class);
131+
namespaceConfigurators.addBinding().to(GitconfigUserDataConfigurator.class);
130132

131133
bind(KubernetesNamespaceService.class);
132134

0 commit comments

Comments
 (0)