che #6258: Adding TLS support for OpenShift routes
Signed-off-by: Ilya Buziuk <ibuziuk@redhat.com>6.19.x
parent
772b1bbc71
commit
dcbd5bf1e0
|
|
@ -398,6 +398,9 @@ che.infra.openshift.username=
|
|||
che.infra.openshift.password=
|
||||
che.infra.openshift.trust_certs=
|
||||
|
||||
# Create routes with Transport Layer Security (TLS) enabled
|
||||
che.infra.openshift.tls_enabled=false
|
||||
|
||||
# Defines OpenShift namespace in which all workspaces will be created.
|
||||
# If not set, every workspace will be created in a new project, where project name = workspace id
|
||||
che.infra.openshift.project=
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ 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.route.TlsRouteProvisioner;
|
||||
import org.eclipse.che.workspace.infrastructure.openshift.provision.volume.PersistentVolumeClaimProvisioner;
|
||||
|
||||
/**
|
||||
|
|
@ -32,15 +33,18 @@ public class OpenShiftInfrastructureProvisioner {
|
|||
private final InstallerConfigProvisioner installerConfigProvisioner;
|
||||
private final PersistentVolumeClaimProvisioner persistentVolumeClaimProvisioner;
|
||||
private final UniqueNamesProvisioner uniqueNamesProvisioner;
|
||||
private final TlsRouteProvisioner tlsRouteProvisioner;
|
||||
|
||||
@Inject
|
||||
public OpenShiftInfrastructureProvisioner(
|
||||
InstallerConfigProvisioner installerConfigProvisioner,
|
||||
PersistentVolumeClaimProvisioner projectVolumeProvisioner,
|
||||
UniqueNamesProvisioner uniqueNamesProvisioner) {
|
||||
UniqueNamesProvisioner uniqueNamesProvisioner,
|
||||
TlsRouteProvisioner tlsRouteProvisioner) {
|
||||
this.installerConfigProvisioner = installerConfigProvisioner;
|
||||
this.persistentVolumeClaimProvisioner = projectVolumeProvisioner;
|
||||
this.uniqueNamesProvisioner = uniqueNamesProvisioner;
|
||||
this.tlsRouteProvisioner = tlsRouteProvisioner;
|
||||
}
|
||||
|
||||
public void provision(
|
||||
|
|
@ -49,5 +53,6 @@ public class OpenShiftInfrastructureProvisioner {
|
|||
installerConfigProvisioner.provision(environment, osEnv, identity);
|
||||
persistentVolumeClaimProvisioner.provision(environment, osEnv, identity);
|
||||
uniqueNamesProvisioner.provision(environment, osEnv, identity);
|
||||
tlsRouteProvisioner.provision(environment, osEnv, identity);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,8 +90,8 @@ public class RoutesAnnotations {
|
|||
/**
|
||||
* Retrieves server configuration from route annotations and returns (ref -> server config) map.
|
||||
*/
|
||||
public Map<String, ServerConfig> servers() {
|
||||
Map<String, ServerConfig> servers = new HashMap<>();
|
||||
public Map<String, ServerConfigImpl> servers() {
|
||||
Map<String, ServerConfigImpl> servers = new HashMap<>();
|
||||
for (Map.Entry<String, String> entry : annotations.entrySet()) {
|
||||
Matcher refMatcher = SERVER_ANNOTATION_PATTERN.matcher(entry.getKey());
|
||||
if (refMatcher.matches()) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.route;
|
||||
|
||||
import io.fabric8.openshift.api.model.Route;
|
||||
import io.fabric8.openshift.api.model.RouteSpec;
|
||||
import io.fabric8.openshift.api.model.TLSConfig;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
|
||||
import org.eclipse.che.api.workspace.server.model.impl.ServerConfigImpl;
|
||||
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.RoutesAnnotations;
|
||||
import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironment;
|
||||
import org.eclipse.che.workspace.infrastructure.openshift.provision.ConfigurationProvisioner;
|
||||
|
||||
/**
|
||||
* Enables Transport Layer Security (TLS) for workspace routes and changes protocol to secure (wss /
|
||||
* https) in servers' configuration
|
||||
*
|
||||
* @author Ilya Buziuk
|
||||
*/
|
||||
@Singleton
|
||||
public class TlsRouteProvisioner implements ConfigurationProvisioner {
|
||||
private static final String TERMINATION_EDGE = "edge";
|
||||
private static final String TERMINATION_POLICY_REDIRECT = "Redirect";
|
||||
private final boolean isTlsEnabled;
|
||||
|
||||
@Inject
|
||||
public TlsRouteProvisioner(@Named("che.infra.openshift.tls_enabled") boolean isTlsEnabled) {
|
||||
this.isTlsEnabled = isTlsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provision(
|
||||
InternalEnvironment environment, OpenShiftEnvironment osEnv, RuntimeIdentity identity)
|
||||
throws InfrastructureException {
|
||||
if (isTlsEnabled) {
|
||||
final Set<Route> routes = new HashSet<>(osEnv.getRoutes().values());
|
||||
for (Route route : routes) {
|
||||
useSecureProtocolForServers(route);
|
||||
enableTls(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void useSecureProtocolForServers(final Route route) {
|
||||
Map<String, ServerConfigImpl> servers =
|
||||
RoutesAnnotations.newDeserializer(route.getMetadata().getAnnotations()).servers();
|
||||
|
||||
servers.values().forEach(s -> s.setProtocol(getSecureProtocol(s.getProtocol())));
|
||||
|
||||
Map<String, String> annotations =
|
||||
RoutesAnnotations.newSerializer().servers(servers).annotations();
|
||||
|
||||
route.getMetadata().getAnnotations().putAll(annotations);
|
||||
}
|
||||
|
||||
private String getSecureProtocol(final String protocol) {
|
||||
if ("ws".equals(protocol)) {
|
||||
return "wss";
|
||||
} else if ("http".equals(protocol)) {
|
||||
return "https";
|
||||
} else return protocol;
|
||||
}
|
||||
|
||||
private void enableTls(final Route route) {
|
||||
RouteSpec spec = route.getSpec();
|
||||
spec.setTls(getTLSConfig());
|
||||
}
|
||||
|
||||
private TLSConfig getTLSConfig() {
|
||||
TLSConfig config = new TLSConfig();
|
||||
config.setTermination(TERMINATION_EDGE);
|
||||
config.setInsecureEdgeTerminationPolicy(TERMINATION_POLICY_REDIRECT);
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ 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.route.TlsRouteProvisioner;
|
||||
import org.eclipse.che.workspace.infrastructure.openshift.provision.volume.PersistentVolumeClaimProvisioner;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
|
|
@ -40,6 +41,7 @@ public class OpenShiftInfrastructureProvisionerTest {
|
|||
@Mock private InternalEnvironment environment;
|
||||
@Mock private OpenShiftEnvironment osEnv;
|
||||
@Mock private RuntimeIdentity runtimeIdentity;
|
||||
@Mock private TlsRouteProvisioner tlsRouteProvisioner;
|
||||
|
||||
private OpenShiftInfrastructureProvisioner osInfraProvisioner;
|
||||
|
||||
|
|
@ -49,8 +51,9 @@ public class OpenShiftInfrastructureProvisionerTest {
|
|||
public void setUp() {
|
||||
osInfraProvisioner =
|
||||
new OpenShiftInfrastructureProvisioner(
|
||||
installerProvisioner, pvcProvisioner, uniqueNamesProvisioner);
|
||||
provisionOrder = inOrder(installerProvisioner, pvcProvisioner, uniqueNamesProvisioner);
|
||||
installerProvisioner, pvcProvisioner, uniqueNamesProvisioner, tlsRouteProvisioner);
|
||||
provisionOrder =
|
||||
inOrder(installerProvisioner, pvcProvisioner, uniqueNamesProvisioner, tlsRouteProvisioner);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -66,6 +69,9 @@ public class OpenShiftInfrastructureProvisionerTest {
|
|||
provisionOrder
|
||||
.verify(uniqueNamesProvisioner)
|
||||
.provision(eq(environment), eq(osEnv), eq(runtimeIdentity));
|
||||
provisionOrder
|
||||
.verify(tlsRouteProvisioner)
|
||||
.provision(eq(environment), eq(osEnv), eq(runtimeIdentity));
|
||||
provisionOrder.verifyNoMoreInteractions();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class RoutesAnnotationsTest {
|
|||
|
||||
RoutesAnnotations.Deserializer deserializer = RoutesAnnotations.newDeserializer(annotations);
|
||||
|
||||
Map<String, ServerConfig> servers = deserializer.servers();
|
||||
Map<String, ServerConfigImpl> servers = deserializer.servers();
|
||||
ServerConfig server1 = servers.get("my-server1/http");
|
||||
assertNotNull(server1, "first server");
|
||||
assertEquals(server1.getPort(), "8000/tcp");
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ public class ServerExposerTest {
|
|||
|
||||
RoutesAnnotations.Deserializer routeDeserializer =
|
||||
RoutesAnnotations.newDeserializer(route.getMetadata().getAnnotations());
|
||||
Map<String, ServerConfig> servers = routeDeserializer.servers();
|
||||
Map<String, ServerConfigImpl> servers = routeDeserializer.servers();
|
||||
ServerConfig serverConfig = servers.get(serverName);
|
||||
assertEquals(serverConfig, expected);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.route;
|
||||
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.fabric8.openshift.api.model.Route;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
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.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests {@link TlsRouteProvisioner}.
|
||||
*
|
||||
* @author Ilya Buziuk
|
||||
*/
|
||||
@Listeners(MockitoTestNGListener.class)
|
||||
public class TlsRouteProvisionerTest {
|
||||
|
||||
@Mock private InternalEnvironment environment;
|
||||
@Mock private OpenShiftEnvironment osEnv;
|
||||
@Mock private RuntimeIdentity runtimeIdentity;
|
||||
|
||||
@Test
|
||||
public void doNothingWhenTlsDisabled() throws Exception {
|
||||
TlsRouteProvisioner tlsProvisioner = new TlsRouteProvisioner(false);
|
||||
tlsProvisioner.provision(environment, osEnv, runtimeIdentity);
|
||||
verify(osEnv, never()).getRoutes();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void provisionTlsForRoutes() throws Exception {
|
||||
TlsRouteProvisioner tlsProvisioner = new TlsRouteProvisioner(true);
|
||||
final Map<String, Route> routes = new HashMap<>();
|
||||
when(osEnv.getRoutes()).thenReturn(routes);
|
||||
tlsProvisioner.provision(environment, osEnv, runtimeIdentity);
|
||||
verify(osEnv, times(1)).getRoutes();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue