Skip to content

Commit

Permalink
Also copy the content of the truststore config map to the workspace n…
Browse files Browse the repository at this point in the history
…amespace
  • Loading branch information
mshaposhnik committed Nov 5, 2020
1 parent 4feb4bf commit 6c03073
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@
import static com.google.common.base.Strings.isNullOrEmpty;

import com.google.common.base.Splitter;
import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.kubernetes.api.model.VolumeBuilder;
import io.fabric8.kubernetes.api.model.VolumeMountBuilder;
import java.util.Map;
import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.workspace.infrastructure.kubernetes.CheServerKubernetesClientFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.CheInstallationLocation;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment.PodData;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment.PodRole;
Expand All @@ -43,19 +47,28 @@ public class Openshift4TrustedCAProvisioner {

private final String certificateMountPath;
private final boolean trustedStoreInitialized;
private final String caBundleConfigMap;
private final String configMapName;
private final Map<String, String> configMapLabelKeyValue;
private final CheServerKubernetesClientFactory cheServerClientFactory;
private final String installationLocationNamespace;

@Inject
public Openshift4TrustedCAProvisioner(
@Nullable @Named("che.trusted_ca_bundles_configmap") String caBundleConfigMap,
@Named("che.infra.openshift.trusted_ca_bundles_config_map") String configMapName,
@Named("che.infra.openshift.trusted_ca_bundles_config_map_labels") String configMapLabel,
@Named("che.infra.openshift.trusted_ca_bundles_mount_path") String certificateMountPath) {
@Named("che.infra.openshift.trusted_ca_bundles_mount_path") String certificateMountPath,
CheInstallationLocation cheInstallationLocation,
CheServerKubernetesClientFactory cheServerClientFactory)
throws InfrastructureException {
this.cheServerClientFactory = cheServerClientFactory;
this.trustedStoreInitialized = !isNullOrEmpty(caBundleConfigMap);
this.configMapName = configMapName;
this.caBundleConfigMap = caBundleConfigMap;
this.certificateMountPath = certificateMountPath;
this.configMapLabelKeyValue = Splitter.on(",").withKeyValueSeparator("=").split(configMapLabel);
this.installationLocationNamespace = cheInstallationLocation.getInstallationLocationNamespace();
}

public boolean isTrustedStoreInitialized() {
Expand All @@ -67,9 +80,22 @@ public void provision(KubernetesEnvironment k8sEnv, OpenShiftProject project)
if (!trustedStoreInitialized) {
return;
}
ConfigMap configMap =
cheServerClientFactory
.create()
.configMaps()
.inNamespace(installationLocationNamespace)
.withName(caBundleConfigMap)
.get();

if (configMap == null) {
return;
}

Optional<ConfigMap> existing = project.configMaps().get(configMapName);

if (!project.configMaps().get(configMapName).isPresent()) {
// create new map
if (!existing.isPresent() || !existing.get().getData().equals(configMap.getData())) {
// create or renew map
k8sEnv
.getConfigMaps()
.put(
Expand All @@ -78,10 +104,14 @@ public void provision(KubernetesEnvironment k8sEnv, OpenShiftProject project)
.withMetadata(
new ObjectMetaBuilder()
.withName(configMapName)
.withAnnotations(configMap.getMetadata().getAnnotations())
.withLabels(configMapLabelKeyValue)
.build())
.withApiVersion(configMap.getApiVersion())
.withData(configMap.getData())
.build());
}

for (PodData pod : k8sEnv.getPodsData().values()) {
if (pod.getRole() == PodRole.DEPLOYMENT) {
if (pod.getSpec()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,34 @@
package org.eclipse.che.workspace.infrastructure.openshift.provision;

import static com.google.common.collect.ImmutableMap.of;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

import com.google.common.collect.ImmutableMap;
import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.api.model.ConfigMapList;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.DoneableConfigMap;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodBuilder;
import io.fabric8.kubernetes.api.model.PodSpec;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.openshift.client.OpenShiftClient;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.che.workspace.infrastructure.kubernetes.CheServerKubernetesClientFactory;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.CheInstallationLocation;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment;
import org.eclipse.che.workspace.infrastructure.kubernetes.environment.KubernetesEnvironment.PodData;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesConfigsMaps;
import org.eclipse.che.workspace.infrastructure.openshift.OpenShiftClientFactory;
import org.eclipse.che.workspace.infrastructure.openshift.project.OpenShiftProject;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
Expand All @@ -48,12 +56,41 @@ public class Openshift4TrustedCAProvisionerTest {
private static final String CERTIFICATE_MOUNT_PATH = "/certs";
private static final String CONFIGMAP_KEY = "testConfigMapKey";
private static final String CONFIGMAP_VALUE = "testConfigMapValue";
private static final String CHE_SERVER_NAMESPACE = "testCheServerNamespace";
private static final String INJECTED_CA_BUNDLE_KEY = "ca-bundle.crt";
private static final String INJECTED_CA_BUNDLE_VALUE = "ca-bundle.crt.content";
private static final String MANUAL_CA_BUNDLE_KEY = "manual-ca.crt";
private static final String MANUAL_CA_BUNDLE_VALUE = "maunal-ca.crt.content";

@Mock OpenShiftClientFactory clientFactory;
@Mock CheServerKubernetesClientFactory clientFactory;

@Mock private KubernetesEnvironment k8sEnv;
@Mock private OpenShiftProject openShiftProject;
@Mock private KubernetesConfigsMaps kubernetesConfigsMaps;
@Mock private CheInstallationLocation cheInstallationLocation;

@Mock
private MixedOperation<
ConfigMap, ConfigMapList, DoneableConfigMap, Resource<ConfigMap, DoneableConfigMap>>
cheServerConfigMapGetter1;

@Mock
private NonNamespaceOperation<
ConfigMap, ConfigMapList, DoneableConfigMap, Resource<ConfigMap, DoneableConfigMap>>
cheServerConfigMapGetter2;

@Mock private Resource<ConfigMap, DoneableConfigMap> cheServerConfigMapResource;
@Mock private ConfigMap cheServerConfigMap;
@Mock private ObjectMeta cheServerConfigMapMetadata;

private Map<String, String> cheServerConfigMapData =
ImmutableMap.of(
INJECTED_CA_BUNDLE_KEY, INJECTED_CA_BUNDLE_VALUE,
MANUAL_CA_BUNDLE_KEY, MANUAL_CA_BUNDLE_VALUE);

private Map<String, String> cheServerConfigMapAnnotations =
ImmutableMap.of(
"testCheServerConfigMapAnnotationsKey", "testCheServerConfigMapAnnotationsValue");

@Mock private OpenShiftClient k8sClient;

Expand All @@ -63,35 +100,68 @@ public class Openshift4TrustedCAProvisionerTest {

@BeforeMethod
public void setup() throws Exception {
lenient().when(clientFactory.createOC()).thenReturn(k8sClient);
lenient().when(clientFactory.create()).thenReturn(k8sClient);
lenient().when(openShiftProject.configMaps()).thenReturn(kubernetesConfigsMaps);
lenient()
.when(cheInstallationLocation.getInstallationLocationNamespace())
.thenReturn(CHE_SERVER_NAMESPACE);
lenient().when(k8sEnv.getConfigMaps()).thenReturn(envConfigMaps);
lenient().when(k8sClient.configMaps()).thenReturn(cheServerConfigMapGetter1);
lenient()
.when(cheServerConfigMapGetter1.inNamespace(CHE_SERVER_NAMESPACE))
.thenReturn(cheServerConfigMapGetter2);
lenient()
.when(cheServerConfigMapGetter2.withName(anyString()))
.thenReturn(cheServerConfigMapResource);
lenient().when(cheServerConfigMap.getData()).thenReturn(cheServerConfigMapData);
lenient().when(cheServerConfigMap.getMetadata()).thenReturn(cheServerConfigMapMetadata);
lenient()
.when(cheServerConfigMapMetadata.getAnnotations())
.thenReturn(cheServerConfigMapAnnotations);

this.trustedCAProvisioner =
new Openshift4TrustedCAProvisioner(
CONFIGMAP_NAME, CONFIGMAP_NAME, CONFIGMAP_LABELS, CERTIFICATE_MOUNT_PATH);
CONFIGMAP_NAME,
CONFIGMAP_NAME,
CONFIGMAP_LABELS,
CERTIFICATE_MOUNT_PATH,
cheInstallationLocation,
clientFactory);
}

@Test
public void shouldDoNothingIfCAStoreIsNotInitialized() throws Exception {
Openshift4TrustedCAProvisioner localProvisioner =
new Openshift4TrustedCAProvisioner(
null, CONFIGMAP_NAME, CONFIGMAP_LABELS, CERTIFICATE_MOUNT_PATH);
null,
CONFIGMAP_NAME,
CONFIGMAP_LABELS,
CERTIFICATE_MOUNT_PATH,
cheInstallationLocation,
clientFactory);

localProvisioner.provision(k8sEnv, openShiftProject);
verifyZeroInteractions(k8sEnv, openShiftProject, clientFactory, openShiftProject);
verifyZeroInteractions(
k8sEnv, openShiftProject, clientFactory, openShiftProject, clientFactory);
}

@Test
public void shouldProvisionTrustStoreMapAndMountIt() throws Exception {
Pod pod = newPod();
PodData podData = new PodData(pod.getSpec(), pod.getMetadata());
doReturn(of(POD_NAME, podData)).when(k8sEnv).getPodsData();
lenient().when(cheServerConfigMapResource.get()).thenReturn(cheServerConfigMap);

trustedCAProvisioner.provision(k8sEnv, openShiftProject);

assertEquals(envConfigMaps.size(), 1);
assertTrue(envConfigMaps.get(CONFIGMAP_NAME).getMetadata().getLabels().containsKey("foo"));
assertEquals(envConfigMaps.get(CONFIGMAP_NAME).getMetadata().getLabels().get("foo"), "bar");
assertEquals(
envConfigMaps.get(CONFIGMAP_NAME).getMetadata().getAnnotations(),
cheServerConfigMapAnnotations);
assertEquals(envConfigMaps.get(CONFIGMAP_NAME).getData(), cheServerConfigMapData);

PodSpec podSpec = pod.getSpec();
assertEquals(podSpec.getVolumes().size(), 1);
assertEquals(podSpec.getVolumes().get(0).getConfigMap().getName(), CONFIGMAP_NAME);
Expand All @@ -111,14 +181,4 @@ private static Pod newPod() {
.endSpec()
.build();
}

private static ConfigMap newConfigMap() {
return new ConfigMapBuilder()
.withNewMetadata()
.withName(CONFIGMAP_NAME)
.withLabels(of("foo", "bar"))
.endMetadata()
.withData(of(CONFIGMAP_KEY, CONFIGMAP_VALUE))
.build();
}
}

0 comments on commit 6c03073

Please sign in to comment.