Add prefix into names of OpenShift objects

6.19.x
Anton Korneta 2017-09-19 14:03:28 +03:00
parent 8af134edbf
commit d43901a83a
8 changed files with 202 additions and 8 deletions

View File

@ -90,6 +90,10 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-shared</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-commons-lang</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>

View File

@ -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);
}
}

View File

@ -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<OpenShiftRuntimeCo
throws InfrastructureException {
final ServerResolver serverResolver = ServerResolver.of(services, routes);
for (Pod toCreate : getContext().getOpenShiftEnvironment().getPods().values()) {
Pod createdPod = project.pods().create(toCreate);
final Pod createdPod = project.pods().create(toCreate);
final ObjectMeta podMetadata = createdPod.getMetadata();
for (Container container : createdPod.getSpec().getContainers()) {
OpenShiftMachine machine =
new OpenShiftMachine(
createdPod.getMetadata().getName(),
podMetadata.getLabels().get(CHE_ORIGINAL_NAME_LABEL) + '/' + container.getName(),
podMetadata.getName(),
container.getName(),
serverResolver.resolve(createdPod, container),
project);

View File

@ -27,16 +27,19 @@ public class OpenShiftMachine implements Machine {
//TODO Make timeout configurable
private static final int EXEC_TIMEOUT_MIN = 5;
private final String machineName;
private final String podName;
private final String containerName;
private final Map<String, ServerImpl> ref2Server;
private final OpenShiftProject project;
public OpenShiftMachine(
String machineName,
String podName,
String containerName,
Map<String, ServerImpl> 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

View File

@ -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<Pod> 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<Route> 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);
}
}
}

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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<String, Pod> 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<String, Route> 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();
}
}