From d43901a83a393ea9fc9c00130edac4ac91a743a0 Mon Sep 17 00:00:00 2001 From: Anton Korneta Date: Tue, 19 Sep 2017 14:03:28 +0300 Subject: [PATCH] Add prefix into names of OpenShift objects --- infrastructures/openshift/pom.xml | 4 + .../OpenShiftInfrastructureProvisioner.java | 7 +- .../openshift/OpenShiftInternalRuntime.java | 8 +- .../openshift/OpenShiftMachine.java | 5 +- .../provision/UniqueNamesProvisioner.java | 63 +++++++++++ ...penShiftInfrastructureProvisionerTest.java | 10 +- .../OpenShiftInternalRuntimeTest.java | 7 +- .../provision/UniqueNamesProvisionerTest.java | 106 ++++++++++++++++++ 8 files changed, 202 insertions(+), 8 deletions(-) create mode 100644 infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/UniqueNamesProvisioner.java create mode 100644 infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/provision/UniqueNamesProvisionerTest.java diff --git a/infrastructures/openshift/pom.xml b/infrastructures/openshift/pom.xml index 6254fabb9b..a940726704 100644 --- a/infrastructures/openshift/pom.xml +++ b/infrastructures/openshift/pom.xml @@ -90,6 +90,10 @@ org.eclipse.che.core che-core-api-workspace-shared + + org.eclipse.che.core + che-core-commons-lang + org.slf4j slf4j-api diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfrastructureProvisioner.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfrastructureProvisioner.java index 43aa0f94e5..333725285f 100644 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfrastructureProvisioner.java +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfrastructureProvisioner.java @@ -16,6 +16,7 @@ import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.api.workspace.server.spi.InfrastructureException; import org.eclipse.che.api.workspace.server.spi.InternalEnvironment; import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment; +import org.eclipse.che.workspace.infrastructure.openshift.provision.UniqueNamesProvisioner; import org.eclipse.che.workspace.infrastructure.openshift.provision.installer.InstallerConfigProvisioner; import org.eclipse.che.workspace.infrastructure.openshift.provision.volume.PersistentVolumeClaimProvisioner; @@ -30,13 +31,16 @@ public class OpenShiftInfrastructureProvisioner { private final InstallerConfigProvisioner installerConfigProvisioner; private final PersistentVolumeClaimProvisioner persistentVolumeClaimProvisioner; + private final UniqueNamesProvisioner uniqueNamesProvisioner; @Inject public OpenShiftInfrastructureProvisioner( InstallerConfigProvisioner installerConfigProvisioner, - PersistentVolumeClaimProvisioner projectVolumeProvisioner) { + PersistentVolumeClaimProvisioner projectVolumeProvisioner, + UniqueNamesProvisioner uniqueNamesProvisioner) { this.installerConfigProvisioner = installerConfigProvisioner; this.persistentVolumeClaimProvisioner = projectVolumeProvisioner; + this.uniqueNamesProvisioner = uniqueNamesProvisioner; } public void provision( @@ -44,5 +48,6 @@ public class OpenShiftInfrastructureProvisioner { throws InfrastructureException { installerConfigProvisioner.provision(environment, osEnv, identity); persistentVolumeClaimProvisioner.provision(environment, osEnv, identity); + uniqueNamesProvisioner.provision(environment, osEnv, identity); } } diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntime.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntime.java index bff7cded74..1259dd2afe 100644 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntime.java +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntime.java @@ -13,10 +13,12 @@ package org.eclipse.che.workspace.infrastructure.openshift; import static java.lang.String.format; import static java.util.Collections.emptyMap; import static java.util.stream.Collectors.toSet; +import static org.eclipse.che.workspace.infrastructure.openshift.provision.UniqueNamesProvisioner.CHE_ORIGINAL_NAME_LABEL; import com.google.common.collect.ImmutableMap; import com.google.inject.assistedinject.Assisted; import io.fabric8.kubernetes.api.model.Container; +import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.PersistentVolumeClaim; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.Service; @@ -214,11 +216,13 @@ public class OpenShiftInternalRuntime extends InternalRuntime ref2Server; private final OpenShiftProject project; public OpenShiftMachine( + String machineName, String podName, String containerName, Map ref2Server, OpenShiftProject project) { + this.machineName = machineName; this.podName = podName; this.containerName = containerName; this.ref2Server = new HashMap<>(); @@ -47,7 +50,7 @@ public class OpenShiftMachine implements Machine { } public String getName() { - return podName + "/" + containerName; + return machineName; } @Override diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/UniqueNamesProvisioner.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/UniqueNamesProvisioner.java new file mode 100644 index 0000000000..e4c093a587 --- /dev/null +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/provision/UniqueNamesProvisioner.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.workspace.infrastructure.openshift.provision; + +import io.fabric8.kubernetes.api.model.ObjectMeta; +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.openshift.api.model.Route; +import java.util.HashSet; +import java.util.Set; +import javax.inject.Singleton; +import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; +import org.eclipse.che.api.workspace.server.spi.InfrastructureException; +import org.eclipse.che.api.workspace.server.spi.InternalEnvironment; +import org.eclipse.che.commons.lang.NameGenerator; +import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment; + +/** + * Changes names of OpenShift pods by adding the workspace identifier to the prefix also generates + * OpenShift routes names with prefix 'route' see {@link NameGenerator#generate(String, int)}. + * + * @author Anton Korneta + */ +@Singleton +public class UniqueNamesProvisioner implements ConfigurationProvisioner { + + public static final String CHE_ORIGINAL_NAME_LABEL = "CHE_ORIGINAL_NAME_LABEL"; + public static final String ROUTE_PREFIX = "route"; + public static final int ROUTE_SUFFIX_SIZE = 8; + public static final char SEPARATOR = '.'; + + @Override + public void provision( + InternalEnvironment environment, OpenShiftEnvironment osEnv, RuntimeIdentity identity) + throws InfrastructureException { + final String workspaceId = identity.getWorkspaceId(); + final Set pods = new HashSet<>(osEnv.getPods().values()); + osEnv.getPods().clear(); + for (Pod pod : pods) { + final ObjectMeta podMeta = pod.getMetadata(); + podMeta.getLabels().put(CHE_ORIGINAL_NAME_LABEL, podMeta.getName()); + final String podName = workspaceId + SEPARATOR + podMeta.getName(); + podMeta.setName(podName); + osEnv.getPods().put(podName, pod); + } + final Set routes = new HashSet<>(osEnv.getRoutes().values()); + osEnv.getRoutes().clear(); + for (Route route : routes) { + final ObjectMeta routeMeta = route.getMetadata(); + routeMeta.getLabels().put(CHE_ORIGINAL_NAME_LABEL, routeMeta.getName()); + final String routeName = NameGenerator.generate(ROUTE_PREFIX, ROUTE_SUFFIX_SIZE); + routeMeta.setName(routeName); + osEnv.getRoutes().put(routeName, route); + } + } +} diff --git a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfrastructureProvisionerTest.java b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfrastructureProvisionerTest.java index f8cbbd2ad3..73a8e32625 100644 --- a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfrastructureProvisionerTest.java +++ b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfrastructureProvisionerTest.java @@ -16,6 +16,7 @@ import static org.mockito.Mockito.inOrder; import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; import org.eclipse.che.api.workspace.server.spi.InternalEnvironment; import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment; +import org.eclipse.che.workspace.infrastructure.openshift.provision.UniqueNamesProvisioner; import org.eclipse.che.workspace.infrastructure.openshift.provision.installer.InstallerConfigProvisioner; import org.eclipse.che.workspace.infrastructure.openshift.provision.volume.PersistentVolumeClaimProvisioner; import org.mockito.InOrder; @@ -35,6 +36,7 @@ public class OpenShiftInfrastructureProvisionerTest { @Mock private InstallerConfigProvisioner installerProvisioner; @Mock private PersistentVolumeClaimProvisioner pvcProvisioner; + @Mock private UniqueNamesProvisioner uniqueNamesProvisioner; @Mock private InternalEnvironment environment; @Mock private OpenShiftEnvironment osEnv; @Mock private RuntimeIdentity runtimeIdentity; @@ -46,8 +48,9 @@ public class OpenShiftInfrastructureProvisionerTest { @BeforeMethod public void setUp() { osInfraProvisioner = - new OpenShiftInfrastructureProvisioner(installerProvisioner, pvcProvisioner); - provisionOrder = inOrder(installerProvisioner, pvcProvisioner); + new OpenShiftInfrastructureProvisioner( + installerProvisioner, pvcProvisioner, uniqueNamesProvisioner); + provisionOrder = inOrder(installerProvisioner, pvcProvisioner, uniqueNamesProvisioner); } @Test @@ -60,6 +63,9 @@ public class OpenShiftInfrastructureProvisionerTest { provisionOrder .verify(pvcProvisioner) .provision(eq(environment), eq(osEnv), eq(runtimeIdentity)); + provisionOrder + .verify(uniqueNamesProvisioner) + .provision(eq(environment), eq(osEnv), eq(runtimeIdentity)); provisionOrder.verifyNoMoreInteractions(); } } diff --git a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntimeTest.java b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntimeTest.java index 557705632c..f0e7da1f9f 100644 --- a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntimeTest.java +++ b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInternalRuntimeTest.java @@ -15,6 +15,7 @@ import static java.util.Collections.emptyMap; import static org.eclipse.che.api.core.model.workspace.runtime.MachineStatus.FAILED; import static org.eclipse.che.api.core.model.workspace.runtime.MachineStatus.RUNNING; import static org.eclipse.che.api.core.model.workspace.runtime.MachineStatus.STARTING; +import static org.eclipse.che.workspace.infrastructure.openshift.provision.UniqueNamesProvisioner.CHE_ORIGINAL_NAME_LABEL; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyListOf; import static org.mockito.Mockito.atLeastOnce; @@ -348,7 +349,8 @@ public class OpenShiftInternalRuntimeTest { mockName(POD_NAME, pod); when(spec.getContainers()).thenReturn(containers); when(pod.getSpec()).thenReturn(spec); - when(pod.getMetadata().getLabels()).thenReturn(ImmutableMap.of(POD_SELECTOR, POD_NAME)); + when(pod.getMetadata().getLabels()) + .thenReturn(ImmutableMap.of(POD_SELECTOR, POD_NAME, CHE_ORIGINAL_NAME_LABEL, POD_NAME)); return pod; } @@ -381,7 +383,8 @@ public class OpenShiftInternalRuntimeTest { when(spec.getTo()).thenReturn(target); when(spec.getHost()).thenReturn(ROUTE_HOST); when(route.getSpec()).thenReturn(spec); - + when(route.getMetadata().getLabels()) + .thenReturn(ImmutableMap.of(CHE_ORIGINAL_NAME_LABEL, ROUTE_NAME)); return route; } diff --git a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/provision/UniqueNamesProvisionerTest.java b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/provision/UniqueNamesProvisionerTest.java new file mode 100644 index 0000000000..d5c38e4908 --- /dev/null +++ b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/provision/UniqueNamesProvisionerTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.workspace.infrastructure.openshift.provision; + +import static java.util.stream.Collectors.toList; +import static org.eclipse.che.workspace.infrastructure.openshift.provision.UniqueNamesProvisioner.CHE_ORIGINAL_NAME_LABEL; +import static org.eclipse.che.workspace.infrastructure.openshift.provision.UniqueNamesProvisioner.ROUTE_PREFIX; +import static org.eclipse.che.workspace.infrastructure.openshift.provision.UniqueNamesProvisioner.ROUTE_SUFFIX_SIZE; +import static org.eclipse.che.workspace.infrastructure.openshift.provision.UniqueNamesProvisioner.SEPARATOR; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +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.openshift.api.model.Route; +import io.fabric8.openshift.api.model.RouteBuilder; +import java.util.HashMap; +import java.util.regex.Pattern; +import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity; +import org.eclipse.che.api.workspace.server.spi.InternalEnvironment; +import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment; +import org.mockito.Mock; +import org.mockito.testng.MockitoTestNGListener; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +/** + * Tests {@link UniqueNamesProvisioner}. + * + * @author Anton Korneta + */ +@Listeners(MockitoTestNGListener.class) +public class UniqueNamesProvisionerTest { + + private static final String WORKSPACE_ID = "workspace37"; + private static final String POD_NAME = "testPod"; + private static final String ROUTE_NAME = "testRoute"; + private static final Pattern UNIQUE_ROUTE_NAME_REGEX = + Pattern.compile('^' + ROUTE_PREFIX + "[A-z0-9]{" + ROUTE_SUFFIX_SIZE + "}$"); + + @Mock private InternalEnvironment environment; + @Mock private OpenShiftEnvironment osEnv; + @Mock private RuntimeIdentity runtimeIdentity; + + private UniqueNamesProvisioner uniqueNamesProvisioner; + + @BeforeMethod + public void setup() { + uniqueNamesProvisioner = new UniqueNamesProvisioner(); + } + + @Test + public void provideUniquePodsNames() throws Exception { + when(runtimeIdentity.getWorkspaceId()).thenReturn(WORKSPACE_ID); + final HashMap pods = new HashMap<>(); + pods.put(POD_NAME, newPod()); + doReturn(pods).when(osEnv).getPods(); + + uniqueNamesProvisioner.provision(environment, osEnv, runtimeIdentity); + + final String expected = WORKSPACE_ID + SEPARATOR + POD_NAME; + final ObjectMeta podMeta = osEnv.getPods().get(expected).getMetadata(); + assertEquals(podMeta.getName(), expected); + assertEquals(podMeta.getLabels().get(CHE_ORIGINAL_NAME_LABEL), POD_NAME); + } + + @Test + public void provideUniqueRoutesNames() throws Exception { + final HashMap routes = new HashMap<>(); + routes.put(POD_NAME, newRoute()); + doReturn(routes).when(osEnv).getRoutes(); + + uniqueNamesProvisioner.provision(environment, osEnv, runtimeIdentity); + + final ObjectMeta routeData = + osEnv.getRoutes().values().stream().map(Route::getMetadata).collect(toList()).get(0); + assertTrue(routeData.getName().startsWith(ROUTE_PREFIX)); + assertTrue(UNIQUE_ROUTE_NAME_REGEX.matcher(routeData.getName()).matches()); + assertEquals(routeData.getLabels().get(CHE_ORIGINAL_NAME_LABEL), ROUTE_NAME); + } + + private static Pod newPod() { + return new PodBuilder() + .withMetadata(new ObjectMetaBuilder().withName(POD_NAME).build()) + .build(); + } + + private static Route newRoute() { + return new RouteBuilder() + .withMetadata(new ObjectMetaBuilder().withName(ROUTE_NAME).build()) + .build(); + } +}