From 397c97c6754da444b91337050c3490ef2a93d8b5 Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Fri, 13 Jan 2023 14:07:36 +0200 Subject: [PATCH] feat: limit the number of workspaces per user (#1585) * feat: limit the number of workspaces per user Signed-off-by: Anatolii Bazko --- api/checluster_conversion_from_test.go | 10 ++++------ api/checluster_conversion_to_test.go | 5 ++--- api/checluster_round_conversion_test.go | 4 +--- api/v1/checluster_conversion_from.go | 4 +++- api/v1/checluster_conversion_to.go | 6 +++++- api/v2/checluster_types.go | 14 ++++++++++++- api/v2/zz_generated.deepcopy.go | 10 ++++++++++ .../che-operator.clusterserviceversion.yaml | 4 ++-- .../org.eclipse.che_checlusters.yaml | 20 +++++++++++++++++-- .../bases/org.eclipse.che_checlusters.yaml | 19 ++++++++++++++++-- deploy/deployment/kubernetes/combined.yaml | 19 ++++++++++++++++-- ....eclipse.che.CustomResourceDefinition.yaml | 19 ++++++++++++++++-- deploy/deployment/openshift/combined.yaml | 19 ++++++++++++++++-- ....eclipse.che.CustomResourceDefinition.yaml | 19 ++++++++++++++++-- ....eclipse.che.CustomResourceDefinition.yaml | 19 ++++++++++++++++-- 15 files changed, 160 insertions(+), 31 deletions(-) diff --git a/api/checluster_conversion_from_test.go b/api/checluster_conversion_from_test.go index d447a2750..dab920eaa 100644 --- a/api/checluster_conversion_from_test.go +++ b/api/checluster_conversion_from_test.go @@ -301,9 +301,6 @@ func TestConvertFrom(t *testing.T) { CredentialsSecretName: "ProxyCredentialsSecretName", }, }, - DevWorkspace: chev2.DevWorkspace{ - RunningLimit: "RunningLimit", - }, }, Networking: chev2.CheClusterSpecNetworking{ Auth: chev2.Auth{ @@ -399,8 +396,9 @@ func TestConvertFrom(t *testing.T) { Value: "Value", Effect: "Effect", }}, - SecondsOfInactivityBeforeIdling: pointer.Int32Ptr(1800), - SecondsOfRunBeforeIdling: pointer.Int32Ptr(-1), + SecondsOfInactivityBeforeIdling: pointer.Int32Ptr(1800), + SecondsOfRunBeforeIdling: pointer.Int32Ptr(-1), + MaxNumberOfRunningWorkspacesPerUser: pointer.Int64Ptr(10), }, ContainerRegistry: chev2.CheClusterContainerRegistry{ Hostname: "AirGapContainerRegistryHostname", @@ -487,7 +485,7 @@ func TestConvertFrom(t *testing.T) { assert.Equal(t, checlusterv1.Spec.Database.PostgresEnv[0].Name, "database-name") assert.Equal(t, checlusterv1.Spec.Database.PostgresEnv[0].Value, "database-value") - assert.Equal(t, checlusterv1.Spec.DevWorkspace.RunningLimit, "RunningLimit") + assert.Equal(t, checlusterv1.Spec.DevWorkspace.RunningLimit, "10") assert.Equal(t, checlusterv1.Spec.DevWorkspace.SecondsOfInactivityBeforeIdling, pointer.Int32Ptr(1800)) assert.Equal(t, checlusterv1.Spec.DevWorkspace.SecondsOfRunBeforeIdling, pointer.Int32Ptr(-1)) assert.True(t, checlusterv1.Spec.DevWorkspace.Enable) diff --git a/api/checluster_conversion_to_test.go b/api/checluster_conversion_to_test.go index 9cce67e3b..f96ac1beb 100644 --- a/api/checluster_conversion_to_test.go +++ b/api/checluster_conversion_to_test.go @@ -334,7 +334,7 @@ func TestConvertTo(t *testing.T) { }, DevWorkspace: chev1.CheClusterSpecDevWorkspace{ Enable: true, - RunningLimit: "RunningLimit", + RunningLimit: "10", SecondsOfInactivityBeforeIdling: pointer.Int32Ptr(1800), SecondsOfRunBeforeIdling: pointer.Int32Ptr(-1), }, @@ -473,8 +473,6 @@ func TestConvertTo(t *testing.T) { assert.Equal(t, checlusterv2.Spec.Components.Database.Pvc.ClaimSize, "DatabasePvcClaimSize") assert.Equal(t, checlusterv2.Spec.Components.Database.Pvc.StorageClass, "PostgresPVCStorageClassName") - assert.Equal(t, checlusterv2.Spec.Components.DevWorkspace.RunningLimit, "RunningLimit") - assert.Equal(t, checlusterv2.Spec.Components.ImagePuller.Enable, true) assert.Equal(t, checlusterv2.Spec.Components.Metrics.Enable, true) @@ -516,6 +514,7 @@ func TestConvertTo(t *testing.T) { assert.Equal(t, checlusterv2.Spec.DevEnvironments.Storage.PvcStrategy, "PvcStrategy") assert.Equal(t, checlusterv2.Spec.DevEnvironments.SecondsOfInactivityBeforeIdling, pointer.Int32Ptr(1800)) assert.Equal(t, checlusterv2.Spec.DevEnvironments.SecondsOfRunBeforeIdling, pointer.Int32Ptr(-1)) + assert.Equal(t, checlusterv2.Spec.DevEnvironments.MaxNumberOfRunningWorkspacesPerUser, pointer.Int64Ptr(10)) assert.Equal(t, checlusterv2.Status.CheURL, "CheURL") assert.Equal(t, checlusterv2.Status.CheVersion, "CheVersion") diff --git a/api/checluster_round_conversion_test.go b/api/checluster_round_conversion_test.go index bdec00b10..91520a481 100644 --- a/api/checluster_round_conversion_test.go +++ b/api/checluster_round_conversion_test.go @@ -236,9 +236,6 @@ func TestRoundConvertCheClusterV2(t *testing.T) { CredentialsSecretName: "ProxyCredentialsSecretName", }, }, - DevWorkspace: chev2.DevWorkspace{ - RunningLimit: "RunningLimit", - }, }, Networking: chev2.CheClusterSpecNetworking{ TlsSecretName: "che-tls", @@ -308,6 +305,7 @@ func TestRoundConvertCheClusterV2(t *testing.T) { Value: "Value", Effect: "Effect", }}, + MaxNumberOfRunningWorkspacesPerUser: pointer.Int64Ptr(10), }, ContainerRegistry: chev2.CheClusterContainerRegistry{ Hostname: "AirGapContainerRegistryHostname", diff --git a/api/v1/checluster_conversion_from.go b/api/v1/checluster_conversion_from.go index e56b7cdc7..fde0f5680 100644 --- a/api/v1/checluster_conversion_from.go +++ b/api/v1/checluster_conversion_from.go @@ -385,7 +385,9 @@ func (dst *CheCluster) convertFrom_Database(src *chev2.CheCluster) error { } func (dst *CheCluster) convertFrom_DevWorkspace(src *chev2.CheCluster) error { - dst.Spec.DevWorkspace.RunningLimit = src.Spec.Components.DevWorkspace.RunningLimit + if src.Spec.DevEnvironments.MaxNumberOfRunningWorkspacesPerUser != nil { + dst.Spec.DevWorkspace.RunningLimit = strconv.FormatInt(*src.Spec.DevEnvironments.MaxNumberOfRunningWorkspacesPerUser, 10) + } dst.Spec.DevWorkspace.SecondsOfInactivityBeforeIdling = src.Spec.DevEnvironments.SecondsOfInactivityBeforeIdling dst.Spec.DevWorkspace.SecondsOfRunBeforeIdling = src.Spec.DevEnvironments.SecondsOfRunBeforeIdling dst.Spec.DevWorkspace.Enable = true diff --git a/api/v1/checluster_conversion_to.go b/api/v1/checluster_conversion_to.go index 1bf8a179e..022ceeb60 100644 --- a/api/v1/checluster_conversion_to.go +++ b/api/v1/checluster_conversion_to.go @@ -290,7 +290,11 @@ func (src *CheCluster) convertTo_Components(dst *chev2.CheCluster) error { } func (src *CheCluster) convertTo_Components_DevWorkspace(dst *chev2.CheCluster) error { - dst.Spec.Components.DevWorkspace.RunningLimit = src.Spec.DevWorkspace.RunningLimit + if src.Spec.DevWorkspace.RunningLimit != "" { + runningLimit, err := strconv.ParseInt(src.Spec.DevWorkspace.RunningLimit, 10, 64) + dst.Spec.DevEnvironments.MaxNumberOfRunningWorkspacesPerUser = pointer.Int64Ptr(runningLimit) + return err + } return nil } diff --git a/api/v2/checluster_types.go b/api/v2/checluster_types.go index 3b56feee3..b15aeed78 100644 --- a/api/v2/checluster_types.go +++ b/api/v2/checluster_types.go @@ -37,7 +37,7 @@ type CheClusterSpec struct { // +optional // +operator-sdk:csv:customresourcedefinitions:type=spec,order=1 // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Development environments" - // +kubebuilder:default:={disableContainerBuildCapabilities: true, defaultComponents: {{name: universal-developer-image, container: {image: "quay.io/devfile/universal-developer-image:ubi8-38da5c2"}}}, defaultEditor: che-incubator/che-code/insiders, storage: {pvcStrategy: per-user}, defaultNamespace: {template: -che, autoProvision: true}, secondsOfInactivityBeforeIdling:1800, secondsOfRunBeforeIdling:-1, startTimeoutSeconds:300} + // +kubebuilder:default:={disableContainerBuildCapabilities: true, defaultComponents: {{name: universal-developer-image, container: {image: "quay.io/devfile/universal-developer-image:ubi8-38da5c2"}}}, defaultEditor: che-incubator/che-code/insiders, storage: {pvcStrategy: per-user}, defaultNamespace: {template: -che, autoProvision: true}, secondsOfInactivityBeforeIdling:1800, secondsOfRunBeforeIdling:-1, startTimeoutSeconds:300, maxNumberOfWorkspacesPerUser:-1} DevEnvironments CheClusterDevEnvironments `json:"devEnvironments"` // Che components configuration. // +optional @@ -130,6 +130,17 @@ type CheClusterDevEnvironments struct { // +kubebuilder:validation:Minimum:=1 // +kubebuilder:default:=300 StartTimeoutSeconds *int32 `json:"startTimeoutSeconds,omitempty"` + // Total number of workspaces, both stopped and running, that a user can keep. + // The value, -1, allows users to keep an unlimited number of workspaces. + // +kubebuilder:validation:Minimum:=-1 + // +kubebuilder:default:=-1 + // +optional + MaxNumberOfWorkspacesPerUser *int64 `json:"maxNumberOfWorkspacesPerUser,omitempty"` + // The maximum number of running workspaces per user. + // The value, -1, allows users to run an unlimited number of workspaces. + // +kubebuilder:validation:Minimum:=-1 + // +optional + MaxNumberOfRunningWorkspacesPerUser *int64 `json:"maxNumberOfRunningWorkspacesPerUser,omitempty"` } // Che components configuration. @@ -360,6 +371,7 @@ type ImagePuller struct { // See https://github.com/devfile/devworkspace-operator // +k8s:openapi-gen=true type DevWorkspace struct { + // Deprecated in favor of `MaxNumberOfRunningWorkspacesPerUser` // The maximum number of running workspaces per user. // +optional RunningLimit string `json:"runningLimit,omitempty"` diff --git a/api/v2/zz_generated.deepcopy.go b/api/v2/zz_generated.deepcopy.go index 684511c0c..d3c1ac72e 100644 --- a/api/v2/zz_generated.deepcopy.go +++ b/api/v2/zz_generated.deepcopy.go @@ -192,6 +192,16 @@ func (in *CheClusterDevEnvironments) DeepCopyInto(out *CheClusterDevEnvironments *out = new(int32) **out = **in } + if in.MaxNumberOfWorkspacesPerUser != nil { + in, out := &in.MaxNumberOfWorkspacesPerUser, &out.MaxNumberOfWorkspacesPerUser + *out = new(int64) + **out = **in + } + if in.MaxNumberOfRunningWorkspacesPerUser != nil { + in, out := &in.MaxNumberOfRunningWorkspacesPerUser, &out.MaxNumberOfRunningWorkspacesPerUser + *out = new(int64) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheClusterDevEnvironments. diff --git a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml index 971724e1a..6f57c5da4 100644 --- a/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml +++ b/bundle/next/eclipse-che/manifests/che-operator.clusterserviceversion.yaml @@ -77,7 +77,7 @@ metadata: operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/eclipse-che/che-operator support: Eclipse Foundation - name: eclipse-che.v7.59.0-745.next + name: eclipse-che.v7.60.0-755.next namespace: placeholder spec: apiservicedefinitions: {} @@ -1233,7 +1233,7 @@ spec: minKubeVersion: 1.19.0 provider: name: Eclipse Foundation - version: 7.59.0-745.next + version: 7.60.0-755.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 77f5cc758..04644f0c3 100644 --- a/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml +++ b/bundle/next/eclipse-che/manifests/org.eclipse.che_checlusters.yaml @@ -4846,8 +4846,8 @@ spec: description: DevWorkspace Operator configuration. properties: runningLimit: - description: The maximum number of running workspaces per - user. + description: Deprecated in favor of `MaxNumberOfRunningWorkspacesPerUser` + The maximum number of running workspaces per user. type: string type: object devfileRegistry: @@ -5408,6 +5408,7 @@ spec: autoProvision: true template: -che disableContainerBuildCapabilities: true + maxNumberOfWorkspacesPerUser: -1 secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 startTimeoutSeconds: 300 @@ -6975,6 +6976,21 @@ spec: default: true description: Disables the container build capabilities. type: boolean + maxNumberOfRunningWorkspacesPerUser: + description: The maximum number of running workspaces per user. + The value, -1, allows users to run an unlimited number of + workspaces. + format: int64 + minimum: -1 + type: integer + maxNumberOfWorkspacesPerUser: + default: -1 + description: Total number of workspaces, both stopped and running, + that a user can keep. The value, -1, allows users to keep + an unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer nodeSelector: additionalProperties: type: string diff --git a/config/crd/bases/org.eclipse.che_checlusters.yaml b/config/crd/bases/org.eclipse.che_checlusters.yaml index 8a1b9c9db..be25781a2 100644 --- a/config/crd/bases/org.eclipse.che_checlusters.yaml +++ b/config/crd/bases/org.eclipse.che_checlusters.yaml @@ -4715,8 +4715,8 @@ spec: description: DevWorkspace Operator configuration. properties: runningLimit: - description: The maximum number of running workspaces per - user. + description: Deprecated in favor of `MaxNumberOfRunningWorkspacesPerUser` + The maximum number of running workspaces per user. type: string type: object devfileRegistry: @@ -5269,6 +5269,7 @@ spec: autoProvision: true template: -che disableContainerBuildCapabilities: true + maxNumberOfWorkspacesPerUser: -1 secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 startTimeoutSeconds: 300 @@ -6785,6 +6786,20 @@ spec: default: true description: Disables the container build capabilities. type: boolean + maxNumberOfRunningWorkspacesPerUser: + description: The maximum number of running workspaces per user. + The value, -1, allows users to run an unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer + maxNumberOfWorkspacesPerUser: + default: -1 + description: Total number of workspaces, both stopped and running, + that a user can keep. The value, -1, allows users to keep an + unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer nodeSelector: additionalProperties: type: string diff --git a/deploy/deployment/kubernetes/combined.yaml b/deploy/deployment/kubernetes/combined.yaml index 83024d92e..bcc941e3a 100644 --- a/deploy/deployment/kubernetes/combined.yaml +++ b/deploy/deployment/kubernetes/combined.yaml @@ -4734,8 +4734,8 @@ spec: description: DevWorkspace Operator configuration. properties: runningLimit: - description: The maximum number of running workspaces per - user. + description: Deprecated in favor of `MaxNumberOfRunningWorkspacesPerUser` + The maximum number of running workspaces per user. type: string type: object devfileRegistry: @@ -5288,6 +5288,7 @@ spec: autoProvision: true template: -che disableContainerBuildCapabilities: true + maxNumberOfWorkspacesPerUser: -1 secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 startTimeoutSeconds: 300 @@ -6804,6 +6805,20 @@ spec: default: true description: Disables the container build capabilities. type: boolean + maxNumberOfRunningWorkspacesPerUser: + description: The maximum number of running workspaces per user. + The value, -1, allows users to run an unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer + maxNumberOfWorkspacesPerUser: + default: -1 + description: Total number of workspaces, both stopped and running, + that a user can keep. The value, -1, allows users to keep an + unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer nodeSelector: additionalProperties: type: string 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 36ae158e7..f0fdc15e5 100644 --- a/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/kubernetes/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -4729,8 +4729,8 @@ spec: description: DevWorkspace Operator configuration. properties: runningLimit: - description: The maximum number of running workspaces per - user. + description: Deprecated in favor of `MaxNumberOfRunningWorkspacesPerUser` + The maximum number of running workspaces per user. type: string type: object devfileRegistry: @@ -5283,6 +5283,7 @@ spec: autoProvision: true template: -che disableContainerBuildCapabilities: true + maxNumberOfWorkspacesPerUser: -1 secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 startTimeoutSeconds: 300 @@ -6799,6 +6800,20 @@ spec: default: true description: Disables the container build capabilities. type: boolean + maxNumberOfRunningWorkspacesPerUser: + description: The maximum number of running workspaces per user. + The value, -1, allows users to run an unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer + maxNumberOfWorkspacesPerUser: + default: -1 + description: Total number of workspaces, both stopped and running, + that a user can keep. The value, -1, allows users to keep an + unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer nodeSelector: additionalProperties: type: string diff --git a/deploy/deployment/openshift/combined.yaml b/deploy/deployment/openshift/combined.yaml index 022eb487d..e9aef6986 100644 --- a/deploy/deployment/openshift/combined.yaml +++ b/deploy/deployment/openshift/combined.yaml @@ -4734,8 +4734,8 @@ spec: description: DevWorkspace Operator configuration. properties: runningLimit: - description: The maximum number of running workspaces per - user. + description: Deprecated in favor of `MaxNumberOfRunningWorkspacesPerUser` + The maximum number of running workspaces per user. type: string type: object devfileRegistry: @@ -5288,6 +5288,7 @@ spec: autoProvision: true template: -che disableContainerBuildCapabilities: true + maxNumberOfWorkspacesPerUser: -1 secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 startTimeoutSeconds: 300 @@ -6804,6 +6805,20 @@ spec: default: true description: Disables the container build capabilities. type: boolean + maxNumberOfRunningWorkspacesPerUser: + description: The maximum number of running workspaces per user. + The value, -1, allows users to run an unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer + maxNumberOfWorkspacesPerUser: + default: -1 + description: Total number of workspaces, both stopped and running, + that a user can keep. The value, -1, allows users to keep an + unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer nodeSelector: additionalProperties: type: string 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 0cccc888d..8566a8a5a 100644 --- a/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/deploy/deployment/openshift/objects/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -4729,8 +4729,8 @@ spec: description: DevWorkspace Operator configuration. properties: runningLimit: - description: The maximum number of running workspaces per - user. + description: Deprecated in favor of `MaxNumberOfRunningWorkspacesPerUser` + The maximum number of running workspaces per user. type: string type: object devfileRegistry: @@ -5283,6 +5283,7 @@ spec: autoProvision: true template: -che disableContainerBuildCapabilities: true + maxNumberOfWorkspacesPerUser: -1 secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 startTimeoutSeconds: 300 @@ -6799,6 +6800,20 @@ spec: default: true description: Disables the container build capabilities. type: boolean + maxNumberOfRunningWorkspacesPerUser: + description: The maximum number of running workspaces per user. + The value, -1, allows users to run an unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer + maxNumberOfWorkspacesPerUser: + default: -1 + description: Total number of workspaces, both stopped and running, + that a user can keep. The value, -1, allows users to keep an + unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer nodeSelector: additionalProperties: type: string diff --git a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml index 36ae158e7..f0fdc15e5 100644 --- a/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml +++ b/helmcharts/next/crds/checlusters.org.eclipse.che.CustomResourceDefinition.yaml @@ -4729,8 +4729,8 @@ spec: description: DevWorkspace Operator configuration. properties: runningLimit: - description: The maximum number of running workspaces per - user. + description: Deprecated in favor of `MaxNumberOfRunningWorkspacesPerUser` + The maximum number of running workspaces per user. type: string type: object devfileRegistry: @@ -5283,6 +5283,7 @@ spec: autoProvision: true template: -che disableContainerBuildCapabilities: true + maxNumberOfWorkspacesPerUser: -1 secondsOfInactivityBeforeIdling: 1800 secondsOfRunBeforeIdling: -1 startTimeoutSeconds: 300 @@ -6799,6 +6800,20 @@ spec: default: true description: Disables the container build capabilities. type: boolean + maxNumberOfRunningWorkspacesPerUser: + description: The maximum number of running workspaces per user. + The value, -1, allows users to run an unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer + maxNumberOfWorkspacesPerUser: + default: -1 + description: Total number of workspaces, both stopped and running, + that a user can keep. The value, -1, allows users to keep an + unlimited number of workspaces. + format: int64 + minimum: -1 + type: integer nodeSelector: additionalProperties: type: string