Deploy legacy variable only for che6 workspaces

* Deploy legacy variable only for che6 workspaces

Signed-off-by: Sergii Kabashniuk <skabashniuk@redhat.com>

* Add tests to the new legacy env var provisioner.

Signed-off-by: Lukas Krejci <lkrejci@redhat.com>
7.20.x
Sergii Kabashniuk 2019-07-01 10:12:03 +02:00 committed by Max Shaposhnik
parent fb41e43214
commit c2ee93182f
11 changed files with 296 additions and 15 deletions

View File

@ -62,6 +62,8 @@ import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiInternalEnvV
import org.eclipse.che.api.workspace.server.spi.provision.env.EnvVarEnvironmentProvisioner;
import org.eclipse.che.api.workspace.server.spi.provision.env.EnvVarProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.JavaOptsEnvVariableProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.LegacyEnvVarEnvironmentProvisioner;
import org.eclipse.che.api.workspace.server.spi.provision.env.LegacyEnvVarProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.MachineTokenEnvVarProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.MavenOptsEnvVariableProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.ProjectsRootEnvVariableProvider;
@ -176,6 +178,7 @@ public class WsMasterModule extends AbstractModule {
Multibinder.newSetBinder(binder(), InternalEnvironmentProvisioner.class);
internalEnvironmentProvisioners.addBinding().to(InstallerConfigProvisioner.class);
internalEnvironmentProvisioners.addBinding().to(EnvVarEnvironmentProvisioner.class);
internalEnvironmentProvisioners.addBinding().to(LegacyEnvVarEnvironmentProvisioner.class);
internalEnvironmentProvisioners.addBinding().to(ProjectsVolumeForWsAgentProvisioner.class);
internalEnvironmentProvisioners.addBinding().to(MachineNameProvisioner.class);
@ -188,16 +191,25 @@ public class WsMasterModule extends AbstractModule {
envVarProviders.addBinding().to(WorkspaceIdEnvVarProvider.class);
envVarProviders.addBinding().to(WorkspaceNamespaceNameEnvVarProvider.class);
envVarProviders.addBinding().to(WorkspaceNameEnvVarProvider.class);
envVarProviders.addBinding().to(JavaOptsEnvVariableProvider.class);
envVarProviders.addBinding().to(MavenOptsEnvVariableProvider.class);
envVarProviders.addBinding().to(ProjectsRootEnvVariableProvider.class);
envVarProviders.addBinding().to(AgentAuthEnableEnvVarProvider.class);
envVarProviders.addBinding().to(WorkspaceAgentJavaOptsEnvVariableProvider.class);
envVarProviders.addBinding().to(WorkspaceAgentCorsAllowedOriginsEnvVarProvider.class);
envVarProviders.addBinding().to(WorkspaceAgentCorsAllowCredentialsEnvVarProvider.class);
envVarProviders.addBinding().to(WorkspaceAgentCorsEnabledEnvVarProvider.class);
Multibinder<LegacyEnvVarProvider> legacyEnvVarProviderMultibinders =
Multibinder.newSetBinder(binder(), LegacyEnvVarProvider.class);
legacyEnvVarProviderMultibinders.addBinding().to(JavaOptsEnvVariableProvider.class);
legacyEnvVarProviderMultibinders.addBinding().to(MavenOptsEnvVariableProvider.class);
legacyEnvVarProviderMultibinders.addBinding().to(AgentAuthEnableEnvVarProvider.class);
legacyEnvVarProviderMultibinders
.addBinding()
.to(WorkspaceAgentJavaOptsEnvVariableProvider.class);
legacyEnvVarProviderMultibinders
.addBinding()
.to(WorkspaceAgentCorsAllowedOriginsEnvVarProvider.class);
legacyEnvVarProviderMultibinders
.addBinding()
.to(WorkspaceAgentCorsAllowCredentialsEnvVarProvider.class);
legacyEnvVarProviderMultibinders.addBinding().to(WorkspaceAgentCorsEnabledEnvVarProvider.class);
bind(org.eclipse.che.api.workspace.server.bootstrap.InstallerService.class);
bind(org.eclipse.che.api.workspace.server.event.WorkspaceJsonRpcMessenger.class)

View File

@ -21,7 +21,7 @@ import org.eclipse.che.commons.lang.Pair;
*
* @author Sergii Leshchenko
*/
public class AgentAuthEnableEnvVarProvider implements EnvVarProvider {
public class AgentAuthEnableEnvVarProvider implements LegacyEnvVarProvider {
public static final String CHE_AUTH_ENABLED_ENV = "CHE_AUTH_ENABLED";

View File

@ -23,7 +23,7 @@ import org.eclipse.che.commons.lang.Pair;
* @author Roman Iuvshyn
* @author Alexander Garagatyi
*/
public class JavaOptsEnvVariableProvider implements EnvVarProvider {
public class JavaOptsEnvVariableProvider implements LegacyEnvVarProvider {
/** Env variable for jvm settings */
public static final String JAVA_OPTS_VARIABLE = "JAVA_OPTS";

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.workspace.server.spi.provision.env;
import java.util.Set;
import javax.inject.Inject;
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.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.provision.InternalEnvironmentProvisioner;
import org.eclipse.che.commons.lang.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Adds the legacy environment variables to the workspaces that contain some machines with
* installers. Because the new (Che 7) workspaces don't use installers we can be sure the new
* workspaces are never provisioned with legacy env vars (which would make them unable to override
* JAVA_OPTS for example).
*
* @author Sergii Kabashniuk
*/
public class LegacyEnvVarEnvironmentProvisioner implements InternalEnvironmentProvisioner {
private static final Logger LOG =
LoggerFactory.getLogger(LegacyEnvVarEnvironmentProvisioner.class);
private final Set<LegacyEnvVarProvider> envVarProviders;
@Inject
public LegacyEnvVarEnvironmentProvisioner(Set<LegacyEnvVarProvider> envVarProviders) {
this.envVarProviders = envVarProviders;
}
@Override
public void provision(RuntimeIdentity id, InternalEnvironment internalEnvironment)
throws InfrastructureException {
if (!hasInstallers(internalEnvironment)) {
LOG.debug(
"Legacy environment variables not provisioned to workspace '{}'.", id.getWorkspaceId());
return;
}
for (EnvVarProvider envVarProvider : envVarProviders) {
Pair<String, String> envVar = envVarProvider.get(id);
if (envVar != null) {
LOG.debug(
"Provisioning legacy environment variables for workspace '{}' from {} with {} variable",
id.getWorkspaceId(),
envVarProvider.getClass().getSimpleName(),
envVar.first);
internalEnvironment
.getMachines()
.values()
.forEach(m -> m.getEnv().putIfAbsent(envVar.first, envVar.second));
}
}
LOG.info(
"Environment legacy variables provisioning done for workspace '{}'", id.getWorkspaceId());
}
private boolean hasInstallers(InternalEnvironment internalEnvironment) {
return internalEnvironment
.getMachines()
.values()
.stream()
.anyMatch(m -> !m.getInstallers().isEmpty());
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.workspace.server.spi.provision.env;
/**
* Marker interface for environment variable providers which keeps backward-compatibility with Che 6
* workspaces.
*/
public interface LegacyEnvVarProvider extends EnvVarProvider {}

View File

@ -23,7 +23,7 @@ import org.eclipse.che.commons.lang.Pair;
*
* @author Yevhenii Voevodin
*/
public class MavenOptsEnvVariableProvider implements EnvVarProvider {
public class MavenOptsEnvVariableProvider implements LegacyEnvVarProvider {
private final String javaOpts;

View File

@ -24,7 +24,7 @@ import org.eclipse.che.commons.lang.Pair;
*
* @author Mykhailo Kuznietsov
*/
public class WorkspaceAgentCorsAllowCredentialsEnvVarProvider implements EnvVarProvider {
public class WorkspaceAgentCorsAllowCredentialsEnvVarProvider implements LegacyEnvVarProvider {
private String wsAgentCorsAllowCredentials;

View File

@ -23,7 +23,7 @@ import org.eclipse.che.commons.lang.Pair;
*
* @author Mykhailo Kuznietsov
*/
public class WorkspaceAgentCorsAllowedOriginsEnvVarProvider implements EnvVarProvider {
public class WorkspaceAgentCorsAllowedOriginsEnvVarProvider implements LegacyEnvVarProvider {
private String wsAgentCorsAllowedOrigins;

View File

@ -23,7 +23,7 @@ import org.eclipse.che.commons.lang.Pair;
*
* @author Mykhailo Kuznietsov
*/
public class WorkspaceAgentCorsEnabledEnvVarProvider implements EnvVarProvider {
public class WorkspaceAgentCorsEnabledEnvVarProvider implements LegacyEnvVarProvider {
private String wsAgentCorsEnabled;

View File

@ -17,7 +17,7 @@ import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.commons.annotation.Nullable;
import org.eclipse.che.commons.lang.Pair;
public class WorkspaceAgentJavaOptsEnvVariableProvider implements EnvVarProvider {
public class WorkspaceAgentJavaOptsEnvVariableProvider implements LegacyEnvVarProvider {
/** Env variable for jvm settings */
public static final String WSAGENT_JAVA_OPTIONS_ENV = "CHE_WORKSPACE_WSAGENT__JAVA__OPTIONS";

View File

@ -0,0 +1,173 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.workspace.server.spi.provision.env;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.che.api.core.model.workspace.runtime.RuntimeIdentity;
import org.eclipse.che.api.installer.server.model.impl.InstallerImpl;
import org.eclipse.che.api.workspace.server.model.impl.RuntimeIdentityImpl;
import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
import org.eclipse.che.api.workspace.server.spi.environment.InternalMachineConfig;
import org.eclipse.che.commons.lang.Pair;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(MockitoTestNGListener.class)
public class LegacyEnvVarEnvironmentProvisionerTest {
private static final RuntimeIdentity RUNTIME_IDENTITY =
new RuntimeIdentityImpl("testWsId", "testEnv", "testOwnerId");
@Mock private LegacyEnvVarProvider provider1;
@Mock private LegacyEnvVarProvider provider2;
@Mock private InternalEnvironment internalEnvironment;
@Mock private InternalMachineConfig machineConfig1;
@Mock private InternalMachineConfig machineConfig2;
private Map<String, String> machine1Env;
private Map<String, String> machine2Env;
@BeforeMethod
public void setup() {
machine1Env = new HashMap<>();
machine2Env = new HashMap<>();
when(internalEnvironment.getMachines())
.thenReturn(ImmutableMap.of("machine1", machineConfig1, "machine2", machineConfig2));
lenient().when(machineConfig2.getInstallers()).thenReturn(emptyList());
when(machineConfig1.getEnv()).thenReturn(machine1Env);
when(machineConfig2.getEnv()).thenReturn(machine2Env);
}
@Test
public void shouldProvisionWorkspacesWithInstallers() throws Exception {
// given
// make 1 of the machine configs have an installer - this should make the whole environment
// be considered legacy and therefore the legacy env vars should be applied.
when(machineConfig1.getInstallers()).thenReturn(singletonList(mock(InstallerImpl.class)));
LegacyEnvVarEnvironmentProvisioner provisioner =
new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1, provider2));
when(provider1.get(any())).thenReturn(Pair.of("test", "test"));
when(provider2.get(any())).thenReturn(Pair.of("test", "test"));
// when
provisioner.provision(RUNTIME_IDENTITY, internalEnvironment);
// then
verify(provider1).get(eq(RUNTIME_IDENTITY));
verify(provider2).get(eq(RUNTIME_IDENTITY));
}
@Test
public void shouldNotProvisionWorkspacesWithoutInstallers() throws Exception {
// given
// none of the machines has installers. Therefore we should see no legacy env var provisioning
when(machineConfig1.getInstallers()).thenReturn(emptyList());
LegacyEnvVarEnvironmentProvisioner provisioner =
new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1, provider2));
// when
provisioner.provision(RUNTIME_IDENTITY, internalEnvironment);
// then
verify(provider1, never()).get(eq(RUNTIME_IDENTITY));
verify(provider2, never()).get(eq(RUNTIME_IDENTITY));
}
@Test
public void shouldAddAllEnvVarsToAllContainers() throws Exception {
// given
when(machineConfig1.getInstallers()).thenReturn(singletonList(mock(InstallerImpl.class)));
LegacyEnvVarEnvironmentProvisioner provisioner =
new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1, provider2));
Pair<String, String> envVar1 = Pair.of("env1", "value1");
Pair<String, String> envVar2 = Pair.of("env2", "value2");
ImmutableMap<String, String> envVarsFromProviders =
ImmutableMap.of(
envVar1.first, envVar1.second,
envVar2.first, envVar2.second);
when(provider1.get(any(RuntimeIdentity.class))).thenReturn(envVar1);
when(provider2.get(any(RuntimeIdentity.class))).thenReturn(envVar2);
// when
provisioner.provision(RUNTIME_IDENTITY, internalEnvironment);
// then
assertEquals(machine1Env, envVarsFromProviders);
assertEquals(machine2Env, envVarsFromProviders);
}
@Test
public void shouldNotRemoveExistingEnvVarsWithDifferentNames() throws Exception {
// given
when(machineConfig1.getInstallers()).thenReturn(singletonList(mock(InstallerImpl.class)));
LegacyEnvVarEnvironmentProvisioner provisioner =
new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1));
Pair<String, String> existingEnvVar = Pair.of("existingEnvVar", "some-value");
machine1Env.put(existingEnvVar.first, existingEnvVar.second);
Pair<String, String> envVar1 = Pair.of("env1", "value1");
when(provider1.get(any(RuntimeIdentity.class))).thenReturn(envVar1);
// when
provisioner.provision(RUNTIME_IDENTITY, internalEnvironment);
// then
assertEquals(
ImmutableMap.of(existingEnvVar.first, existingEnvVar.second, envVar1.first, envVar1.second),
machine1Env);
}
@Test
public void shouldNotReplaceExistingEnvVarsWithMatchingNames() throws Exception {
// given
when(machineConfig1.getInstallers()).thenReturn(singletonList(mock(InstallerImpl.class)));
LegacyEnvVarEnvironmentProvisioner provisioner =
new LegacyEnvVarEnvironmentProvisioner(ImmutableSet.of(provider1));
String existingEnvVarName = "existingEnvVar";
String oldEnvVarValue = "some-value";
machine1Env.put(existingEnvVarName, oldEnvVarValue);
String envVarValueFromProvider = "value1";
when(provider1.get(any(RuntimeIdentity.class)))
.thenReturn(Pair.of(existingEnvVarName, envVarValueFromProvider));
// when
provisioner.provision(RUNTIME_IDENTITY, internalEnvironment);
// then
assertEquals(ImmutableMap.of(existingEnvVarName, oldEnvVarValue), machine1Env);
}
}