diff --git a/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties b/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties index 8ee1f1f10b..d6b2b544c4 100644 --- a/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties +++ b/assembly/assembly-wsmaster-war/src/main/webapp/WEB-INF/classes/che/che.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2012-2023 Red Hat, Inc. +# Copyright (c) 2012-2024 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/ @@ -91,10 +91,6 @@ che.workspace.server.liveness_probes=wsagent/http,exec-agent/http,terminal,theia # The default is: 10MB=10485760. che.workspace.startup_debug_log_limit_bytes=10485760 -# If set to `true`, 'stop-workspace' role with the edit privileges is granted to the 'che' ServiceAccount if OpenShift OAuth is enabled. -# This configuration is mainly required for workspace idling when the OpenShift OAuth is enabled. -che.workspace.stop.role.enabled=true - # Specifies whether {prod-short} is deployed with DevWorkspaces enabled. # This property is set by the {prod-short} Operator if it also installed the support for DevWorkspaces. # This property is used to advertise this fact to the {prod-short} dashboard. diff --git a/infrastructures/openshift/pom.xml b/infrastructures/openshift/pom.xml index 0809742c15..8cb10ada0e 100644 --- a/infrastructures/openshift/pom.xml +++ b/infrastructures/openshift/pom.xml @@ -50,10 +50,6 @@ io.fabric8 kubernetes-model-networking - - io.fabric8 - kubernetes-model-rbac - io.fabric8 openshift-client diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfraModule.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfraModule.java index 0b2e5b1647..27d5a1ea96 100644 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfraModule.java +++ b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/OpenShiftInfraModule.java @@ -87,7 +87,6 @@ import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftE import org.eclipse.che.workspace.infrastructure.openshift.environment.OpenShiftEnvironmentFactory; import org.eclipse.che.workspace.infrastructure.openshift.project.OpenShiftProjectFactory; import org.eclipse.che.workspace.infrastructure.openshift.project.RemoveProjectOnWorkspaceRemove; -import org.eclipse.che.workspace.infrastructure.openshift.project.configurator.OpenShiftStopWorkspaceRoleConfigurator; import org.eclipse.che.workspace.infrastructure.openshift.project.configurator.OpenShiftWorkspaceServiceAccountConfigurator; import org.eclipse.che.workspace.infrastructure.openshift.provision.OpenShiftPreviewUrlCommandProvisioner; import org.eclipse.che.workspace.infrastructure.openshift.provision.OpenshiftTrustedCAProvisioner; @@ -116,7 +115,6 @@ public class OpenShiftInfraModule extends AbstractModule { namespaceConfigurators.addBinding().to(OAuthTokenSecretsConfigurator.class); namespaceConfigurators.addBinding().to(PreferencesConfigMapConfigurator.class); namespaceConfigurators.addBinding().to(OpenShiftWorkspaceServiceAccountConfigurator.class); - namespaceConfigurators.addBinding().to(OpenShiftStopWorkspaceRoleConfigurator.class); namespaceConfigurators.addBinding().to(GitconfigUserDataConfigurator.class); bind(AuthorizationChecker.class).to(OpenShiftAuthorizationCheckerImpl.class); diff --git a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/project/configurator/OpenShiftStopWorkspaceRoleConfigurator.java b/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/project/configurator/OpenShiftStopWorkspaceRoleConfigurator.java deleted file mode 100644 index 8b35b82471..0000000000 --- a/infrastructures/openshift/src/main/java/org/eclipse/che/workspace/infrastructure/openshift/project/configurator/OpenShiftStopWorkspaceRoleConfigurator.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2012-2023 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.workspace.infrastructure.openshift.project.configurator; - -import static com.google.common.base.Strings.isNullOrEmpty; - -import io.fabric8.kubernetes.api.model.rbac.*; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientException; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; -import org.eclipse.che.api.workspace.server.spi.InfrastructureException; -import org.eclipse.che.api.workspace.server.spi.NamespaceResolutionContext; -import org.eclipse.che.commons.annotation.Nullable; -import org.eclipse.che.workspace.infrastructure.kubernetes.CheServerKubernetesClientFactory; -import org.eclipse.che.workspace.infrastructure.kubernetes.environment.CheInstallationLocation; -import org.eclipse.che.workspace.infrastructure.kubernetes.namespace.configurator.NamespaceConfigurator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class creates the necessary role and rolebindings to allow the che serviceaccount to stop - * user workspaces. - * - * @author Tom George - */ -@Singleton -public class OpenShiftStopWorkspaceRoleConfigurator implements NamespaceConfigurator { - - private final CheServerKubernetesClientFactory cheClientFactory; - private final String installationLocation; - private final boolean stopWorkspaceRoleEnabled; - private final String oAuthIdentityProvider; - - private static final Logger LOG = - LoggerFactory.getLogger(OpenShiftStopWorkspaceRoleConfigurator.class); - - @Inject - public OpenShiftStopWorkspaceRoleConfigurator( - CheServerKubernetesClientFactory cheClientFactory, - CheInstallationLocation installationLocation, - @Named("che.workspace.stop.role.enabled") boolean stopWorkspaceRoleEnabled, - @Nullable @Named("che.infra.openshift.oauth_identity_provider") String oAuthIdentityProvider) - throws InfrastructureException { - this.cheClientFactory = cheClientFactory; - this.installationLocation = installationLocation.getInstallationLocationNamespace(); - this.stopWorkspaceRoleEnabled = stopWorkspaceRoleEnabled; - this.oAuthIdentityProvider = oAuthIdentityProvider; - } - - @Override - public void configure(NamespaceResolutionContext namespaceResolutionContext, String projectName) - throws InfrastructureException { - if (isNullOrEmpty(oAuthIdentityProvider)) { - return; - } - - try { - if (stopWorkspaceRoleEnabled && installationLocation != null) { - KubernetesClient client = cheClientFactory.create(); - String stopWorkspacesRoleName = "workspace-stop"; - - client - .rbac() - .roles() - .inNamespace(projectName) - .createOrReplace(createStopWorkspacesRole(stopWorkspacesRoleName)); - - client - .rbac() - .roleBindings() - .inNamespace(projectName) - .createOrReplace(createStopWorkspacesRoleBinding(stopWorkspacesRoleName)); - } - } catch (KubernetesClientException e) { - LOG.warn( - "Stop workspace Role and RoleBinding will not be provisioned to the '{}' namespace. 'che.workspace.stop.role.enabled' property is set to '{}', {}", - installationLocation, - stopWorkspaceRoleEnabled, - e.getMessage()); - } - } - - protected Role createStopWorkspacesRole(String name) { - return new RoleBuilder() - .withNewMetadata() - .withName(name) - .endMetadata() - .withRules( - new PolicyRuleBuilder() - .withApiGroups("") - .withResources("pods") - .withVerbs("get", "list", "watch", "delete") - .build(), - new PolicyRuleBuilder() - .withApiGroups("") - .withResources("configmaps", "services", "secrets") - .withVerbs("delete", "list", "get") - .build(), - new PolicyRuleBuilder() - .withApiGroups("route.openshift.io") - .withResources("routes") - .withVerbs("delete", "list") - .build(), - new PolicyRuleBuilder() - .withApiGroups("apps") - .withResources("deployments", "replicasets") - .withVerbs("delete", "list", "get", "patch") - .build()) - .build(); - } - - protected RoleBinding createStopWorkspacesRoleBinding(String name) { - return new RoleBindingBuilder() - .withNewMetadata() - .withName(name) - .endMetadata() - .withNewRoleRef() - .withKind("Role") - .withName(name) - .endRoleRef() - .withSubjects( - new SubjectBuilder() - .withKind("ServiceAccount") - .withName("che") - .withNamespace(installationLocation) - .build()) - .build(); - } -} diff --git a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/project/configurator/OpenShiftStopWorkspaceRoleConfiguratorTest.java b/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/project/configurator/OpenShiftStopWorkspaceRoleConfiguratorTest.java deleted file mode 100644 index 6651d73887..0000000000 --- a/infrastructures/openshift/src/test/java/org/eclipse/che/workspace/infrastructure/openshift/project/configurator/OpenShiftStopWorkspaceRoleConfiguratorTest.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2012-2023 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.workspace.infrastructure.openshift.project.configurator; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.lenient; -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 static org.testng.Assert.assertEquals; - -import io.fabric8.kubernetes.api.model.rbac.*; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.dsl.MixedOperation; -import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; -import io.fabric8.kubernetes.client.dsl.RbacAPIGroupDSL; -import io.fabric8.kubernetes.client.dsl.Resource; -import org.eclipse.che.api.workspace.server.spi.InfrastructureException; -import org.eclipse.che.workspace.infrastructure.kubernetes.CheServerKubernetesClientFactory; -import org.eclipse.che.workspace.infrastructure.kubernetes.environment.CheInstallationLocation; -import org.mockito.Mock; -import org.mockito.testng.MockitoTestNGListener; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Listeners; -import org.testng.annotations.Test; - -/** - * Test for {@link - * org.eclipse.che.workspace.infrastructure.openshift.project.configurator.OpenShiftStopWorkspaceRoleConfigurator} - * - *

