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

Fix the update validation error while stopping an idling workspace. #15689

Merged
merged 4 commits into from
Jan 17, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -21,6 +21,7 @@
import javax.inject.Provider;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.api.workspace.server.WorkspaceAttributeValidator;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory;

/**
Expand Down Expand Up @@ -76,7 +77,14 @@ public void validate(Map<String, String> attributes) throws ValidationException
+ "')");
}

namespaceFactoryProvider.get().checkIfNamespaceIsAllowed(namespace);
Copy link
Member

@ibuziuk ibuziuk Jan 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be wrong, but according to the comment below it looks like idling is broken in the upstream also, no ? (anonymous subject for scheduled jobs like idling is used in the similar manner in the upstream)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is the case it is just not clear for me why this error was not caught by the pre-release tests..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmytro-ndp @rhopp could you please take a look? would be great to understand if the pre-release testing actually run the idling tests or this use-case is not tested atm?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We talked about this and as far as I understood, this bug doesn't exhibit itself because in the pre-release tests, we use a namespace default that doesn't have <username> or <userid> placeholder.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@metlos could you point me to the code which checks the namespace part and placeholders / ? For now I do not fully understand how idling works and it looks like it works differently depending on the namespace strategies

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the method used during workspace update to check that the namespace contained in the attributes is valid: https://github.com/eclipse/che/blob/b2b6f5f488ea523bac0a9313f0f65a23ac98a16a/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/namespace/KubernetesNamespaceFactory.java#L139

Note that the current version of code in this branch calls this during the update only during a situation that I am not sure can happen even.

// the current user is going to be anonymous only during internal scheduled jobs. In those
// circumstances, we don't actually need to check the namespace validity, because those
// workflows are defined by our code and are therefore "safe". User-initiated workspace
// creation or update is never going to succeed using an anonymous user anyway, so again,
// skipping this check for anonymous user is safe.
if (!EnvironmentContext.getCurrent().getSubject().isAnonymous()) {
namespaceFactoryProvider.get().checkIfNamespaceIsAllowed(namespace);
metlos marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@
import static java.util.Collections.emptyMap;
import static org.eclipse.che.api.workspace.shared.Constants.WORKSPACE_INFRASTRUCTURE_NAMESPACE_ATTRIBUTE;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
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.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import com.google.common.collect.ImmutableMap;
import javax.inject.Provider;
import org.eclipse.che.api.core.ValidationException;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.subject.Subject;
import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.KubernetesNamespaceFactory;
import org.mockito.InjectMocks;
import org.mockito.Mock;
Expand All @@ -46,6 +53,7 @@ public class K8sInfraNamespaceWsAttributeValidatorTest {
@BeforeMethod
public void setUp() {
lenient().when(namespaceFactoryProvider.get()).thenReturn(namespaceFactory);
EnvironmentContext.setCurrent(new EnvironmentContext());
}

@Test(
Expand Down Expand Up @@ -82,6 +90,7 @@ public void testWhenNamespaceFactoryThrowsErrorOnCheckingIfNamespaceIsAllowed()
.when(namespaceFactory)
.checkIfNamespaceIsAllowed(anyString());

setNonAnonymousUserInContext();
validator.validate(ImmutableMap.of(WORKSPACE_INFRASTRUCTURE_NAMESPACE_ATTRIBUTE, "any"));
}

Expand Down Expand Up @@ -112,8 +121,33 @@ public void shouldDoNotAllowToRemoveNamespaceAttribute() throws ValidationExcept
emptyMap());
}

@Test
public void shouldNotCheckIfNamespaceIsAllowedWhenUsingAnonymousUser()
throws ValidationException {
validator.validate(ImmutableMap.of(WORKSPACE_INFRASTRUCTURE_NAMESPACE_ATTRIBUTE, "ns"));
verify(namespaceFactory, never()).checkIfNamespaceIsAllowed(anyString());
}

@Test
public void shouldCheckIfNamespaceIsAllowedWhenUsingNonAnonymousUser()
throws ValidationException {
setNonAnonymousUserInContext();
validator.validate(ImmutableMap.of(WORKSPACE_INFRASTRUCTURE_NAMESPACE_ATTRIBUTE, "ns"));
verify(namespaceFactory).checkIfNamespaceIsAllowed(eq("ns"));
}

@DataProvider
public Object[][] invalidNamespaces() {
return new String[][] {{"name!space"}, {"name@space"}, {"-namespace"}, {"namespace-"}};
}

private void setNonAnonymousUserInContext() {
Subject subj = mock(Subject.class);
when(subj.isAnonymous()).thenReturn(false);

EnvironmentContext ctx = new EnvironmentContext();
ctx.setSubject(subj);

EnvironmentContext.setCurrent(ctx);
}
}