diff --git a/api/v2/checluster_types.go b/api/v2/checluster_types.go index f4d8c05e0..b4924bee7 100644 --- a/api/v2/checluster_types.go +++ b/api/v2/checluster_types.go @@ -500,6 +500,11 @@ type DefaultNamespace struct { // +optional // +kubebuilder:default:=true AutoProvision *bool `json:"autoProvision,omitempty"` + // For OpenShift clusters only, setting this to `true` creates + // a standard Kubernetes Namespace. When false (default), the OpenShift ProjectRequest API + // is used instead to trigger cluster-specific Project Templates. + // +optional + CreateKubernetesNamespaces *bool `json:"createKubernetesNamespaces,omitempty"` } type DashboardHeaderMessage struct { diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index bc9eb8845..180e141de 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -738,6 +738,11 @@ func (in *DefaultNamespace) DeepCopyInto(out *DefaultNamespace) { *out = new(bool) **out = **in } + if in.CreateKubernetesNamespaces != nil { + in, out := &in.CreateKubernetesNamespaces, &out.CreateKubernetesNamespaces + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultNamespace. diff --git a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml index 3cb38441e..1ef33e030 100644 --- a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml @@ -86,7 +86,7 @@ metadata: categories: Developer Tools certified: "false" containerImage: quay.io/eclipse/che-operator:next - createdAt: "2026-04-09T11:50:19Z" + createdAt: "2026-04-13T08:40:46Z" description: A Kube-native development solution that delivers portable and collaborative developer workspaces. features.operators.openshift.io/cnf: "false" @@ -108,7 +108,7 @@ metadata: operatorframework.io/arch.amd64: supported operatorframework.io/arch.arm64: supported operatorframework.io/os.linux: supported - name: eclipse-che.v7.117.0-971.next + name: eclipse-che.v7.117.0-972.next namespace: placeholder spec: apiservicedefinitions: {} @@ -1144,7 +1144,7 @@ spec: name: gateway-authorization-sidecar-k8s - image: quay.io/che-incubator/header-rewrite-proxy:latest name: gateway-header-sidecar - version: 7.117.0-971.next + version: 7.117.0-972.next webhookdefinitions: - admissionReviewVersions: - v1 diff --git a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml index 60ce5513e..635ef614b 100644 --- a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml +++ b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml @@ -16553,6 +16553,12 @@ spec: Indicates if is allowed to automatically create a user namespace. If it set to false, then user namespace must be pre-created by a cluster administrator. type: boolean + createKubernetesNamespaces: + description: |- + For OpenShift clusters only, setting this to `true` creates + a standard Kubernetes Namespace. When false (default), the OpenShift ProjectRequest API + is used instead to trigger cluster-specific Project Templates. + type: boolean template: default: -che description: |- diff --git a/config/crd/bases/org.eclipse.che_checlusters.yaml b/config/crd/bases/org.eclipse.che_checlusters.yaml index ac5218eaf..b60d474fd 100644 --- a/config/crd/bases/org.eclipse.che_checlusters.yaml +++ b/config/crd/bases/org.eclipse.che_checlusters.yaml @@ -16471,6 +16471,12 @@ spec: Indicates if is allowed to automatically create a user namespace. If it set to false, then user namespace must be pre-created by a cluster administrator. type: boolean + createKubernetesNamespaces: + description: |- + For OpenShift clusters only, setting this to `true` creates + a standard Kubernetes Namespace. When false (default), the OpenShift ProjectRequest API + is used instead to trigger cluster-specific Project Templates. + type: boolean template: default: -che description: |- diff --git a/deploy/deployment/kubernetes/combined.yaml b/deploy/deployment/kubernetes/combined.yaml index e7c8183ce..f42d34430 100644 --- a/deploy/deployment/kubernetes/combined.yaml +++ b/deploy/deployment/kubernetes/combined.yaml @@ -16492,6 +16492,12 @@ spec: Indicates if is allowed to automatically create a user namespace. If it set to false, then user namespace must be pre-created by a cluster administrator. type: boolean + createKubernetesNamespaces: + description: |- + For OpenShift clusters only, setting this to `true` creates + a standard Kubernetes Namespace. When false (default), the OpenShift ProjectRequest API + is used instead to trigger cluster-specific Project Templates. + type: boolean template: default: -che description: |- diff --git a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index bf5bf4694..a66467b6c 100644 --- a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -16487,6 +16487,12 @@ spec: Indicates if is allowed to automatically create a user namespace. If it set to false, then user namespace must be pre-created by a cluster administrator. type: boolean + createKubernetesNamespaces: + description: |- + For OpenShift clusters only, setting this to `true` creates + a standard Kubernetes Namespace. When false (default), the OpenShift ProjectRequest API + is used instead to trigger cluster-specific Project Templates. + type: boolean template: default: -che description: |- diff --git a/deploy/deployment/openshift/combined.yaml b/deploy/deployment/openshift/combined.yaml index 7052eb111..b8d29f95a 100644 --- a/deploy/deployment/openshift/combined.yaml +++ b/deploy/deployment/openshift/combined.yaml @@ -16492,6 +16492,12 @@ spec: Indicates if is allowed to automatically create a user namespace. If it set to false, then user namespace must be pre-created by a cluster administrator. type: boolean + createKubernetesNamespaces: + description: |- + For OpenShift clusters only, setting this to `true` creates + a standard Kubernetes Namespace. When false (default), the OpenShift ProjectRequest API + is used instead to trigger cluster-specific Project Templates. + type: boolean template: default: -che description: |- diff --git a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 5dea81a9f..ac7956665 100644 --- a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -16487,6 +16487,12 @@ spec: Indicates if is allowed to automatically create a user namespace. If it set to false, then user namespace must be pre-created by a cluster administrator. type: boolean + createKubernetesNamespaces: + description: |- + For OpenShift clusters only, setting this to `true` creates + a standard Kubernetes Namespace. When false (default), the OpenShift ProjectRequest API + is used instead to trigger cluster-specific Project Templates. + type: boolean template: default: -che description: |- diff --git a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index bf5bf4694..a66467b6c 100644 --- a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -16487,6 +16487,12 @@ spec: Indicates if is allowed to automatically create a user namespace. If it set to false, then user namespace must be pre-created by a cluster administrator. type: boolean + createKubernetesNamespaces: + description: |- + For OpenShift clusters only, setting this to `true` creates + a standard Kubernetes Namespace. When false (default), the OpenShift ProjectRequest API + is used instead to trigger cluster-specific Project Templates. + type: boolean template: default: -che description: |- diff --git a/pkg/common/constants/constants.go b/pkg/common/constants/constants.go index ae5ed50b5..b4aa838ec 100644 --- a/pkg/common/constants/constants.go +++ b/pkg/common/constants/constants.go @@ -108,13 +108,14 @@ const ( ConfigOpenShiftIOInjectTrustedCaBundle = "config.openshift.io/inject-trusted-cabundle" // DevEnvironments - PerUserPVCStorageStrategy = "per-user" - DefaultPvcStorageStrategy = "per-user" - PerWorkspacePVCStorageStrategy = "per-workspace" - EphemeralPVCStorageStrategy = "ephemeral" - CommonPVCStorageStrategy = "common" - DefaultDeploymentStrategy = "Recreate" - DefaultAutoProvision = true + PerUserPVCStorageStrategy = "per-user" + DefaultPvcStorageStrategy = "per-user" + PerWorkspacePVCStorageStrategy = "per-workspace" + EphemeralPVCStorageStrategy = "ephemeral" + CommonPVCStorageStrategy = "common" + DefaultDeploymentStrategy = "Recreate" + DefaultAutoProvision = true + OpenShiftCreateKubernetesNamespaces = false // Ingress DefaultSelfSignedCertificateSecretName = "self-signed-certificate" diff --git a/pkg/deploy/server/server_configmap.go b/pkg/deploy/server/server_configmap.go index bb3975663..e5c78458b 100644 --- a/pkg/deploy/server/server_configmap.go +++ b/pkg/deploy/server/server_configmap.go @@ -38,19 +38,20 @@ import ( ) type CheConfigMap struct { - JavaOpts string `json:"JAVA_OPTS"` - CheHost string `json:"CHE_HOST"` - ChePort string `json:"CHE_PORT"` - CheDebugServer string `json:"CHE_DEBUG_SERVER"` - CheLogLevel string `json:"CHE_LOG_LEVEL"` - CheMetricsEnabled string `json:"CHE_METRICS_ENABLED"` - CheInfrastructure string `json:"CHE_INFRASTRUCTURE_ACTIVE"` - UserClusterRoles string `json:"CHE_INFRA_KUBERNETES_USER__CLUSTER__ROLES"` - NamespaceDefault string `json:"CHE_INFRA_KUBERNETES_NAMESPACE_DEFAULT"` - NamespaceCreationAllowed string `json:"CHE_INFRA_KUBERNETES_NAMESPACE_CREATION__ALLOWED"` - Http2Disable string `json:"HTTP2_DISABLE"` - KubernetesLabels string `json:"KUBERNETES_LABELS"` - OpenShiftOAuthEnabled string `json:"CHE_INFRA_OPENSHIFT_OAUTH__ENABLED"` + JavaOpts string `json:"JAVA_OPTS"` + CheHost string `json:"CHE_HOST"` + ChePort string `json:"CHE_PORT"` + CheDebugServer string `json:"CHE_DEBUG_SERVER"` + CheLogLevel string `json:"CHE_LOG_LEVEL"` + CheMetricsEnabled string `json:"CHE_METRICS_ENABLED"` + CheInfrastructure string `json:"CHE_INFRASTRUCTURE_ACTIVE"` + UserClusterRoles string `json:"CHE_INFRA_KUBERNETES_USER__CLUSTER__ROLES"` + NamespaceDefault string `json:"CHE_INFRA_KUBERNETES_NAMESPACE_DEFAULT"` + NamespaceCreationAllowed string `json:"CHE_INFRA_KUBERNETES_NAMESPACE_CREATION__ALLOWED"` + Http2Disable string `json:"HTTP2_DISABLE"` + KubernetesLabels string `json:"KUBERNETES_LABELS"` + OpenShiftOAuthEnabled string `json:"CHE_INFRA_OPENSHIFT_OAUTH__ENABLED"` + OpenShiftCreateKubernetesNamespaces string `json:"CHE_INFRA_OPENSHIFT__KUBERNETES_NAMESPACES_CREATION"` // TODO remove when keycloak codebase is removed from che-server component CheOIDCAuthServerUrl string `json:"CHE_OIDC_AUTH__SERVER__URL,omitempty"` } @@ -136,19 +137,27 @@ func (s *CheServerReconciler) getConfigMapData(ctx *chetypes.DeployContext) (che kubernetesLabels := labels.FormatLabels(deploy.GetLabels(defaults.GetCheFlavor())) + openShiftCreateKubernetesNamespaces := strconv.FormatBool( + pointer.BoolDeref( + ctx.CheCluster.Spec.DevEnvironments.DefaultNamespace.CreateKubernetesNamespaces, + constants.OpenShiftCreateKubernetesNamespaces, + ), + ) + data := &CheConfigMap{ - JavaOpts: javaOpts, - CheHost: ctx.CheHost, - ChePort: chePort, - CheDebugServer: cheDebugServer, - CheLogLevel: cheLogLevel, - CheMetricsEnabled: cheMetricsEnabled, - CheInfrastructure: cheInfrastructure, - CheOIDCAuthServerUrl: ctx.CheCluster.Spec.Networking.Auth.IdentityProviderURL, - NamespaceDefault: namespaceDefault, - NamespaceCreationAllowed: namespaceCreationAllowed, - KubernetesLabels: kubernetesLabels, - OpenShiftOAuthEnabled: strconv.FormatBool(infrastructure.IsOpenShiftOAuthEnabled()), + JavaOpts: javaOpts, + CheHost: ctx.CheHost, + ChePort: chePort, + CheDebugServer: cheDebugServer, + CheLogLevel: cheLogLevel, + CheMetricsEnabled: cheMetricsEnabled, + CheInfrastructure: cheInfrastructure, + CheOIDCAuthServerUrl: ctx.CheCluster.Spec.Networking.Auth.IdentityProviderURL, + NamespaceDefault: namespaceDefault, + NamespaceCreationAllowed: namespaceCreationAllowed, + KubernetesLabels: kubernetesLabels, + OpenShiftOAuthEnabled: strconv.FormatBool(infrastructure.IsOpenShiftOAuthEnabled()), + OpenShiftCreateKubernetesNamespaces: openShiftCreateKubernetesNamespaces, // Disable HTTP2 protocol. // Fix issue with creating config maps on the cluster https://issues.redhat.com/browse/CRW-2677 // The root cause is in the HTTP2 protocol support of the okttp3 library that is used by fabric8.kubernetes-client that is used by che-server diff --git a/pkg/deploy/server/server_configmap_test.go b/pkg/deploy/server/server_configmap_test.go index 169c3e20b..c23fc92f9 100644 --- a/pkg/deploy/server/server_configmap_test.go +++ b/pkg/deploy/server/server_configmap_test.go @@ -77,13 +77,14 @@ func TestGetConfigMapData(t *testing.T) { "CHE_LOG_LEVEL": "INFO", "CHE_METRICS_ENABLED": "false", "CHE_INFRASTRUCTURE_ACTIVE": "openshift", - "CHE_INFRA_KUBERNETES_USER__CLUSTER__ROLES": "eclipse-che-cheworkspaces-clusterrole,eclipse-che-cheworkspaces-devworkspace-clusterrole", - "CHE_INFRA_KUBERNETES_NAMESPACE_DEFAULT": "-" + defaults.GetCheFlavor(), - "CHE_INFRA_KUBERNETES_NAMESPACE_CREATION__ALLOWED": "true", - "KUBERNETES_LABELS": labels.FormatLabels(deploy.GetLabels(defaults.GetCheFlavor())), - "HTTP2_DISABLE": "true", - "CHE_OIDC_AUTH__SERVER__URL": "http://identity-provider", - "CHE_INFRA_OPENSHIFT_OAUTH__ENABLED": "true", + "CHE_INFRA_KUBERNETES_USER__CLUSTER__ROLES": "eclipse-che-cheworkspaces-clusterrole,eclipse-che-cheworkspaces-devworkspace-clusterrole", + "CHE_INFRA_KUBERNETES_NAMESPACE_DEFAULT": "-" + defaults.GetCheFlavor(), + "CHE_INFRA_KUBERNETES_NAMESPACE_CREATION__ALLOWED": "true", + "KUBERNETES_LABELS": labels.FormatLabels(deploy.GetLabels(defaults.GetCheFlavor())), + "HTTP2_DISABLE": "true", + "CHE_OIDC_AUTH__SERVER__URL": "http://identity-provider", + "CHE_INFRA_OPENSHIFT_OAUTH__ENABLED": "true", + "CHE_INFRA_OPENSHIFT__KUBERNETES_NAMESPACES_CREATION": "false", }, }, }