#author Tom George - */ -@Listeners(MockitoTestNGListener.class) -public class OpenShiftStopWorkspaceRoleConfiguratorTest { - - @Mock private CheInstallationLocation cheInstallationLocation; - private OpenShiftStopWorkspaceRoleConfigurator stopWorkspaceRoleProvisioner; - - @Mock private CheServerKubernetesClientFactory cheClientFactory; - @Mock private KubernetesClient client; - - @Mock private MixedOperation> mixedRoleOperation; - - @Mock - private MixedOperation> - mixedRoleBindingOperation; - - @Mock private NonNamespaceOperation> nonNamespaceRoleOperation; - - @Mock - private NonNamespaceOperation> - nonNamespaceRoleBindingOperation; - - @Mock private Resource roleResource; - @Mock private Resource roleBindingResource; - @Mock private Role mockRole; - @Mock private RoleBinding mockRoleBinding; - @Mock private RbacAPIGroupDSL rbacAPIGroupDSL; - - private final Role expectedRole = - new RoleBuilder() - .withNewMetadata() - .withName("workspace-stop") - .endMetadata() - .withRules( - new PolicyRuleBuilder() - .withApiGroups("") - .withResources("pods") - .withVerbs("get", "list", "watch", "delete") - .build(), - new PolicyRuleBuilder() - .withApiGroups("") - .withResources("configmaps", "services", "secrets") - .withVerbs("delete", "list", "get") - .build(), - new PolicyRuleBuilder() - .withApiGroups("route.openshift.io") - .withResources("routes") - .withVerbs("delete", "list") - .build(), - new PolicyRuleBuilder() - .withApiGroups("apps") - .withResources("deployments", "replicasets") - .withVerbs("delete", "list", "get", "patch") - .build()) - .build(); - - private final RoleBinding expectedRoleBinding = - new RoleBindingBuilder() - .withNewMetadata() - .withName("workspace-stop") - .endMetadata() - .withNewRoleRef() - .withKind("Role") - .withName("workspace-stop") - .endRoleRef() - .withSubjects( - new SubjectBuilder() - .withKind("ServiceAccount") - .withName("che") - .withNamespace("che") - .build()) - .build(); - - @BeforeMethod - public void setUp() throws Exception { - lenient().when(cheInstallationLocation.getInstallationLocationNamespace()).thenReturn("che"); - stopWorkspaceRoleProvisioner = - new OpenShiftStopWorkspaceRoleConfigurator( - cheClientFactory, cheInstallationLocation, true, "yes"); - lenient().when(cheClientFactory.create()).thenReturn(client); - lenient().when(client.rbac()).thenReturn(rbacAPIGroupDSL); - lenient().when(rbacAPIGroupDSL.roles()).thenReturn(mixedRoleOperation); - lenient().when(rbacAPIGroupDSL.roleBindings()).thenReturn(mixedRoleBindingOperation); - lenient() - .when(mixedRoleOperation.inNamespace(anyString())) - .thenReturn(nonNamespaceRoleOperation); - lenient() - .when(mixedRoleBindingOperation.inNamespace(anyString())) - .thenReturn(nonNamespaceRoleBindingOperation); - lenient().when(nonNamespaceRoleOperation.withName(anyString())).thenReturn(roleResource); - lenient() - .when(nonNamespaceRoleBindingOperation.withName(anyString())) - .thenReturn(roleBindingResource); - lenient().when(roleResource.get()).thenReturn(null); - lenient().when(nonNamespaceRoleOperation.createOrReplace(any())).thenReturn(mockRole); - lenient() - .when(nonNamespaceRoleBindingOperation.createOrReplace(any())) - .thenReturn(mockRoleBinding); - } - - @Test - public void shouldCreateRole() { - assertEquals( - stopWorkspaceRoleProvisioner.createStopWorkspacesRole("workspace-stop"), expectedRole); - } - - @Test - public void shouldCreateRoleBinding() throws InfrastructureException { - assertEquals( - stopWorkspaceRoleProvisioner.createStopWorkspacesRoleBinding("workspace-stop"), - expectedRoleBinding); - } - - @Test - public void shouldCreateRoleAndRoleBindingWhenRoleDoesNotYetExist() - throws InfrastructureException { - stopWorkspaceRoleProvisioner.configure(null, "developer-che"); - verify(client.rbac().roles().inNamespace("developer-che")).createOrReplace(expectedRole); - verify(client.rbac().roleBindings().inNamespace("developer-che")) - .createOrReplace(expectedRoleBinding); - } - - @Test - public void shouldNotCreateRoleBindingWhenStopWorkspaceRolePropertyIsDisabled() - throws InfrastructureException { - OpenShiftStopWorkspaceRoleConfigurator disabledStopWorkspaceRoleProvisioner = - new OpenShiftStopWorkspaceRoleConfigurator( - cheClientFactory, cheInstallationLocation, false, "yes"); - disabledStopWorkspaceRoleProvisioner.configure(null, "developer-che"); - verify(client, never()).rbac(); - } - - @Test - public void shouldNotCreateRoleBindingWhenInstallationLocationIsNull() - throws InfrastructureException { - lenient().when(cheInstallationLocation.getInstallationLocationNamespace()).thenReturn(null); - OpenShiftStopWorkspaceRoleConfigurator - stopWorkspaceRoleProvisionerWithoutValidInstallationLocation = - new OpenShiftStopWorkspaceRoleConfigurator( - cheClientFactory, cheInstallationLocation, true, "yes"); - stopWorkspaceRoleProvisionerWithoutValidInstallationLocation.configure(null, "developer-che"); - verify(client, never()).rbac(); - } - - @Test - public void shouldNotCallStopWorkspaceRoleProvisionWhenIdentityProviderIsDefined() - throws Exception { - when(cheInstallationLocation.getInstallationLocationNamespace()).thenReturn("something"); - OpenShiftStopWorkspaceRoleConfigurator configurator = - new OpenShiftStopWorkspaceRoleConfigurator( - cheClientFactory, cheInstallationLocation, true, null); - - configurator.configure(null, "something"); - - verify(cheClientFactory, times(0)).create(); - } -}