Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy legacy variable only for che6 workspaces #13612

Merged
merged 4 commits into from
Jul 1, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
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;
Expand Down Expand Up @@ -176,6 +178,7 @@ protected void configure() {
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);

Expand All @@ -188,16 +191,25 @@ protected void configure() {
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*
* @author Sergii Leshchenko
*/
public class AgentAuthEnableEnvVarProvider implements EnvVarProvider {
public class AgentAuthEnableEnvVarProvider implements LegacyEnvVarProvider {

public static final String CHE_AUTH_ENABLED_ENV = "CHE_AUTH_ENABLED";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* @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";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* 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 workspaces we can be sure the new
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved
* 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(EnvVarEnvironmentProvisioner.class);
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved

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)) {

for (EnvVarProvider envVarProvider : envVarProviders) {
Pair<String, String> envVar = envVarProvider.get(id);
if (envVar != null) {
LOG.info(
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved
"Provisioning legacy environment variables for workspace '{}' from {} with {} variable",
id.getWorkspaceId(),
envVarProvider,
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved
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());
} else {
LOG.debug(
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved
"Legacy environment variables not provisioned to workspace '{}'.", id.getWorkspaceId());
}
}

private boolean hasInstallers(InternalEnvironment internalEnvironment) {
return internalEnvironment
.getMachines()
.values()
.stream()
.anyMatch(m -> !m.getInstallers().isEmpty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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;

public interface LegacyEnvVarProvider extends EnvVarProvider {}
mshaposhnik marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*
* @author Yevhenii Voevodin
*/
public class MavenOptsEnvVariableProvider implements EnvVarProvider {
public class MavenOptsEnvVariableProvider implements LegacyEnvVarProvider {

private final String javaOpts;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*
* @author Mykhailo Kuznietsov
*/
public class WorkspaceAgentCorsAllowCredentialsEnvVarProvider implements EnvVarProvider {
public class WorkspaceAgentCorsAllowCredentialsEnvVarProvider implements LegacyEnvVarProvider {

private String wsAgentCorsAllowCredentials;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*
* @author Mykhailo Kuznietsov
*/
public class WorkspaceAgentCorsAllowedOriginsEnvVarProvider implements EnvVarProvider {
public class WorkspaceAgentCorsAllowedOriginsEnvVarProvider implements LegacyEnvVarProvider {

private String wsAgentCorsAllowedOrigins;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*
* @author Mykhailo Kuznietsov
*/
public class WorkspaceAgentCorsEnabledEnvVarProvider implements EnvVarProvider {
public class WorkspaceAgentCorsEnabledEnvVarProvider implements LegacyEnvVarProvider {

private String wsAgentCorsEnabled;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
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";
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}